1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.audio; 18 19 import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; 20 import static android.Manifest.permission.BLUETOOTH_STACK; 21 import static android.Manifest.permission.CALL_AUDIO_INTERCEPTION; 22 import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD; 23 import static android.Manifest.permission.CAPTURE_AUDIO_OUTPUT; 24 import static android.Manifest.permission.CAPTURE_MEDIA_OUTPUT; 25 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 26 import static android.Manifest.permission.MODIFY_AUDIO_ROUTING; 27 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS; 28 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED; 29 import static android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS; 30 import static android.Manifest.permission.MODIFY_PHONE_STATE; 31 import static android.Manifest.permission.QUERY_AUDIO_STATE; 32 import static android.Manifest.permission.WRITE_SETTINGS; 33 import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT; 34 import static android.content.Intent.ACTION_PACKAGE_ADDED; 35 import static android.content.Intent.EXTRA_ARCHIVAL; 36 import static android.content.Intent.EXTRA_REPLACING; 37 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP; 38 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES; 39 import static android.media.AudioManager.RINGER_MODE_NORMAL; 40 import static android.media.AudioManager.RINGER_MODE_SILENT; 41 import static android.media.AudioManager.RINGER_MODE_VIBRATE; 42 import static android.media.AudioManager.STREAM_SYSTEM; 43 import static android.media.audio.Flags.autoPublicVolumeApiHardening; 44 import static android.media.audio.Flags.cacheGetStreamMinMaxVolume; 45 import static android.media.audio.Flags.cacheGetStreamVolume; 46 import static android.media.audio.Flags.concurrentAudioRecordBypassPermission; 47 import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency; 48 import static android.media.audio.Flags.focusFreezeTestApi; 49 import static android.media.audio.Flags.roForegroundAudioControl; 50 import static android.media.audio.Flags.scoManagedByAudio; 51 import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration; 52 import static android.os.Process.FIRST_APPLICATION_UID; 53 import static android.os.Process.INVALID_UID; 54 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; 55 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF; 56 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE; 57 58 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; 59 import static com.android.media.audio.Flags.alarmMinVolumeZero; 60 import static com.android.media.audio.Flags.asDeviceConnectionFailure; 61 import static com.android.media.audio.Flags.audioserverPermissions; 62 import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume; 63 import static com.android.media.audio.Flags.deferWearPermissionUpdates; 64 import static com.android.media.audio.Flags.equalScoLeaVcIndexRange; 65 import static com.android.media.audio.Flags.optimizeBtDeviceSwitch; 66 import static com.android.media.audio.Flags.replaceStreamBtSco; 67 import static com.android.media.audio.Flags.ringMyCar; 68 import static com.android.media.audio.Flags.ringerModeAffectsAlarm; 69 import static com.android.media.flags.Flags.enableAudioInputDeviceRoutingAndVolumeControl; 70 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE; 71 import static com.android.server.utils.EventLogger.Event.ALOGE; 72 import static com.android.server.utils.EventLogger.Event.ALOGI; 73 import static com.android.server.utils.EventLogger.Event.ALOGW; 74 75 import android.Manifest; 76 import android.annotation.EnforcePermission; 77 import android.annotation.IntDef; 78 import android.annotation.IntRange; 79 import android.annotation.NonNull; 80 import android.annotation.Nullable; 81 import android.annotation.RequiresPermission; 82 import android.annotation.SuppressLint; 83 import android.annotation.UserIdInt; 84 import android.app.ActivityManager; 85 import android.app.ActivityManagerInternal; 86 import android.app.AppGlobals; 87 import android.app.AppOpsManager; 88 import android.app.BroadcastOptions; 89 import android.app.IUidObserver; 90 import android.app.NotificationManager; 91 import android.app.PropertyInvalidatedCache; 92 import android.app.UidObserver; 93 import android.app.role.OnRoleHoldersChangedListener; 94 import android.app.role.RoleManager; 95 import android.bluetooth.BluetoothDevice; 96 import android.bluetooth.BluetoothHeadset; 97 import android.bluetooth.BluetoothProfile; 98 import android.content.AttributionSource; 99 import android.content.BroadcastReceiver; 100 import android.content.ComponentName; 101 import android.content.ContentResolver; 102 import android.content.Context; 103 import android.content.Intent; 104 import android.content.IntentFilter; 105 import android.content.pm.ApplicationInfo; 106 import android.content.pm.PackageInfo; 107 import android.content.pm.PackageManager; 108 import android.content.pm.UserInfo; 109 import android.content.res.Configuration; 110 import android.content.res.Resources; 111 import android.database.ContentObserver; 112 import android.hardware.SensorPrivacyManager; 113 import android.hardware.SensorPrivacyManagerInternal; 114 import android.hardware.display.DisplayManager; 115 import android.hardware.display.DisplayManager.DisplayListener; 116 import android.hardware.hdmi.HdmiAudioSystemClient; 117 import android.hardware.hdmi.HdmiClient; 118 import android.hardware.hdmi.HdmiControlManager; 119 import android.hardware.hdmi.HdmiPlaybackClient; 120 import android.hardware.hdmi.HdmiTvClient; 121 import android.hardware.input.InputManager; 122 import android.hardware.usb.UsbManager; 123 import android.hidl.manager.V1_0.IServiceManager; 124 import android.media.AudioAttributes; 125 import android.media.AudioAttributes.AttributeSystemUsage; 126 import android.media.AudioDescriptor; 127 import android.media.AudioDeviceAttributes; 128 import android.media.AudioDeviceInfo; 129 import android.media.AudioDeviceVolumeManager; 130 import android.media.AudioFocusInfo; 131 import android.media.AudioFocusRequest; 132 import android.media.AudioFormat; 133 import android.media.AudioHalVersionInfo; 134 import android.media.AudioManager; 135 import android.media.AudioManager.AudioDeviceCategory; 136 import android.media.AudioManagerInternal; 137 import android.media.AudioMixerAttributes; 138 import android.media.AudioPlaybackConfiguration; 139 import android.media.AudioProfile; 140 import android.media.AudioRecordingConfiguration; 141 import android.media.AudioRoutesInfo; 142 import android.media.AudioSystem; 143 import android.media.BluetoothProfileConnectionInfo; 144 import android.media.FadeManagerConfiguration; 145 import android.media.IAudioDeviceVolumeDispatcher; 146 import android.media.IAudioFocusDispatcher; 147 import android.media.IAudioManagerNative; 148 import android.media.IAudioModeDispatcher; 149 import android.media.IAudioRoutesObserver; 150 import android.media.IAudioServerStateDispatcher; 151 import android.media.IAudioService; 152 import android.media.ICapturePresetDevicesRoleDispatcher; 153 import android.media.ICommunicationDeviceDispatcher; 154 import android.media.IDeviceVolumeBehaviorDispatcher; 155 import android.media.IDevicesForAttributesCallback; 156 import android.media.ILoudnessCodecUpdatesDispatcher; 157 import android.media.IMuteAwaitConnectionCallback; 158 import android.media.IPlaybackConfigDispatcher; 159 import android.media.IPreferredMixerAttributesDispatcher; 160 import android.media.IRecordingConfigDispatcher; 161 import android.media.IRingtonePlayer; 162 import android.media.ISpatializerCallback; 163 import android.media.ISpatializerHeadToSoundStagePoseCallback; 164 import android.media.ISpatializerHeadTrackerAvailableCallback; 165 import android.media.ISpatializerHeadTrackingModeCallback; 166 import android.media.ISpatializerOutputCallback; 167 import android.media.IStrategyNonDefaultDevicesDispatcher; 168 import android.media.IStrategyPreferredDevicesDispatcher; 169 import android.media.IStreamAliasingDispatcher; 170 import android.media.IVolumeController; 171 import android.media.LoudnessCodecController; 172 import android.media.LoudnessCodecInfo; 173 import android.media.MediaCodec; 174 import android.media.MediaMetrics; 175 import android.media.MediaRecorder.AudioSource; 176 import android.media.PlayerBase; 177 import android.media.Spatializer; 178 import android.media.Utils; 179 import android.media.VolumeInfo; 180 import android.media.VolumePolicy; 181 import android.media.audiofx.AudioEffect; 182 import android.media.audiopolicy.AudioMix; 183 import android.media.audiopolicy.AudioMixingRule; 184 import android.media.audiopolicy.AudioPolicy; 185 import android.media.audiopolicy.AudioPolicyConfig; 186 import android.media.audiopolicy.AudioProductStrategy; 187 import android.media.audiopolicy.AudioVolumeGroup; 188 import android.media.audiopolicy.IAudioPolicyCallback; 189 import android.media.audiopolicy.IAudioVolumeChangeDispatcher; 190 import android.media.permission.ClearCallingIdentityContext; 191 import android.media.permission.SafeCloseable; 192 import android.media.projection.IMediaProjection; 193 import android.media.projection.IMediaProjectionCallback; 194 import android.media.projection.IMediaProjectionManager; 195 import android.media.session.MediaSessionManager; 196 import android.net.Uri; 197 import android.os.Binder; 198 import android.os.Build; 199 import android.os.Bundle; 200 import android.os.Handler; 201 import android.os.HandlerThread; 202 import android.os.HwBinder; 203 import android.os.IBinder; 204 import android.os.Looper; 205 import android.os.Message; 206 import android.os.PermissionEnforcer; 207 import android.os.PersistableBundle; 208 import android.os.PowerManager; 209 import android.os.Process; 210 import android.os.RemoteCallbackList; 211 import android.os.RemoteException; 212 import android.os.ResultReceiver; 213 import android.os.ServiceDebugInfo; 214 import android.os.ServiceManager; 215 import android.os.ShellCallback; 216 import android.os.SystemClock; 217 import android.os.SystemProperties; 218 import android.os.UserHandle; 219 import android.os.UserManager; 220 import android.os.VibrationAttributes; 221 import android.os.VibrationEffect; 222 import android.os.Vibrator; 223 import android.os.VibratorManager; 224 import android.permission.PermissionManager; 225 import android.provider.Settings; 226 import android.provider.Settings.System; 227 import android.service.notification.ZenModeConfig; 228 import android.telecom.TelecomManager; 229 import android.telephony.SubscriptionManager; 230 import android.text.TextUtils; 231 import android.util.AndroidRuntimeException; 232 import android.util.ArrayMap; 233 import android.util.ArraySet; 234 import android.util.IntArray; 235 import android.util.Log; 236 import android.util.PrintWriterPrinter; 237 import android.util.Slog; 238 import android.util.SparseArray; 239 import android.util.SparseIntArray; 240 import android.view.Display; 241 import android.view.KeyEvent; 242 import android.view.accessibility.AccessibilityManager; 243 import android.widget.Toast; 244 245 import com.android.internal.annotations.GuardedBy; 246 import com.android.internal.annotations.VisibleForTesting; 247 import com.android.internal.os.SomeArgs; 248 import com.android.internal.util.DumpUtils; 249 import com.android.internal.util.Preconditions; 250 import com.android.modules.expresslog.Counter; 251 import com.android.server.EventLogTags; 252 import com.android.server.LocalManagerRegistry; 253 import com.android.server.LocalServices; 254 import com.android.server.SystemService; 255 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent; 256 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; 257 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent; 258 import com.android.server.audio.AudioServiceEvents.VolumeEvent; 259 import com.android.server.pm.PackageManagerLocal; 260 import com.android.server.pm.UserManagerInternal; 261 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener; 262 import com.android.server.pm.UserManagerService; 263 import com.android.server.pm.permission.PermissionManagerServiceInternal; 264 import com.android.server.pm.pkg.PackageState; 265 import com.android.server.utils.EventLogger; 266 import com.android.server.wm.ActivityTaskManagerInternal; 267 268 import java.io.FileDescriptor; 269 import java.io.PrintWriter; 270 import java.lang.annotation.Retention; 271 import java.lang.annotation.RetentionPolicy; 272 import java.text.SimpleDateFormat; 273 import java.util.ArrayList; 274 import java.util.Arrays; 275 import java.util.Collection; 276 import java.util.Collections; 277 import java.util.Date; 278 import java.util.HashMap; 279 import java.util.HashSet; 280 import java.util.Iterator; 281 import java.util.LinkedHashMap; 282 import java.util.List; 283 import java.util.Map; 284 import java.util.NoSuchElementException; 285 import java.util.Objects; 286 import java.util.Set; 287 import java.util.TreeSet; 288 import java.util.concurrent.CancellationException; 289 import java.util.concurrent.ExecutionException; 290 import java.util.concurrent.Executor; 291 import java.util.concurrent.Executors; 292 import java.util.concurrent.Future; 293 import java.util.concurrent.ScheduledExecutorService; 294 import java.util.concurrent.TimeUnit; 295 import java.util.concurrent.atomic.AtomicBoolean; 296 import java.util.concurrent.atomic.AtomicInteger; 297 import java.util.function.BooleanSupplier; 298 import java.util.stream.Collectors; 299 300 /** 301 * The implementation of the audio service for volume, audio focus, device management... 302 * <p> 303 * This implementation focuses on delivering a responsive UI. Most methods are 304 * asynchronous to external calls. For example, the task of setting a volume 305 * will update our internal state, but in a separate thread will set the system 306 * volume and later persist to the database. Similarly, setting the ringer mode 307 * will update the state and broadcast a change and in a separate thread later 308 * persist the ringer mode. 309 * 310 * @hide 311 */ 312 public class AudioService extends IAudioService.Stub 313 implements AccessibilityManager.TouchExplorationStateChangeListener, 314 AccessibilityManager.AccessibilityServicesStateChangeListener, 315 AudioSystemAdapter.OnRoutingUpdatedListener, 316 AudioSystemAdapter.OnVolRangeInitRequestListener { 317 318 private static final String TAG = "AS.AudioService"; 319 320 private final AudioSystemAdapter mAudioSystem; 321 private final SystemServerAdapter mSystemServer; 322 private final SettingsAdapter mSettings; 323 private final AudioPolicyFacade mAudioPolicy; 324 325 private final AudioServerPermissionProvider mPermissionProvider; 326 327 private final MusicFxHelper mMusicFxHelper; 328 329 /** Debug audio mode */ 330 protected static final boolean DEBUG_MODE = false; 331 332 /** Debug audio policy feature */ 333 protected static final boolean DEBUG_AP = false; 334 335 /** Debug volumes */ 336 protected static final boolean DEBUG_VOL = false; 337 338 /** debug calls to devices APIs */ 339 protected static final boolean DEBUG_DEVICES = false; 340 341 /** Debug communication route */ 342 protected static final boolean DEBUG_COMM_RTE = false; 343 344 /** Debug log sound fx (touchsounds...) in dumpsys */ 345 protected static final boolean DEBUG_LOG_SOUND_FX = false; 346 347 /** How long to delay before persisting a change in volume/ringer mode. */ 348 private static final int PERSIST_DELAY = 500; 349 350 /** How long to delay after a volume down event before unmuting a stream */ 351 private static final int UNMUTE_STREAM_DELAY = 350; 352 353 /** 354 * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent, 355 * to give a chance to applications to pause. 356 */ 357 @VisibleForTesting 358 public static final int BECOMING_NOISY_DELAY_MS = 1000; 359 360 /** 361 * Only used in the result from {@link #checkForRingerModeChange(int, int, int)} 362 */ 363 private static final int FLAG_ADJUST_VOLUME = 1; 364 365 final Context mContext; 366 private final ContentResolver mContentResolver; 367 private final AppOpsManager mAppOps; 368 369 /** do not use directly, use getMediaSessionManager() which handles lazy initialization */ 370 @Nullable private volatile MediaSessionManager mMediaSessionManager; 371 372 // the platform type affects volume and silent mode behavior 373 private final int mPlatformType; 374 375 // indicates whether the system maps all streams to a single stream. 376 private final boolean mIsSingleVolume; 377 378 /** 379 * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING 380 * not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}. 381 */ 382 private boolean mNotifAliasRing = false; 383 384 /** 385 * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING, 386 * volumes will be updated in case of a change. 387 * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING 388 */ 389 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setNotifAliasRingForTest(boolean alias)390 public void setNotifAliasRingForTest(boolean alias) { 391 super.setNotifAliasRingForTest_enforcePermission(); 392 boolean update = (mNotifAliasRing != alias); 393 mNotifAliasRing = alias; 394 if (update) { 395 updateStreamVolumeAlias(true, "AudioServiceTest"); 396 } 397 } 398 isPlatformVoice()399 /*package*/ boolean isPlatformVoice() { 400 return mPlatformType == AudioSystem.PLATFORM_VOICE; 401 } 402 isPlatformTelevision()403 /*package*/ boolean isPlatformTelevision() { 404 return mPlatformType == AudioSystem.PLATFORM_TELEVISION; 405 } 406 isPlatformAutomotive()407 /*package*/ boolean isPlatformAutomotive() { 408 return mPlatformType == AudioSystem.PLATFORM_AUTOMOTIVE; 409 } 410 411 /** The controller for the volume UI. */ 412 private final VolumeController mVolumeController = new VolumeController(); 413 414 /** Used only for testing to enable/disable the long press timeout volume actions. */ 415 private final AtomicBoolean mVolumeControllerLongPressEnabled = new AtomicBoolean(true); 416 417 // sendMsg() flags 418 /** If the msg is already queued, replace it with this one. */ 419 private static final int SENDMSG_REPLACE = 0; 420 /** If the msg is already queued, ignore this one and leave the old. */ 421 private static final int SENDMSG_NOOP = 1; 422 /** If the msg is already queued, queue this one and leave the old. */ 423 private static final int SENDMSG_QUEUE = 2; 424 425 // AudioHandler messages 426 /*package*/ static final int MSG_SET_DEVICE_VOLUME = 0; 427 private static final int MSG_PERSIST_VOLUME = 1; 428 private static final int MSG_PERSIST_VOLUME_GROUP = 2; 429 private static final int MSG_PERSIST_RINGER_MODE = 3; 430 private static final int MSG_AUDIO_SERVER_DIED = 4; 431 private static final int MSG_PLAY_SOUND_EFFECT = 5; 432 private static final int MSG_LOAD_SOUND_EFFECTS = 7; 433 private static final int MSG_SET_FORCE_USE = 8; 434 private static final int MSG_SET_ALL_VOLUMES = 10; 435 private static final int MSG_UNLOAD_SOUND_EFFECTS = 15; 436 private static final int MSG_SYSTEM_READY = 16; 437 private static final int MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE = 18; 438 private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19; 439 private static final int MSG_INDICATE_SYSTEM_READY = 20; 440 private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21; 441 private static final int MSG_NOTIFY_VOL_EVENT = 22; 442 private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23; 443 private static final int MSG_ENABLE_SURROUND_FORMATS = 24; 444 private static final int MSG_UPDATE_RINGER_MODE = 25; 445 private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26; 446 private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27; 447 private static final int MSG_HDMI_VOLUME_CHECK = 28; 448 private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29; 449 private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30; 450 private static final int MSG_CHECK_MODE_FOR_UID = 31; 451 private static final int MSG_STREAM_DEVICES_CHANGED = 32; 452 private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33; 453 private static final int MSG_REINIT_VOLUMES = 34; 454 private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35; 455 private static final int MSG_UPDATE_AUDIO_MODE = 36; 456 private static final int MSG_RECORDING_CONFIG_CHANGE = 37; 457 private static final int MSG_BT_DEV_CHANGED = 38; 458 private static final int MSG_UPDATE_AUDIO_MODE_SIGNAL = 39; 459 private static final int MSG_DISPATCH_AUDIO_MODE = 40; 460 private static final int MSG_ROUTING_UPDATED = 41; 461 private static final int MSG_INIT_HEADTRACKING_SENSORS = 42; 462 private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44; 463 private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; 464 private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; 465 private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47; 466 private static final int MSG_ROTATION_UPDATE = 48; 467 private static final int MSG_FOLD_UPDATE = 49; 468 private static final int MSG_RESET_SPATIALIZER = 50; 469 private static final int MSG_NO_LOG_FOR_PLAYER_I = 51; 470 private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52; 471 private static final int MSG_CONFIGURATION_CHANGED = 54; 472 private static final int MSG_BROADCAST_MASTER_MUTE = 55; 473 private static final int MSG_UPDATE_CONTEXTUAL_VOLUMES = 56; 474 private static final int MSG_BT_COMM_DEVICE_ACTIVE_UPDATE = 57; 475 476 /** 477 * Messages handled by the {@link SoundDoseHelper}, do not exceed 478 * {@link MUSICFX_HELPER_MSG_START}. 479 */ 480 /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000; 481 482 /** Messages handled by the {@link MusicFxHelper}. */ 483 /*package*/ static final int MUSICFX_HELPER_MSG_START = 1100; 484 485 // start of messages handled under wakelock 486 // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), 487 // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) 488 private static final int MSG_DISABLE_AUDIO_FOR_UID = 100; 489 private static final int MSG_INIT_STREAMS_VOLUMES = 101; 490 private static final int MSG_INIT_SPATIALIZER = 102; 491 private static final int MSG_INIT_ADI_DEVICE_STATES = 103; 492 493 private static final int MSG_INIT_INPUT_GAINS = 104; 494 private static final int MSG_APPLY_INPUT_GAIN_INDEX = 105; 495 private static final int MSG_PERSIST_INPUT_GAIN_INDEX = 106; 496 497 // end of messages handled under wakelock 498 499 // retry delay in case of failure to indicate system ready to AudioFlinger 500 private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; 501 502 // List of empty UIDs used to reset the active assistant list 503 private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0]; 504 505 // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION 506 private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000; 507 508 // Roughly chosen to be long enough to suppress the autocork behavior of the permission 509 // cache (50ms), while not introducing visible permission leaks - since the app needs to 510 // restart, and trigger an action which requires permissions from audioserver before this 511 // delay. For RECORD_AUDIO, we are additionally protected by appops. 512 private static final int SCHEDULED_PERMISSION_UPDATE_DELAY_MS = 60; 513 514 // Increased delay to not interefere with low core app launch latency 515 private static final int SCHEDULED_PERMISSION_UPDATE_LONG_DELAY_MS = 500; 516 517 /** @see AudioSystemThread */ 518 private AudioSystemThread mAudioSystemThread; 519 /** @see AudioHandler */ 520 private AudioHandler mAudioHandler; 521 /** 522 * @see VolumeStreamState 523 * Mapping which contains for each stream type its associated {@link VolumeStreamState} 524 **/ 525 private SparseArray<VolumeStreamState> mStreamStates; 526 527 /** 528 * @see InputDeviceVolumeHelper 529 */ 530 private InputDeviceVolumeHelper mInputDeviceVolumeHelper; 531 getVolumeForDeviceIgnoreMute(int stream, int device)532 /*package*/ int getVolumeForDeviceIgnoreMute(int stream, int device) { 533 final VolumeStreamState streamState = mStreamStates.get(stream); 534 return streamState != null ? streamState.getIndex(device) : -1; 535 } 536 537 /** 538 * Returns the {@link VolumeStreamState} corresponding to the passed stream type. This can be 539 * {@code null} since not all possible stream types have a valid {@link VolumeStreamState} (e.g. 540 * {@link AudioSystem#STREAM_BLUETOOTH_SCO}) is deprecated and will return a {@code null} stream 541 * state). 542 * 543 * @param stream the stream type for querying the stream state 544 * 545 * @return the {@link VolumeStreamState} corresponding to the passed stream type or {@code null} 546 */ 547 @Nullable getVssForStream(int stream)548 /*package*/ VolumeStreamState getVssForStream(int stream) { 549 return mStreamStates.get(stream); 550 } 551 552 /** 553 * Returns the {@link VolumeStreamState} corresponding to the passed stream type. In case 554 * there is no associated stream state for the given stream type we return the default stream 555 * state for {@link AudioSystem#STREAM_MUSIC} (or throw an {@link IllegalArgumentException} in 556 * the ramp up phase of the replaceStreamBtSco flag to ensure that this case will never happen). 557 * 558 * @param stream the stream type for querying the stream state 559 * 560 * @return the {@link VolumeStreamState} corresponding to the passed stream type 561 */ 562 @NonNull getVssForStreamOrDefault(int stream)563 /*package*/ VolumeStreamState getVssForStreamOrDefault(int stream) { 564 VolumeStreamState streamState = mStreamStates.get(stream); 565 if (streamState == null) { 566 if (replaceStreamBtSco()) { 567 throw new IllegalArgumentException("No VolumeStreamState for stream " + stream); 568 } else { 569 Log.e(TAG, "No VolumeStreamState for stream " + stream 570 + ". Returning default state for STREAM_MUSIC", new Exception()); 571 streamState = mStreamStates.get(AudioSystem.STREAM_MUSIC); 572 } 573 } 574 return streamState; 575 } 576 getMaxVssVolumeForStream(int stream)577 /*package*/ int getMaxVssVolumeForStream(int stream) { 578 final VolumeStreamState streamState = mStreamStates.get(stream); 579 return streamState != null ? streamState.getMaxIndex() : -1; 580 } 581 582 private SettingsObserver mSettingsObserver; 583 584 private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL); 585 586 // protects mRingerMode 587 private final Object mSettingsLock = new Object(); 588 589 // protects VolumeStreamState / VolumeGroupState operations 590 private final Object mVolumeStateLock = new Object(); 591 592 /** Maximum volume index values for audio streams */ 593 protected static int[] MAX_STREAM_VOLUME = new int[] { 594 5, // STREAM_VOICE_CALL 595 7, // STREAM_SYSTEM 596 7, // STREAM_RING // configured by config_audio_ring_vol_steps 597 15, // STREAM_MUSIC 598 7, // STREAM_ALARM 599 7, // STREAM_NOTIFICATION // configured by config_audio_notif_vol_steps 600 15, // STREAM_BLUETOOTH_SCO 601 7, // STREAM_SYSTEM_ENFORCED 602 15, // STREAM_DTMF 603 15, // STREAM_TTS 604 15, // STREAM_ACCESSIBILITY 605 15 // STREAM_ASSISTANT 606 }; 607 608 /** Minimum volume index values for audio streams */ 609 protected static int[] MIN_STREAM_VOLUME = new int[] { 610 1, // STREAM_VOICE_CALL 611 0, // STREAM_SYSTEM 612 0, // STREAM_RING 613 0, // STREAM_MUSIC 614 1, // STREAM_ALARM 615 0, // STREAM_NOTIFICATION 616 0, // STREAM_BLUETOOTH_SCO 617 0, // STREAM_SYSTEM_ENFORCED 618 0, // STREAM_DTMF 619 0, // STREAM_TTS 620 1, // STREAM_ACCESSIBILITY 621 0 // STREAM_ASSISTANT 622 }; 623 624 /* sStreamVolumeAlias[] indicates for each stream if it uses the volume settings 625 * of another stream: This avoids multiplying the volume settings for hidden 626 * stream types that follow other stream behavior for volume settings 627 * NOTE: do not create loops in aliases! 628 * Some streams alias to different streams according to device category (phone or tablet) or 629 * use case (in call vs off call...). See updateStreamVolumeAlias() for more details. 630 * sStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device 631 * (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and 632 * STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/ 633 private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] { 634 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 635 AudioSystem.STREAM_RING, // STREAM_SYSTEM 636 AudioSystem.STREAM_RING, // STREAM_RING 637 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 638 AudioSystem.STREAM_ALARM, // STREAM_ALARM 639 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 640 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 641 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 642 AudioSystem.STREAM_RING, // STREAM_DTMF 643 AudioSystem.STREAM_MUSIC, // STREAM_TTS 644 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 645 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 646 }; 647 private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { 648 AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL 649 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM 650 AudioSystem.STREAM_MUSIC, // STREAM_RING 651 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 652 AudioSystem.STREAM_MUSIC, // STREAM_ALARM 653 AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION 654 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 655 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED 656 AudioSystem.STREAM_MUSIC, // STREAM_DTMF 657 AudioSystem.STREAM_MUSIC, // STREAM_TTS 658 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 659 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 660 }; 661 /** 662 * Using Volume groups configuration allows to control volume per attributes 663 * and group definition may differ from stream aliases. 664 * So, do not alias any stream on one another when using volume groups. 665 * TODO(b/181140246): volume group definition hosting alias definition. 666 */ 667 private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] { 668 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 669 AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM 670 AudioSystem.STREAM_RING, // STREAM_RING 671 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 672 AudioSystem.STREAM_ALARM, // STREAM_ALARM 673 AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION 674 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 675 AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED 676 AudioSystem.STREAM_DTMF, // STREAM_DTMF 677 AudioSystem.STREAM_TTS, // STREAM_TTS 678 AudioSystem.STREAM_ACCESSIBILITY, // STREAM_ACCESSIBILITY 679 AudioSystem.STREAM_ASSISTANT // STREAM_ASSISTANT 680 }; 681 private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { 682 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 683 AudioSystem.STREAM_RING, // STREAM_SYSTEM 684 AudioSystem.STREAM_RING, // STREAM_RING 685 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 686 AudioSystem.STREAM_ALARM, // STREAM_ALARM 687 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 688 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 689 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 690 AudioSystem.STREAM_RING, // STREAM_DTMF 691 AudioSystem.STREAM_MUSIC, // STREAM_TTS 692 AudioSystem.STREAM_MUSIC, // STREAM_ACCESSIBILITY 693 AudioSystem.STREAM_MUSIC // STREAM_ASSISTANT 694 }; 695 protected static SparseIntArray sStreamVolumeAlias; 696 private static final int UNSET_INDEX = -1; 697 698 /** 699 * Map AudioSystem.STREAM_* constants to app ops. This should be used 700 * after mapping through sStreamVolumeAlias. 701 */ 702 private static final int[] STREAM_VOLUME_OPS = new int[] { 703 AppOpsManager.OP_AUDIO_VOICE_VOLUME, // STREAM_VOICE_CALL 704 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM 705 AppOpsManager.OP_AUDIO_RING_VOLUME, // STREAM_RING 706 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_MUSIC 707 AppOpsManager.OP_AUDIO_ALARM_VOLUME, // STREAM_ALARM 708 AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, // STREAM_NOTIFICATION 709 AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, // STREAM_BLUETOOTH_SCO 710 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED 711 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF 712 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS 713 AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME, // STREAM_ACCESSIBILITY 714 AppOpsManager.OP_AUDIO_MEDIA_VOLUME // STREAM_ASSISTANT 715 }; 716 717 private final boolean mUseFixedVolume; 718 private final boolean mRingerModeAffectsAlarm; 719 private final boolean mUseVolumeGroupAliases; 720 721 // If absolute volume is supported in AVRCP device 722 private volatile boolean mAvrcpAbsVolSupported = false; 723 724 private final Object mCachedAbsVolDrivingStreamsLock = new Object(); 725 // Contains for all the device types which support absolute volume the current streams that 726 // are driving the volume changes 727 @GuardedBy("mCachedAbsVolDrivingStreamsLock") 728 private final HashMap<Integer, Integer> mCachedAbsVolDrivingStreams = new HashMap<>( 729 Map.of(AudioSystem.DEVICE_OUT_BLE_HEADSET, AudioSystem.STREAM_MUSIC, 730 AudioSystem.DEVICE_OUT_BLE_SPEAKER, AudioSystem.STREAM_MUSIC, 731 AudioSystem.DEVICE_OUT_BLE_BROADCAST, AudioSystem.STREAM_MUSIC, 732 AudioSystem.DEVICE_OUT_HEARING_AID, AudioSystem.STREAM_MUSIC 733 )); 734 735 /** 736 * Default stream type used for volume control in the absence of playback 737 * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this 738 * stream type is controlled. 739 */ 740 protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC; 741 742 private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() { 743 public void onError(int error) { 744 switch (error) { 745 case AudioSystem.AUDIO_STATUS_SERVER_DIED: 746 // check for null in case error callback is called during instance creation 747 if (mRecordMonitor != null) { 748 mRecordMonitor.onAudioServerDied(); 749 } 750 // Notify the playback monitor that the audio server has died 751 if (mPlaybackMonitor != null) { 752 mPlaybackMonitor.onAudioServerDied(); 753 } 754 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, 755 SENDMSG_NOOP, 0, 0, null, 0); 756 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 757 SENDMSG_QUEUE, 0, 0, null, 0); 758 break; 759 default: 760 break; 761 } 762 } 763 }; 764 765 /** 766 * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL}, 767 * {@link AudioManager#RINGER_MODE_SILENT}, or 768 * {@link AudioManager#RINGER_MODE_VIBRATE}. 769 */ 770 @GuardedBy("mSettingsLock") 771 private int mRingerMode; // internal ringer mode, affects muting of underlying streams 772 @GuardedBy("mSettingsLock") 773 private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager) 774 775 /** @see System#MODE_RINGER_STREAMS_AFFECTED */ 776 @VisibleForTesting 777 protected int mRingerModeAffectedStreams = 0; 778 779 private int mZenModeAffectedStreams = 0; 780 781 // Streams currently muted by ringer mode and dnd 782 protected static volatile int sRingerAndZenModeMutedStreams; 783 784 /** Streams that can be muted by system. Do not resolve to aliases when checking. 785 * @see System#MUTE_STREAMS_AFFECTED */ 786 protected int mMuteAffectedStreams; 787 788 /** Streams that can be muted by user. Do not resolve to aliases when checking. 789 * @see System#MUTE_STREAMS_AFFECTED */ 790 private int mUserMutableStreams; 791 792 /** The active bluetooth device type used for communication is sco. */ 793 /*package*/ static final int BT_COMM_DEVICE_ACTIVE_SCO = 1; 794 /** The active bluetooth device type used for communication is ble headset. */ 795 /*package*/ static final int BT_COMM_DEVICE_ACTIVE_BLE_HEADSET = 1 << 1; 796 /** The active bluetooth device type used for communication is ble speaker. */ 797 /*package*/ static final int BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER = 1 << 2; 798 @IntDef({ 799 BT_COMM_DEVICE_ACTIVE_SCO, BT_COMM_DEVICE_ACTIVE_BLE_HEADSET, 800 BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER 801 }) 802 @Retention(RetentionPolicy.SOURCE) 803 public @interface BtCommDeviceActiveType { 804 } 805 806 private final AtomicInteger mBtCommDeviceActive = new AtomicInteger(0); 807 808 @NonNull 809 private SoundEffectsHelper mSfxHelper; 810 811 /** 812 * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated. 813 * mVibrateSetting is just maintained during deprecation period but vibration policy is 814 * now only controlled by mHasVibrator and mRingerMode 815 */ 816 private int mVibrateSetting; 817 818 // Is there a vibrator 819 private final boolean mHasVibrator; 820 // Used to play vibrations 821 private Vibrator mVibrator; 822 private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES = 823 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH); 824 825 // Handler for broadcast receiver 826 // TODO(b/335513647) combine handlers 827 private final HandlerThread mBroadcastHandlerThread; 828 // Broadcast receiver for device connections intent broadcasts 829 private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); 830 831 private final Executor mAudioServerLifecycleExecutor; 832 private long mSysPropListenerNativeHandle; 833 private CacheWatcher mCacheWatcher; 834 private final List<Future> mScheduledPermissionTasks = new ArrayList(); 835 836 private IMediaProjectionManager mProjectionService; // to validate projection token 837 838 /** Interface for UserManagerService. */ 839 private final UserManagerInternal mUserManagerInternal; 840 private final ActivityManagerInternal mActivityManagerInternal; 841 private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal; 842 843 private final UserRestrictionsListener mUserRestrictionsListener = 844 new AudioServiceUserRestrictionsListener(); 845 846 private final IAudioManagerNative mNativeShim = new IAudioManagerNative.Stub() { 847 static final String METRIC_COUNTERS_PLAYBACK_PARTIAL = 848 "media_audio.value_audio_playback_hardening_partial_restriction"; 849 static final String METRIC_COUNTERS_PLAYBACK_STRICT = 850 "media_audio.value_audio_playback_hardening_strict_would_restrict"; 851 // oneway 852 @Override 853 public void playbackHardeningEvent(int uid, byte type, boolean bypassed) { 854 if (Binder.getCallingUid() != Process.AUDIOSERVER_UID) { 855 return; 856 } 857 if (type == HardeningType.PARTIAL) { 858 Counter.logIncrementWithUid(METRIC_COUNTERS_PLAYBACK_PARTIAL, uid); 859 } else if (type == HardeningType.FULL) { 860 Counter.logIncrementWithUid(METRIC_COUNTERS_PLAYBACK_STRICT, uid); 861 } else { 862 Slog.wtf(TAG, "Unexpected hardening type" + type); 863 return; 864 } 865 String msg = "AudioHardening background playback " 866 + (bypassed ? "would be " : "") 867 + "muted for " 868 + getPackageNameForUid(uid) + " (" + uid + "), " 869 + "level: " + (type == HardeningType.PARTIAL ? "partial" : "full"); 870 871 AudioService.this.mHardeningLogger.enqueueAndSlog(msg, 872 bypassed ? EventLogger.Event.ALOGI : EventLogger.Event.ALOGW, TAG); 873 } 874 875 @Override 876 public void permissionUpdateBarrier() { 877 AudioService.this.permissionUpdateBarrier(); 878 } 879 880 /** 881 * Update mute state event for port 882 * @param portId Port id to update 883 * @param event the mute event containing info about the mute 884 */ 885 @Override 886 public void portMuteEvent(int portId, int event) { 887 mPlaybackMonitor.portMuteEvent(portId, event, Binder.getCallingUid()); 888 } 889 }; 890 891 // List of binder death handlers for setMode() client processes. 892 // The last process to have called setMode() is at the top of the list. 893 // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers 894 //TODO candidate to be moved to separate class that handles synchronization 895 @GuardedBy("mDeviceBroker.mSetModeLock") 896 /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers = 897 new ArrayList<SetModeDeathHandler>(); 898 899 // true if boot sequence has been completed 900 private boolean mSystemReady; 901 // true if Intent.ACTION_USER_SWITCHED has ever been received 902 private boolean mUserSwitchedReceived; 903 // previous volume adjustment direction received by checkForRingerModeChange() 904 private int mPrevVolDirection = AudioManager.ADJUST_SAME; 905 // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume 906 // is controlled by Vol keys. 907 private int mVolumeControlStream = -1; 908 // interpretation of whether the volume stream has been selected by the user by clicking on a 909 // volume slider to change which volume is controlled by the volume keys. Is false 910 // when mVolumeControlStream is -1. 911 private boolean mUserSelectedVolumeControlStream = false; 912 private final Object mForceControlStreamLock = new Object(); 913 // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system 914 // server process so in theory it is not necessary to monitor the client death. 915 // However it is good to be ready for future evolutions. 916 private ForceControlStreamClient mForceControlStreamClient = null; 917 // Used to play ringtones outside system_server 918 private volatile IRingtonePlayer mRingtonePlayer; 919 920 // Devices for which the volume is fixed (volume is either max or muted) 921 Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList( 922 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, 923 AudioSystem.DEVICE_OUT_AUX_LINE)); 924 // Devices for which the volume is always max, no volume panel 925 Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList( 926 AudioSystem.DEVICE_OUT_HDMI_ARC, 927 AudioSystem.DEVICE_OUT_HDMI_EARC 928 )); 929 930 private final Object mAbsoluteVolumeDeviceInfoMapLock = new Object(); 931 // Devices where the framework sends a full scale audio signal, and controls the volume of 932 // the external audio system separately. 933 // For possible volume behaviors, see 934 // {@link AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior}. 935 @GuardedBy("mAbsoluteVolumeDeviceInfoMapLock") 936 Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>(); 937 938 /** 939 * Stores information about a device using absolute volume behavior. 940 */ 941 private static final class AbsoluteVolumeDeviceInfo implements IBinder.DeathRecipient { 942 private final AudioService mParent; 943 private final AudioDeviceAttributes mDevice; 944 private final List<VolumeInfo> mVolumeInfos; 945 private final IAudioDeviceVolumeDispatcher mCallback; 946 private final boolean mHandlesVolumeAdjustment; 947 private @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior; 948 AbsoluteVolumeDeviceInfo( AudioService parent, AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment, @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int behavior)949 private AbsoluteVolumeDeviceInfo( 950 AudioService parent, 951 AudioDeviceAttributes device, 952 List<VolumeInfo> volumeInfos, 953 IAudioDeviceVolumeDispatcher callback, 954 boolean handlesVolumeAdjustment, 955 @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int behavior) { 956 this.mParent = parent; 957 this.mDevice = device; 958 this.mVolumeInfos = volumeInfos; 959 this.mCallback = callback; 960 this.mHandlesVolumeAdjustment = handlesVolumeAdjustment; 961 this.mDeviceVolumeBehavior = behavior; 962 963 try { 964 this.mCallback.asBinder().linkToDeath(this, 0); 965 } catch (RemoteException | NullPointerException e) { 966 // NPE can be raised when mocking the callback object 967 Slog.w(TAG, "Exception: " + e 968 + "\nCannot listen to callback binder death for device " + mDevice); 969 } 970 } 971 972 /** 973 * Given a stream type, returns a matching VolumeInfo. 974 */ 975 @Nullable getMatchingVolumeInfoForStream(int streamType)976 private VolumeInfo getMatchingVolumeInfoForStream(int streamType) { 977 for (VolumeInfo volumeInfo : mVolumeInfos) { 978 boolean streamTypeMatches = volumeInfo.hasStreamType() 979 && volumeInfo.getStreamType() == streamType; 980 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup() 981 && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes()) 982 .anyMatch(s -> s == streamType); 983 if (streamTypeMatches || volumeGroupMatches) { 984 return volumeInfo; 985 } 986 } 987 return null; 988 } 989 990 @Override binderDied()991 public void binderDied() { 992 if (mParent.removeAudioSystemDeviceOutFromAbsVolumeDevices(mDevice.getInternalType()) 993 != null) { 994 mParent.dispatchDeviceVolumeBehavior(mDevice, 995 AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE); 996 } 997 } 998 unlinkToDeath()999 public void unlinkToDeath() { 1000 try { 1001 mCallback.asBinder().unlinkToDeath(this, 0); 1002 } catch (NullPointerException e) { 1003 // NPE can be raised when mocking the callback object 1004 Slog.w(TAG, "Exception: " + e 1005 + "\nCannot unlink to death, null binder object for device " + mDevice); 1006 } 1007 } 1008 } 1009 1010 // Devices for the which use the "absolute volume" concept (framework sends audio signal 1011 // full scale, and volume control separately) and can be used for multiple use cases reflected 1012 // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL). 1013 Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>( 1014 Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID, 1015 AudioSystem.DEVICE_OUT_BLE_HEADSET, 1016 AudioSystem.DEVICE_OUT_BLE_SPEAKER)); 1017 1018 private final boolean mMonitorRotation; 1019 1020 private boolean mDockAudioMediaEnabled = true; 1021 1022 /** 1023 * RestorableParameters is a thread-safe class used to store a 1024 * first-in first-out history of parameters for replay / restoration. 1025 * 1026 * The idealized implementation of restoration would have a list of setting methods and 1027 * values to be called for restoration. Explicitly managing such setters and 1028 * values would be tedious - a simpler method is to store the values and the 1029 * method implicitly by lambda capture (the values must be immutable or synchronization 1030 * needs to be taken). 1031 * 1032 * We provide queueRestoreWithRemovalIfTrue() to allow 1033 * the caller to provide a BooleanSupplier lambda, which conveniently packages 1034 * the setter and its parameters needed for restoration. If during restoration, 1035 * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap 1036 * so as not to be called on a subsequent restore. 1037 * 1038 * We provide a setParameters() method as an example helper method. 1039 */ 1040 private static class RestorableParameters { 1041 /** 1042 * Sets a parameter and queues for restoration if successful. 1043 * 1044 * @param id a string handle associated with this parameter. 1045 * @param parameter the actual parameter string. 1046 * @return the result of AudioSystem.setParameters 1047 */ setParameters(@onNull String id, @NonNull String parameter)1048 public int setParameters(@NonNull String id, @NonNull String parameter) { 1049 Objects.requireNonNull(id, "id must not be null"); 1050 Objects.requireNonNull(parameter, "parameter must not be null"); 1051 synchronized (mMap) { 1052 final int status = AudioSystem.setParameters(parameter); 1053 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes. 1054 queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails. 1055 return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK; 1056 }); 1057 } 1058 // Implementation detail: We do not mMap.remove(id); on failure. 1059 return status; 1060 } 1061 } 1062 1063 /** 1064 * Queues a restore method which is executed on restoreAll(). 1065 * 1066 * If the supplier null, the id is removed from the restore map. 1067 * 1068 * Note: When the BooleanSupplier restore method is executed 1069 * during restoreAll, if it returns true, it is removed from the 1070 * restore map. 1071 * 1072 * @param id a unique tag associated with the restore method. 1073 * @param supplier is a BooleanSupplier lambda. 1074 */ queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)1075 public void queueRestoreWithRemovalIfTrue( 1076 @NonNull String id, @Nullable BooleanSupplier supplier) { 1077 Objects.requireNonNull(id, "id must not be null"); 1078 synchronized (mMap) { 1079 if (supplier != null) { 1080 mMap.put(id, supplier); 1081 } else { 1082 mMap.remove(id); 1083 } 1084 } 1085 } 1086 1087 /** 1088 * Restore all parameters 1089 * 1090 * During restoration after audioserver death, any BooleanSupplier that returns 1091 * true, for example on parameter restoration error, will be removed from mMap 1092 * so as not to be executed on a subsequent restoreAll(). 1093 */ restoreAll()1094 public void restoreAll() { 1095 synchronized (mMap) { 1096 // Note: removing from values() also removes from the backing map. 1097 // TODO: Consider catching exceptions? 1098 mMap.values().removeIf(v -> { 1099 return v.getAsBoolean(); // this iterates the setters(). 1100 }); 1101 } 1102 } 1103 1104 /** 1105 * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore(). 1106 * The Key is a unique id tag for identification. 1107 * The Value is a lambda expression which returns true if the entry is to 1108 * be removed. 1109 * 1110 * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES 1111 * accessed in the map. 1112 * 2) Parameters are restored in order of queuing, first in first out, 1113 * from earliest to latest. 1114 */ 1115 @GuardedBy("mMap") 1116 private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap = 1117 new LinkedHashMap<>() { 1118 // TODO: do we need this memory limitation? 1119 private static final int MAX_ENTRIES = 1000; // limit our memory for now. 1120 @Override 1121 protected boolean removeEldestEntry(Map.Entry eldest) { 1122 if (size() <= MAX_ENTRIES) return false; 1123 Log.w(TAG, "Parameter map exceeds " 1124 + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove. 1125 return true; 1126 } 1127 }; 1128 } 1129 1130 // We currently have one instance for mRestorableParameters used for 1131 // setAdditionalOutputDeviceDelay(). Other methods requiring restoration could share this 1132 // or use their own instance. 1133 private RestorableParameters mRestorableParameters = new RestorableParameters(); 1134 1135 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 1136 1137 private PowerManager.WakeLock mAudioEventWakeLock; 1138 1139 private final MediaFocusControl mMediaFocusControl; 1140 1141 // Pre-scale for Bluetooth Absolute Volume 1142 private float[] mPrescaleAbsoluteVolume = new float[] { 1143 0.6f, // Pre-scale for index 1 1144 0.8f, // Pre-scale for index 2 1145 0.9f, // Pre-scale for index 3 1146 }; 1147 1148 private NotificationManager mNm; 1149 private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; 1150 private volatile VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; 1151 private long mLoweredFromNormalToVibrateTime; 1152 1153 // Array of Uids of valid assistant services to check if caller is one of them 1154 @GuardedBy("mSettingsLock") 1155 private final ArraySet<Integer> mAssistantUids = new ArraySet<>(); 1156 @GuardedBy("mSettingsLock") 1157 private int mPrimaryAssistantUid = INVALID_UID; 1158 1159 // Array of Uids of valid active assistant service to check if caller is one of them 1160 @GuardedBy("mSettingsLock") 1161 private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 1162 1163 // Array of Uids of valid accessibility services to check if caller is one of them 1164 private final Object mAccessibilityServiceUidsLock = new Object(); 1165 @GuardedBy("mAccessibilityServiceUidsLock") 1166 private int[] mAccessibilityServiceUids; 1167 1168 // Input Method 1169 private final Object mInputMethodServiceUidLock = new Object(); 1170 // Uid of the active input method service to check if caller is the one or not. 1171 @GuardedBy("mInputMethodServiceUidLock") 1172 private int mInputMethodServiceUid = android.os.Process.INVALID_UID; 1173 1174 private int mEncodedSurroundMode; 1175 private String mEnabledSurroundFormats; 1176 private boolean mSurroundModeChanged; 1177 1178 private boolean mSupportsMicPrivacyToggle; 1179 1180 private boolean mMicMuteFromSwitch; 1181 private boolean mMicMuteFromApi; 1182 private boolean mMicMuteFromRestrictions; 1183 private boolean mMicMuteFromPrivacyToggle; 1184 // caches the value returned by AudioSystem.isMicrophoneMuted() 1185 private boolean mMicMuteFromSystemCached; 1186 1187 private boolean mNavigationRepeatSoundEffectsEnabled; 1188 private boolean mHomeSoundEffectEnabled; 1189 1190 private final SoundDoseHelper mSoundDoseHelper; 1191 1192 private final LoudnessCodecHelper mLoudnessCodecHelper; 1193 1194 private final HardeningEnforcer mHardeningEnforcer; 1195 1196 private final AudioVolumeGroupHelperBase mAudioVolumeGroupHelper; 1197 1198 private final Object mSupportedSystemUsagesLock = new Object(); 1199 @GuardedBy("mSupportedSystemUsagesLock") 1200 private @AttributeSystemUsage int[] mSupportedSystemUsages = 1201 new int[]{AudioAttributes.USAGE_CALL_ASSISTANT}; 1202 1203 // Tracks the API/shell override of hardening enforcement used for debugging 1204 // When this is set to true, enforcement is on regardless of flag state and any specific 1205 // exemptions in place for compat purposes. 1206 private final AtomicBoolean mShouldEnableAllHardening = new AtomicBoolean(false); 1207 1208 // Defines the format for the connection "address" for ALSA devices makeAlsaAddressString(int card, int device)1209 public static String makeAlsaAddressString(int card, int device) { 1210 return "card=" + card + ";device=" + device; 1211 } 1212 1213 private static class AudioVolumeGroupHelper extends AudioVolumeGroupHelperBase { 1214 @Override getAudioVolumeGroups()1215 public List<AudioVolumeGroup> getAudioVolumeGroups() { 1216 return AudioVolumeGroup.getAudioVolumeGroups(); 1217 } 1218 } 1219 1220 public static final class Lifecycle extends SystemService { 1221 private AudioService mService; 1222 Lifecycle(Context context)1223 public Lifecycle(Context context) { 1224 super(context); 1225 var audioserverLifecycleExecutor = Executors.newSingleThreadScheduledExecutor( 1226 (Runnable r) -> new Thread(r, "audioserver_lifecycle")); 1227 var audioPolicyFacade = new DefaultAudioPolicyFacade(audioserverLifecycleExecutor); 1228 mService = new AudioService(context, 1229 AudioSystemAdapter.getDefaultAdapter(), 1230 SystemServerAdapter.getDefaultAdapter(context), 1231 SettingsAdapter.getDefaultAdapter(), 1232 new AudioVolumeGroupHelper(), 1233 audioPolicyFacade, 1234 null, 1235 context.getSystemService(AppOpsManager.class), 1236 PermissionEnforcer.fromContext(context), 1237 audioserverPermissions() ? 1238 initializeAudioServerPermissionProvider( 1239 context, audioPolicyFacade, audioserverLifecycleExecutor) : 1240 null, 1241 audioserverLifecycleExecutor 1242 ); 1243 } 1244 1245 @Override onStart()1246 public void onStart() { 1247 publishBinderService(Context.AUDIO_SERVICE, mService); 1248 } 1249 1250 @Override onBootPhase(int phase)1251 public void onBootPhase(int phase) { 1252 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 1253 mService.systemReady(); 1254 } 1255 } 1256 } 1257 1258 final private IUidObserver mUidObserver = new UidObserver() { 1259 @Override public void onUidGone(int uid, boolean disabled) { 1260 // Once the uid is no longer running, no need to keep trying to disable its audio. 1261 disableAudioForUid(false, uid); 1262 } 1263 1264 @Override public void onUidCachedChanged(int uid, boolean cached) { 1265 disableAudioForUid(cached, uid); 1266 } 1267 1268 private void disableAudioForUid(boolean disable, int uid) { 1269 queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID, 1270 disable ? 1 : 0 /* arg1 */, uid /* arg2 */, 1271 null /* obj */, 0 /* delay */); 1272 } 1273 }; 1274 1275 private AtomicBoolean mRttEnabled = new AtomicBoolean(false); 1276 1277 private AtomicBoolean mMasterMute = new AtomicBoolean(false); 1278 1279 private DisplayManager mDisplayManager; 1280 1281 private DisplayListener mDisplayListener = 1282 new DisplayListener() { 1283 @Override 1284 public void onDisplayAdded(int displayId) {} 1285 1286 @Override 1287 public void onDisplayRemoved(int displayId) {} 1288 1289 @Override 1290 public void onDisplayChanged(int displayId) { 1291 if (displayId != Display.DEFAULT_DISPLAY) { 1292 return; 1293 } 1294 int displayState = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState(); 1295 if (displayState == Display.STATE_ON) { 1296 if (mMonitorRotation) { 1297 RotationHelper.enable(); 1298 } 1299 AudioSystem.setParameters("screen_state=on"); 1300 } else { 1301 if (mMonitorRotation) { 1302 //reduce wakeups (save current) by only listening when display is on 1303 RotationHelper.disable(); 1304 } 1305 AudioSystem.setParameters("screen_state=off"); 1306 } 1307 } 1308 }; 1309 1310 /////////////////////////////////////////////////////////////////////////// 1311 // Construction 1312 /////////////////////////////////////////////////////////////////////////// 1313 1314 1315 /** 1316 * @param context 1317 * @param audioSystem Adapter for {@link AudioSystem} 1318 * @param systemServer Adapter for privilieged functionality for system server components 1319 * @param settings Adapter for {@link Settings} 1320 * @param audioVolumeGroupHelper Adapter for {@link AudioVolumeGroup} 1321 * @param audioPolicy Interface of a facade to IAudioPolicyManager 1322 * @param looper Looper to use for the service's message handler. If this is null, an 1323 * {@link AudioSystemThread} is created as the messaging thread instead. 1324 * @param appOps {@link AppOpsManager} system service 1325 * @param enforcer Used for permission enforcing 1326 * @param permissionProvider Used to push permissions to audioserver 1327 * @param audioserverLifecycleExecutor Used for tasks managing audioserver lifecycle 1328 */ 1329 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioVolumeGroupHelperBase audioVolumeGroupHelper, AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer, AudioServerPermissionProvider permissionProvider, Executor audioserverLifecycleExecutor)1330 public AudioService(Context context, AudioSystemAdapter audioSystem, 1331 SystemServerAdapter systemServer, SettingsAdapter settings, 1332 AudioVolumeGroupHelperBase audioVolumeGroupHelper, AudioPolicyFacade audioPolicy, 1333 @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer, 1334 /* @NonNull */ AudioServerPermissionProvider permissionProvider, 1335 Executor audioserverLifecycleExecutor) { 1336 super(enforcer); 1337 sLifecycleLogger.enqueue(new EventLogger.StringEvent("AudioService()")); 1338 mContext = context; 1339 mContentResolver = context.getContentResolver(); 1340 mAppOps = appOps; 1341 1342 mPermissionProvider = permissionProvider; 1343 mAudioServerLifecycleExecutor = audioserverLifecycleExecutor; 1344 1345 mAudioSystem = audioSystem; 1346 mSystemServer = systemServer; 1347 mAudioVolumeGroupHelper = audioVolumeGroupHelper; 1348 mSettings = settings; 1349 mAudioPolicy = audioPolicy; 1350 mAudioPolicy.registerOnStartTask(() -> { 1351 mAudioPolicy.setEnableHardening(mShouldEnableAllHardening.get()); 1352 }); 1353 1354 mPlatformType = AudioSystem.getPlatformType(context); 1355 1356 mBroadcastHandlerThread = new HandlerThread("AudioService Broadcast"); 1357 mBroadcastHandlerThread.start(); 1358 1359 mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem); 1360 1361 mIsSingleVolume = AudioSystem.isSingleVolume(context); 1362 1363 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 1364 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 1365 mSensorPrivacyManagerInternal = 1366 LocalServices.getService(SensorPrivacyManagerInternal.class); 1367 1368 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1369 mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); 1370 1371 mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase)); 1372 1373 boolean binauralEnabledDefault = SystemProperties.getBoolean( 1374 "ro.audio.spatializer_binaural_enabled_default", true); 1375 boolean transauralEnabledDefault = SystemProperties.getBoolean( 1376 "ro.audio.spatializer_transaural_enabled_default", true); 1377 boolean headTrackingEnabledDefault = mContext.getResources().getBoolean( 1378 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default); 1379 1380 mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, mDeviceBroker, 1381 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault); 1382 1383 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 1384 mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); 1385 1386 mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class) 1387 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE); 1388 1389 mUseVolumeGroupAliases = mContext.getResources().getBoolean( 1390 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups); 1391 1392 mAudioVolumeChangeHandler = new AudioVolumeChangeHandler(mAudioSystem); 1393 // Initialize volume 1394 // Priority 1 - Android Property 1395 // Priority 2 - Audio Policy Service 1396 // Priority 3 - Default Value 1397 if (AudioProductStrategy.getAudioProductStrategies().size() > 0) { 1398 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1399 1400 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1401 AudioAttributes attr = 1402 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( 1403 streamType); 1404 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); 1405 if (maxVolume != -1) { 1406 MAX_STREAM_VOLUME[streamType] = maxVolume; 1407 } 1408 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); 1409 if (minVolume != -1) { 1410 MIN_STREAM_VOLUME[streamType] = minVolume; 1411 } 1412 } 1413 if (mUseVolumeGroupAliases) { 1414 // Set all default to uninitialized. 1415 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) { 1416 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX; 1417 } 1418 } 1419 } 1420 1421 int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); 1422 if (maxCallVolume != -1) { 1423 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume; 1424 } 1425 1426 int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1); 1427 if (defaultCallVolume != -1 && 1428 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] && 1429 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { 1430 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume; 1431 } else { 1432 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = 1433 (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4; 1434 } 1435 1436 int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1); 1437 if (maxMusicVolume != -1) { 1438 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume; 1439 } 1440 1441 int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1); 1442 if (defaultMusicVolume != -1 && 1443 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] && 1444 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { 1445 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume; 1446 } else { 1447 if (isPlatformTelevision()) { 1448 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1449 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4; 1450 } else { 1451 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = 1452 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3; 1453 } 1454 } 1455 1456 int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1); 1457 if (maxAlarmVolume != -1) { 1458 MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume; 1459 } 1460 1461 if (alarmMinVolumeZero()) { 1462 try { 1463 int minAlarmVolume = mContext.getResources().getInteger( 1464 com.android.internal.R.integer.config_audio_alarm_min_vol); 1465 if (minAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) { 1466 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = minAlarmVolume; 1467 } else { 1468 Log.e(TAG, "Error min alarm volume greater than max alarm volume"); 1469 } 1470 } catch (Resources.NotFoundException e) { 1471 Log.e(TAG, "Error querying for alarm min volume ", e); 1472 } 1473 } 1474 int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1); 1475 if (defaultAlarmVolume != -1 && 1476 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) { 1477 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume; 1478 } else { 1479 // Default is 6 out of 7 (default maximum), so scale accordingly. 1480 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = 1481 6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7; 1482 } 1483 1484 int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1); 1485 if (maxSystemVolume != -1) { 1486 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume; 1487 } 1488 1489 int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1); 1490 if (defaultSystemVolume != -1 && 1491 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) { 1492 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume; 1493 } else { 1494 // Default is to use maximum. 1495 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = 1496 MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]; 1497 } 1498 1499 int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1); 1500 if (minAssistantVolume != -1) { 1501 MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume; 1502 } 1503 1504 // Read following properties to configure max volume (number of steps) and default volume 1505 // for STREAM_NOTIFICATION and STREAM_RING: 1506 // config_audio_notif_vol_default 1507 // config_audio_notif_vol_steps 1508 // config_audio_ring_vol_default 1509 // config_audio_ring_vol_steps 1510 int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING }; 1511 int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps, 1512 com.android.internal.R.integer.config_audio_ring_vol_steps }; 1513 int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default, 1514 com.android.internal.R.integer.config_audio_ring_vol_default }; 1515 for (int s = 0; s < streams.length; s++) { 1516 try { 1517 final int maxVol = mContext.getResources().getInteger(stepsResId[s]); 1518 if (maxVol <= 0) { 1519 throw new IllegalArgumentException("Invalid negative max volume for stream " 1520 + streams[s]); 1521 } 1522 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol); 1523 MAX_STREAM_VOLUME[streams[s]] = maxVol; 1524 } catch (Resources.NotFoundException e) { 1525 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e); 1526 } 1527 try { 1528 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]); 1529 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) { 1530 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1531 + ") for stream " + streams[s] + ", greater than max volume of " 1532 + MAX_STREAM_VOLUME[streams[s]]); 1533 } 1534 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) { 1535 throw new IllegalArgumentException("Invalid default volume (" + defaultVol 1536 + ") for stream " + streams[s] + ", lower than min volume of " 1537 + MIN_STREAM_VOLUME[streams[s]]); 1538 } 1539 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol); 1540 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol; 1541 } catch (Resources.NotFoundException e) { 1542 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e); 1543 } 1544 } 1545 1546 if (looper == null) { 1547 createAudioSystemThread(); 1548 } else { 1549 mAudioHandler = new AudioHandler(looper); 1550 } 1551 1552 mSoundDoseHelper = new SoundDoseHelper(this, mContext, mAudioHandler, mSettings, 1553 mVolumeController); 1554 1555 AudioSystem.setErrorCallback(mAudioSystemCallback); 1556 1557 updateAudioHalPids(); 1558 1559 mUseFixedVolume = mContext.getResources().getBoolean( 1560 com.android.internal.R.bool.config_useFixedVolume); 1561 1562 mRingerModeAffectsAlarm = mContext.getResources().getBoolean( 1563 com.android.internal.R.bool.config_audio_ringer_mode_affects_alarm_stream); 1564 1565 mRecordMonitor = new RecordingActivityMonitor(mContext); 1566 mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true); 1567 1568 // must be called before readPersistedSettings() which needs a valid sStreamVolumeAlias[] 1569 // array initialized by updateStreamVolumeAlias() 1570 updateStreamVolumeAlias(false /*updateVolumes*/, TAG); 1571 readPersistedSettings(); 1572 readUserRestrictions(); 1573 1574 mLoudnessCodecHelper = new LoudnessCodecHelper(this); 1575 1576 mPlaybackMonitor = 1577 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM], 1578 device -> onMuteAwaitConnectionTimeout(device), 1579 stream -> isStreamMute(stream)); 1580 mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true); 1581 1582 mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor); 1583 1584 readAndSetLowRamDevice(); 1585 1586 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 1587 1588 if (mSystemServer.isPrivileged()) { 1589 LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); 1590 1591 mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); 1592 1593 mRecordMonitor.initMonitor(); 1594 } 1595 1596 mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); 1597 1598 mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false); 1599 1600 // monitor routing updates coming from native 1601 mAudioSystem.setRoutingListener(this); 1602 // monitor requests for volume range initialization coming from native (typically when 1603 // errors are found by AudioPolicyManager 1604 mAudioSystem.setVolRangeInitReqListener(this); 1605 1606 // done with service initialization, continue additional work in our Handler thread 1607 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES, 1608 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1609 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES, 1610 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1611 queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER, 1612 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */); 1613 if (enableAudioInputDeviceRoutingAndVolumeControl()) { 1614 queueMsgUnderWakeLock( 1615 mAudioHandler, 1616 MSG_INIT_INPUT_GAINS, 1617 0 /* arg1 */, 1618 0 /* arg2 */, 1619 null /* obj */, 1620 0 /* delay */); 1621 } 1622 1623 mDisplayManager = context.getSystemService(DisplayManager.class); 1624 1625 mMusicFxHelper = new MusicFxHelper(mContext, mAudioHandler); 1626 1627 mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive(), 1628 mShouldEnableAllHardening, 1629 mAppOps, 1630 context.getPackageManager(), 1631 mHardeningLogger); 1632 } 1633 initVolumeStreamStates()1634 private void initVolumeStreamStates() { 1635 int numStreamTypes = AudioSystem.getNumStreamTypes(); 1636 synchronized (mVolumeStateLock) { 1637 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 1638 final VolumeStreamState streamState = getVssForStream(streamType); 1639 if (streamState == null) { 1640 continue; 1641 } 1642 int groupId = getVolumeGroupForStreamType(streamType); 1643 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP 1644 && sVolumeGroupStates.indexOfKey(groupId) >= 0) { 1645 streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId)); 1646 } 1647 } 1648 } 1649 } 1650 1651 /** 1652 * Called by handling of MSG_INIT_STREAMS_VOLUMES 1653 */ onInitStreamsAndVolumes()1654 private void onInitStreamsAndVolumes() { 1655 synchronized (this) { 1656 mCameraSoundForced.set(readCameraSoundForced()); 1657 sendMsg(mAudioHandler, 1658 MSG_SET_FORCE_USE, 1659 SENDMSG_QUEUE, 1660 AudioSystem.FOR_SYSTEM, 1661 mCameraSoundForced.get() 1662 ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 1663 new String("AudioService ctor"), 1664 0); 1665 } 1666 1667 createStreamStates(); 1668 1669 // must be called after createStreamStates() as it uses MUSIC volume as default if no 1670 // persistent data 1671 initVolumeGroupStates(); 1672 1673 mSoundDoseHelper.initSafeMediaVolumeIndex(); 1674 // Link VGS on VSS 1675 initVolumeStreamStates(); 1676 1677 // Call setRingerModeInt() to apply correct mute 1678 // state on streams affected by ringer mode. 1679 sRingerAndZenModeMutedStreams = 0; 1680 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 1681 sRingerAndZenModeMutedStreams, "onInitStreamsAndVolumes")); 1682 setRingerModeInt(getRingerModeInternal(), false); 1683 1684 if (!disablePrescaleAbsoluteVolume()) { 1685 final float[] preScale = new float[3]; 1686 preScale[0] = mContext.getResources().getFraction( 1687 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1, 1688 1, 1); 1689 preScale[1] = mContext.getResources().getFraction( 1690 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2, 1691 1, 1); 1692 preScale[2] = mContext.getResources().getFraction( 1693 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3, 1694 1, 1); 1695 for (int i = 0; i < preScale.length; i++) { 1696 if (0.0f <= preScale[i] && preScale[i] <= 1.0f) { 1697 mPrescaleAbsoluteVolume[i] = preScale[i]; 1698 } 1699 } 1700 } 1701 1702 initExternalEventReceivers(); 1703 1704 // check on volume initialization 1705 checkVolumeRangeInitialization("AudioService()"); 1706 1707 synchronized (mCachedAbsVolDrivingStreamsLock) { 1708 mCachedAbsVolDrivingStreams.forEach((dev, stream) -> { 1709 boolean enabled = true; 1710 if (dev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { 1711 enabled = mAvrcpAbsVolSupported; 1712 } 1713 final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", 1714 enabled, stream); 1715 if (result != AudioSystem.AUDIO_STATUS_OK) { 1716 sVolumeLogger.enqueueAndSlog( 1717 new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR, 1718 result, dev, enabled, stream).eventToString(), ALOGE, TAG); 1719 1720 } 1721 }); 1722 } 1723 } 1724 1725 /** Called by handling of MSG_INIT_INPUT_GAINS */ onInitInputGains()1726 private void onInitInputGains() { 1727 mInputDeviceVolumeHelper = 1728 new InputDeviceVolumeHelper( 1729 mSettings, 1730 mContentResolver, 1731 System.INPUT_GAIN_INDEX_SETTINGS); 1732 } 1733 1734 private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener = 1735 new SubscriptionManager.OnSubscriptionsChangedListener() { 1736 @Override 1737 public void onSubscriptionsChanged() { 1738 Log.i(TAG, "onSubscriptionsChanged()"); 1739 sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE, 1740 0, 0, null, 0); 1741 } 1742 }; 1743 getMediaSessionManager()1744 private MediaSessionManager getMediaSessionManager() { 1745 if (mMediaSessionManager == null) { 1746 mMediaSessionManager = (MediaSessionManager) mContext 1747 .getSystemService(Context.MEDIA_SESSION_SERVICE); 1748 } 1749 return mMediaSessionManager; 1750 } 1751 1752 /** 1753 * Initialize intent receives and settings observers for this service. 1754 * Must be called after createStreamStates() as the handling of some events 1755 * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED 1756 * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer) 1757 */ initExternalEventReceivers()1758 private void initExternalEventReceivers() { 1759 mSettingsObserver = new SettingsObserver(); 1760 1761 // Register for device connection intent broadcasts. 1762 IntentFilter intentFilter = 1763 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 1764 if (!mDeviceBroker.isScoManagedByAudio()) { 1765 intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED); 1766 } 1767 intentFilter.addAction(Intent.ACTION_DOCK_EVENT); 1768 if (mDisplayManager == null) { 1769 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 1770 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 1771 } 1772 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 1773 intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); 1774 intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); 1775 intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 1776 intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 1777 1778 intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 1779 if (mMonitorRotation) { 1780 RotationHelper.init(mContext, mAudioHandler, 1781 rotation -> onRotationUpdate(rotation), 1782 foldState -> onFoldStateUpdate(foldState)); 1783 } 1784 1785 intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); 1786 intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); 1787 intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE); 1788 intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 1789 1790 mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, 1791 mBroadcastHandlerThread.getThreadHandler(), 1792 Context.RECEIVER_EXPORTED); 1793 1794 SubscriptionManager subscriptionManager = mContext.getSystemService( 1795 SubscriptionManager.class); 1796 if (subscriptionManager == null) { 1797 Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!"); 1798 } else { 1799 subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener); 1800 } 1801 1802 if (mDisplayManager != null) { 1803 mDisplayManager.registerDisplayListener(mDisplayListener, mAudioHandler); 1804 } 1805 } 1806 systemReady()1807 public void systemReady() { 1808 sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 1809 0, 0, null, 0); 1810 if (false) { 1811 // This is turned off for now, because it is racy and thus causes apps to break. 1812 // Currently banning a uid means that if an app tries to start playing an audio 1813 // stream, that will be preventing, and unbanning it will not allow that stream 1814 // to resume. However these changes in uid state are racy with what the app is doing, 1815 // so that after taking a process out of the cached state we can't guarantee that 1816 // we will unban the uid before the app actually tries to start playing audio. 1817 // (To do that, the activity manager would need to wait until it knows for sure 1818 // that the ban has been removed, before telling the app to do whatever it is 1819 // supposed to do that caused it to go out of the cached state.) 1820 try { 1821 ActivityManager.getService().registerUidObserver(mUidObserver, 1822 ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE, 1823 ActivityManager.PROCESS_STATE_UNKNOWN, null); 1824 } catch (RemoteException e) { 1825 // ignored; both services live in system_server 1826 } 1827 } 1828 } 1829 updateVibratorInfos()1830 private void updateVibratorInfos() { 1831 VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class); 1832 if (vibratorManager == null) { 1833 Slog.e(TAG, "Vibrator manager is not found"); 1834 return; 1835 } 1836 int[] vibratorIds = vibratorManager.getVibratorIds(); 1837 if (vibratorIds.length == 0) { 1838 Slog.d(TAG, "No vibrator found"); 1839 return; 1840 } 1841 List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length); 1842 for (int id : vibratorIds) { 1843 Vibrator vibrator = vibratorManager.getVibrator(id); 1844 if (vibrator != null) { 1845 vibrators.add(vibrator); 1846 } else { 1847 Slog.w(TAG, "Vibrator(" + id + ") is not found"); 1848 } 1849 } 1850 if (vibrators.isEmpty()) { 1851 Slog.w(TAG, "Cannot find any available vibrator"); 1852 return; 1853 } 1854 AudioSystem.setVibratorInfos(vibrators); 1855 } 1856 onSystemReady()1857 public void onSystemReady() { 1858 mSystemReady = true; 1859 if (audioserverPermissions()) { 1860 setupPermissionListener(); 1861 } 1862 scheduleLoadSoundEffects(); 1863 mDeviceBroker.onSystemReady(); 1864 1865 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) { 1866 synchronized (mHdmiClientLock) { 1867 mHdmiManager = mContext.getSystemService(HdmiControlManager.class); 1868 if (mHdmiManager != null) { 1869 mHdmiManager.addHdmiControlStatusChangeListener( 1870 mHdmiControlStatusChangeListenerCallback); 1871 mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(), 1872 mMyHdmiCecVolumeControlFeatureListener); 1873 } 1874 mHdmiTvClient = mHdmiManager.getTvClient(); 1875 if (mHdmiTvClient != null) { 1876 mFixedVolumeDevices.removeAll( 1877 AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET); 1878 } 1879 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); 1880 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 1881 } 1882 } 1883 1884 if (mSupportsMicPrivacyToggle) { 1885 mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers( 1886 SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> { 1887 if (userId == getCurrentUserId()) { 1888 mMicMuteFromPrivacyToggle = enabled; 1889 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 1890 } 1891 }); 1892 } 1893 1894 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 1895 1896 mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG); 1897 1898 initA11yMonitoring(); 1899 1900 mRoleObserver = new RoleObserver(); 1901 mRoleObserver.register(); 1902 1903 onIndicateSystemReady(); 1904 1905 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 1906 setMicMuteFromSwitchInput(); 1907 1908 initMinStreamVolumeWithoutModifyAudioSettings(); 1909 1910 updateVibratorInfos(); 1911 1912 synchronized (mSupportedSystemUsagesLock) { 1913 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 1914 } 1915 } 1916 1917 //----------------------------------------------------------------- 1918 // routing monitoring from AudioSystemAdapter 1919 @Override onRoutingUpdatedFromNative()1920 public void onRoutingUpdatedFromNative() { 1921 sendMsg(mAudioHandler, 1922 MSG_ROUTING_UPDATED, 1923 SENDMSG_REPLACE, 0, 0, null, 1924 /*delay*/ 0); 1925 } 1926 1927 /** 1928 * called when handling MSG_ROUTING_UPDATED 1929 */ onRoutingUpdatedFromAudioThread()1930 void onRoutingUpdatedFromAudioThread() { 1931 if (mHasSpatializerEffect) { 1932 mSpatializerHelper.onRoutingUpdated(); 1933 } 1934 checkMuteAwaitConnection(); 1935 if (cacheGetStreamVolume()) { 1936 if (DEBUG_VOL) { 1937 Log.d(TAG, "Clear volume cache after routing update"); 1938 } 1939 AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API); 1940 } 1941 } 1942 1943 //----------------------------------------------------------------- 1944 // rotation/fold updates coming from RotationHelper onRotationUpdate(Integer rotation)1945 void onRotationUpdate(Integer rotation) { 1946 mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.)); 1947 // use REPLACE as only the last rotation matters 1948 final String rotationParameter = "rotation=" + rotation; 1949 sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1950 /*obj*/ rotationParameter, /*delay*/ 0); 1951 } 1952 onFoldStateUpdate(Boolean foldState)1953 void onFoldStateUpdate(Boolean foldState) { 1954 mSpatializerHelper.setFoldState(foldState); 1955 // use REPLACE as only the last fold state matters 1956 final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off"); 1957 sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, 1958 /*obj*/ foldStateParameter, /*delay*/ 0); 1959 } 1960 1961 //----------------------------------------------------------------- 1962 // Communicate to PlayackActivityMonitor whether to log or not 1963 // the sound FX activity (useful for removing touch sounds in the activity logs) ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1964 void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) { 1965 if (DEBUG_LOG_SOUND_FX) { 1966 return; 1967 } 1968 sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE, 1969 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(), 1970 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0); 1971 } 1972 1973 //----------------------------------------------------------------- 1974 // monitoring requests for volume range initialization 1975 @Override // AudioSystemAdapter.OnVolRangeInitRequestListener onVolumeRangeInitRequestFromNative()1976 public void onVolumeRangeInitRequestFromNative() { 1977 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0, 1978 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0); 1979 } 1980 1981 //----------------------------------------------------------------- 1982 RoleObserver mRoleObserver; 1983 1984 class RoleObserver implements OnRoleHoldersChangedListener { 1985 private RoleManager mRm; 1986 private final Executor mExecutor; 1987 RoleObserver()1988 RoleObserver() { 1989 mExecutor = mContext.getMainExecutor(); 1990 } 1991 register()1992 public void register() { 1993 mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE); 1994 if (mRm != null) { 1995 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL); 1996 synchronized (mSettingsLock) { 1997 updateAssistantUIdLocked(/* forceUpdate= */ true); 1998 } 1999 } 2000 } 2001 2002 @Override onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)2003 public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { 2004 if (RoleManager.ROLE_ASSISTANT.equals(roleName)) { 2005 synchronized (mSettingsLock) { 2006 updateAssistantUIdLocked(/* forceUpdate= */ false); 2007 } 2008 } 2009 } 2010 getAssistantRoleHolder()2011 public String getAssistantRoleHolder() { 2012 String assitantPackage = ""; 2013 if (mRm != null) { 2014 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT); 2015 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0); 2016 } 2017 return assitantPackage; 2018 } 2019 } 2020 onIndicateSystemReady()2021 void onIndicateSystemReady() { 2022 if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { 2023 return; 2024 } 2025 sendMsg(mAudioHandler, 2026 MSG_INDICATE_SYSTEM_READY, 2027 SENDMSG_REPLACE, 2028 0, 2029 0, 2030 null, 2031 INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 2032 } 2033 onAudioServerDied()2034 public void onAudioServerDied() { 2035 if (!mSystemReady || 2036 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { 2037 Log.e(TAG, "Audioserver died."); 2038 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 2039 "onAudioServerDied() audioserver died")); 2040 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, 2041 null, 500); 2042 return; 2043 } 2044 Log.i(TAG, "Audioserver started."); 2045 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 2046 "onAudioServerDied() audioserver started")); 2047 2048 updateAudioHalPids(); 2049 2050 // indicate to audio HAL that we start the reconfiguration phase after a media 2051 // server crash 2052 // Note that we only execute this when the media server 2053 // process restarts after a crash, not the first time it is started. 2054 AudioSystem.setParameters("restarting=true"); 2055 2056 readAndSetLowRamDevice(); 2057 2058 mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); 2059 2060 // Restore device connection states, BT state 2061 mDeviceBroker.onAudioServerDied(); 2062 2063 // Restore call state 2064 synchronized (mDeviceBroker.mSetModeLock) { 2065 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 2066 mContext.getPackageName(), true /*force*/, false /*signal*/); 2067 } 2068 2069 final int forSys = mCameraSoundForced.get() 2070 ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE; 2071 2072 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied"); 2073 2074 // Restore stream volumes 2075 onReinitVolumes("after audioserver restart"); 2076 2077 // Restore audio volume groups 2078 restoreVolumeGroups(); 2079 2080 // Restore mono mode 2081 updateMasterMono(mContentResolver); 2082 2083 // Restore audio balance 2084 updateMasterBalance(mContentResolver); 2085 2086 // Restore ringer mode 2087 setRingerModeInt(getRingerModeInternal(), false); 2088 2089 // Reset device rotation (if monitored for this device) 2090 if (mMonitorRotation) { 2091 RotationHelper.updateOrientation(); 2092 } 2093 2094 // Restore setParameters and other queued setters. 2095 mRestorableParameters.restoreAll(); 2096 2097 final int forDock = mDockAudioMediaEnabled ? 2098 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE; 2099 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied"); 2100 sendEncodedSurroundMode(mContentResolver, "onAudioServerDied"); 2101 sendEnabledSurroundFormats(mContentResolver, true); 2102 AudioSystem.setRttEnabled(mRttEnabled.get()); 2103 synchronized (mSettingsLock) { 2104 resetAssistantServicesUidsLocked(); 2105 } 2106 2107 synchronized (mAccessibilityServiceUidsLock) { 2108 AudioSystem.setA11yServicesUids(mAccessibilityServiceUids); 2109 } 2110 synchronized (mInputMethodServiceUidLock) { 2111 mAudioSystem.setCurrentImeUid(mInputMethodServiceUid); 2112 } 2113 synchronized (mHdmiClientLock) { 2114 if (mHdmiManager != null && mHdmiTvClient != null) { 2115 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); 2116 } 2117 } 2118 2119 synchronized (mSupportedSystemUsagesLock) { 2120 AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages); 2121 } 2122 2123 synchronized (mAudioPolicies) { 2124 ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>(); 2125 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 2126 final int status = policy.connectMixes(); 2127 if (status != AudioSystem.SUCCESS) { 2128 // note that PERMISSION_DENIED may also indicate trouble getting to APService 2129 Log.e(TAG, "onAudioServerDied: error " 2130 + AudioSystem.audioSystemErrorToString(status) 2131 + " when connecting mixes for policy " + policy.toLogFriendlyString()); 2132 invalidProxies.add(policy); 2133 } else { 2134 final int deviceAffinitiesStatus = policy.setupDeviceAffinities(); 2135 if (deviceAffinitiesStatus != AudioSystem.SUCCESS) { 2136 Log.e(TAG, "onAudioServerDied: error " 2137 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus) 2138 + " when connecting device affinities for policy " 2139 + policy.toLogFriendlyString()); 2140 invalidProxies.add(policy); 2141 } 2142 } 2143 } 2144 invalidProxies.forEach((policy) -> policy.release()); 2145 2146 } 2147 2148 // Restore capture policies 2149 synchronized (mPlaybackMonitor) { 2150 HashMap<Integer, Integer> allowedCapturePolicies = 2151 mPlaybackMonitor.getAllAllowedCapturePolicies(); 2152 for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) { 2153 int result = mAudioSystem.setAllowedCapturePolicy( 2154 entry.getKey(), 2155 AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0)); 2156 if (result != AudioSystem.AUDIO_STATUS_OK) { 2157 Log.e(TAG, "Failed to restore capture policy, uid: " 2158 + entry.getKey() + ", capture policy: " + entry.getValue() 2159 + ", result: " + result); 2160 // When restoring capture policy failed, set the capture policy as 2161 // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached 2162 // capture policy in PlaybackActivityMonitor. 2163 mPlaybackMonitor.setAllowedCapturePolicy( 2164 entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL); 2165 } 2166 } 2167 } 2168 2169 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 2170 2171 // Restore rotation information. 2172 if (mMonitorRotation) { 2173 RotationHelper.forceUpdate(); 2174 } 2175 2176 onIndicateSystemReady(); 2177 2178 // indicate the end of reconfiguration phase to audio HAL 2179 AudioSystem.setParameters("restarting=false"); 2180 2181 mSoundDoseHelper.reset(/*resetISoundDose=*/true); 2182 2183 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, 2184 SENDMSG_QUEUE, 1, 0, null, 0); 2185 2186 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache 2187 setMicMuteFromSwitchInput(); 2188 2189 // Restore vibrator info 2190 updateVibratorInfos(); 2191 } 2192 onRemoveAssistantServiceUids(int[] uids)2193 private void onRemoveAssistantServiceUids(int[] uids) { 2194 synchronized (mSettingsLock) { 2195 removeAssistantServiceUidsLocked(uids); 2196 } 2197 } 2198 2199 @GuardedBy("mSettingsLock") removeAssistantServiceUidsLocked(int[] uids)2200 private void removeAssistantServiceUidsLocked(int[] uids) { 2201 boolean changed = false; 2202 for (int index = 0; index < uids.length; index++) { 2203 if (!mAssistantUids.remove(uids[index])) { 2204 Slog.e(TAG, TextUtils.formatSimple( 2205 "Cannot remove assistant service, uid(%d) not present", uids[index])); 2206 continue; 2207 } 2208 changed = true; 2209 } 2210 if (changed) { 2211 updateAssistantServicesUidsLocked(); 2212 } 2213 } 2214 onAddAssistantServiceUids(int[] uids)2215 private void onAddAssistantServiceUids(int[] uids) { 2216 synchronized (mSettingsLock) { 2217 addAssistantServiceUidsLocked(uids); 2218 } 2219 } 2220 2221 @GuardedBy("mSettingsLock") addAssistantServiceUidsLocked(int[] uids)2222 private void addAssistantServiceUidsLocked(int[] uids) { 2223 boolean changed = false; 2224 for (int index = 0; index < uids.length; index++) { 2225 if (uids[index] == INVALID_UID) { 2226 continue; 2227 } 2228 if (!mAssistantUids.add(uids[index])) { 2229 Slog.e(TAG, TextUtils.formatSimple( 2230 "Cannot add assistant service, uid(%d) already present", 2231 uids[index])); 2232 continue; 2233 } 2234 changed = true; 2235 } 2236 if (changed) { 2237 updateAssistantServicesUidsLocked(); 2238 } 2239 } 2240 2241 @GuardedBy("mSettingsLock") resetAssistantServicesUidsLocked()2242 private void resetAssistantServicesUidsLocked() { 2243 mAssistantUids.clear(); 2244 updateAssistantUIdLocked(/* forceUpdate= */ true); 2245 } 2246 2247 @GuardedBy("mSettingsLock") updateAssistantServicesUidsLocked()2248 private void updateAssistantServicesUidsLocked() { 2249 int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 2250 AudioSystem.setAssistantServicesUids(assistantUids); 2251 } 2252 updateActiveAssistantServiceUids()2253 private void updateActiveAssistantServiceUids() { 2254 int [] activeAssistantServiceUids; 2255 synchronized (mSettingsLock) { 2256 activeAssistantServiceUids = mActiveAssistantServiceUids; 2257 } 2258 AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids); 2259 } 2260 onReinitVolumes(@onNull String caller)2261 private void onReinitVolumes(@NonNull String caller) { 2262 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 2263 // keep track of any error during stream volume initialization 2264 int status = AudioSystem.AUDIO_STATUS_OK; 2265 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 2266 VolumeStreamState streamState = getVssForStream(streamType); 2267 if (streamState == null) { 2268 continue; 2269 } 2270 final int res = AudioSystem.initStreamVolume( 2271 streamType, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType]); 2272 if (res != AudioSystem.AUDIO_STATUS_OK) { 2273 status = res; 2274 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType); 2275 // stream volume initialization failed, no need to try the others, it will be 2276 // attempted again when MSG_REINIT_VOLUMES is handled 2277 break; 2278 } 2279 streamState.applyAllVolumes(); 2280 } 2281 2282 // did it work? check based on status 2283 if (status != AudioSystem.AUDIO_STATUS_OK) { 2284 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 2285 caller + ": initStreamVolume failed with " + status + " will retry") 2286 .printLog(ALOGE, TAG)); 2287 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 2288 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 2289 return; 2290 } 2291 2292 synchronized (mCachedAbsVolDrivingStreamsLock) { 2293 mCachedAbsVolDrivingStreams.forEach((dev, stream) -> { 2294 boolean enabled = true; 2295 if (dev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { 2296 enabled = mAvrcpAbsVolSupported; 2297 } 2298 final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", 2299 enabled, stream); 2300 if (result != AudioSystem.AUDIO_STATUS_OK) { 2301 sVolumeLogger.enqueueAndSlog( 2302 new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR, 2303 result, dev, enabled, stream).eventToString(), ALOGE, TAG); 2304 } 2305 }); 2306 } 2307 2308 // did it work? check based on min/max values of some basic streams 2309 if (!checkVolumeRangeInitialization(caller)) { 2310 return; 2311 } 2312 2313 // success 2314 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 2315 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG)); 2316 } 2317 2318 /** 2319 * Check volume ranges were properly initialized 2320 * @return true if volume ranges were successfully initialized 2321 */ checkVolumeRangeInitialization(String caller)2322 private boolean checkVolumeRangeInitialization(String caller) { 2323 boolean success = true; 2324 final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING, 2325 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL, 2326 AudioSystem.STREAM_ACCESSIBILITY }; 2327 for (int streamType : basicStreams) { 2328 final AudioAttributes aa = new AudioAttributes.Builder() 2329 .setInternalLegacyStreamType(streamType).build(); 2330 if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0 2331 || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) { 2332 success = false; 2333 break; 2334 } 2335 } 2336 if (!success) { 2337 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 2338 caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry") 2339 .printLog(ALOGW, TAG)); 2340 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 2341 caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 2342 } 2343 return success; 2344 } 2345 onDispatchAudioServerStateChange(boolean state)2346 private void onDispatchAudioServerStateChange(boolean state) { 2347 synchronized (mAudioServerStateListeners) { 2348 for (AsdProxy asdp : mAudioServerStateListeners.values()) { 2349 try { 2350 asdp.callback().dispatchAudioServerStateChange(state); 2351 } catch (RemoteException e) { 2352 Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e); 2353 } 2354 } 2355 } 2356 } 2357 createAudioSystemThread()2358 private void createAudioSystemThread() { 2359 mAudioSystemThread = new AudioSystemThread(); 2360 mAudioSystemThread.start(); 2361 waitForAudioHandlerCreation(); 2362 } 2363 2364 /** Waits for the volume handler to be created by the other thread. */ waitForAudioHandlerCreation()2365 private void waitForAudioHandlerCreation() { 2366 synchronized(this) { 2367 while (mAudioHandler == null) { 2368 try { 2369 // Wait for mAudioHandler to be set by the other thread 2370 wait(); 2371 } catch (InterruptedException e) { 2372 Log.e(TAG, "Interrupted while waiting on volume handler."); 2373 } 2374 } 2375 } 2376 } 2377 2378 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 2379 /** 2380 * @see AudioManager#setSupportedSystemUsages(int[]) 2381 */ setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)2382 public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) { 2383 super.setSupportedSystemUsages_enforcePermission(); 2384 2385 verifySystemUsages(systemUsages); 2386 2387 synchronized (mSupportedSystemUsagesLock) { 2388 AudioSystem.setSupportedSystemUsages(systemUsages); 2389 mSupportedSystemUsages = systemUsages; 2390 } 2391 } 2392 2393 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 2394 /** 2395 * @see AudioManager#getSupportedSystemUsages() 2396 */ getSupportedSystemUsages()2397 public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() { 2398 super.getSupportedSystemUsages_enforcePermission(); 2399 2400 synchronized (mSupportedSystemUsagesLock) { 2401 return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length); 2402 } 2403 } 2404 verifySystemUsages(@onNull int[] systemUsages)2405 private void verifySystemUsages(@NonNull int[] systemUsages) { 2406 for (int i = 0; i < systemUsages.length; i++) { 2407 if (!AudioAttributes.isSystemUsage(systemUsages[i])) { 2408 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]); 2409 } 2410 } 2411 } 2412 2413 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 2414 /** 2415 * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the 2416 * platform configuration file. 2417 */ 2418 @NonNull getAudioProductStrategies()2419 public List<AudioProductStrategy> getAudioProductStrategies() { 2420 // verify permissions 2421 super.getAudioProductStrategies_enforcePermission(); 2422 2423 return AudioProductStrategy.getAudioProductStrategies(); 2424 } 2425 2426 @android.annotation.EnforcePermission(anyOf = { 2427 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) 2428 /** 2429 * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the 2430 * platform configuration file. 2431 */ 2432 @NonNull getAudioVolumeGroups()2433 public List<AudioVolumeGroup> getAudioVolumeGroups() { 2434 // verify permissions 2435 super.getAudioVolumeGroups_enforcePermission(); 2436 2437 return mAudioVolumeGroupHelper.getAudioVolumeGroups(); 2438 } 2439 checkAllAliasStreamVolumes()2440 private void checkAllAliasStreamVolumes() { 2441 synchronized (mSettingsLock) { 2442 synchronized (mVolumeStateLock) { 2443 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2444 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2445 int streamAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1); 2446 final VolumeStreamState streamState = getVssForStream(streamType); 2447 if (streamAlias != -1 && streamState != null) { 2448 streamState.setAllIndexes(getVssForStream(streamAlias), TAG); 2449 // apply stream volume 2450 if (!streamState.mIsMuted) { 2451 streamState.applyAllVolumes(); 2452 } 2453 } 2454 } 2455 } 2456 } 2457 } 2458 2459 2460 /** 2461 * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected. 2462 */ postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2463 /*package*/ void postCheckVolumeCecOnHdmiConnection( 2464 @AudioService.ConnectionState int state, String caller) { 2465 sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE, 2466 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/); 2467 } 2468 onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2469 private void onCheckVolumeCecOnHdmiConnection( 2470 @AudioService.ConnectionState int state, String caller) { 2471 if (state == AudioService.CONNECTION_STATE_CONNECTED) { 2472 // DEVICE_OUT_HDMI is now connected 2473 if (mSoundDoseHelper.safeDevicesContains(AudioSystem.DEVICE_OUT_HDMI)) { 2474 mSoundDoseHelper.scheduleMusicActiveCheck(); 2475 } 2476 2477 if (isPlatformTelevision()) { 2478 synchronized (mHdmiClientLock) { 2479 if (mHdmiManager != null && mHdmiPlaybackClient != null) { 2480 updateHdmiCecSinkLocked( 2481 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2482 } 2483 } 2484 } 2485 sendEnabledSurroundFormats(mContentResolver, true); 2486 } else { 2487 // DEVICE_OUT_HDMI disconnected 2488 if (isPlatformTelevision()) { 2489 synchronized (mHdmiClientLock) { 2490 if (mHdmiManager != null) { 2491 updateHdmiCecSinkLocked( 2492 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)); 2493 } 2494 } 2495 } 2496 } 2497 } 2498 2499 /** 2500 * Asynchronously update volume states for the given device. 2501 * 2502 * @param device a single audio device, ensure that this is not a devices bitmask 2503 * @param caller caller of this method 2504 */ postUpdateVolumeStatesForAudioDevice(int device, String caller)2505 private void postUpdateVolumeStatesForAudioDevice(int device, String caller) { 2506 sendMsg(mAudioHandler, 2507 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE, 2508 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/, 2509 0 /*delay*/); 2510 } 2511 2512 /** 2513 * Update volume states for the given device. 2514 * 2515 * This will initialize the volume index if no volume index is available. 2516 * If the device is the currently routed device, fixed/full volume policies will be applied. 2517 * 2518 * @param device a single audio device, ensure that this is not a devices bitmask 2519 * @param caller caller of this method 2520 */ onUpdateVolumeStatesForAudioDevice(int device, String caller)2521 private void onUpdateVolumeStatesForAudioDevice(int device, String caller) { 2522 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 2523 synchronized (mSettingsLock) { 2524 synchronized (mVolumeStateLock) { 2525 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2526 updateVolumeStates(device, streamType, caller); 2527 } 2528 } 2529 } 2530 } 2531 2532 /** 2533 * Update volume states for the given device and given stream. 2534 * 2535 * This will initialize the volume index if no volume index is available. 2536 * If the device is the currently routed device, fixed/full volume policies will be applied. 2537 * 2538 * @param device a single audio device, ensure that this is not a devices bitmask 2539 * @param streamType streamType to be updated 2540 * @param caller caller of this method 2541 */ updateVolumeStates(int device, int streamType, String caller)2542 private void updateVolumeStates(int device, int streamType, String caller) { 2543 if (replaceStreamBtSco() && streamType == AudioSystem.STREAM_BLUETOOTH_SCO) { 2544 return; 2545 } 2546 2547 // Handle device volume aliasing of SPEAKER_SAFE. 2548 if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) { 2549 device = AudioSystem.DEVICE_OUT_SPEAKER; 2550 } 2551 2552 final VolumeStreamState streamState = getVssForStream(streamType); 2553 if (streamState == null) { 2554 // nothing to update 2555 return; 2556 } 2557 2558 if (!streamState.hasIndexForDevice(device)) { 2559 // set the default value, if device is affected by a full/fix/abs volume rule, it 2560 // will taken into account in checkFixedVolumeDevices() 2561 streamState.setIndex(getVssForStreamOrDefault(sStreamVolumeAlias.get(streamType)) 2562 .getIndex(AudioSystem.DEVICE_OUT_DEFAULT), 2563 device, caller, true /*hasModifyAudioSettings*/); 2564 } 2565 2566 // Check if device to be updated is routed for the given audio stream 2567 // This may include devices such as SPEAKER_SAFE. 2568 List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt( 2569 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(), 2570 true /* forVolume */); 2571 for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) { 2572 if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType( 2573 device)) { 2574 streamState.checkFixedVolumeDevices(); 2575 2576 // Unmute streams if required and device is full volume 2577 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) { 2578 streamState.mute(false, "updateVolumeStates(" + caller); 2579 } 2580 } 2581 } 2582 } 2583 checkAllFixedVolumeDevices()2584 private void checkAllFixedVolumeDevices() 2585 { 2586 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2587 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2588 final VolumeStreamState vss = getVssForStream(streamType); 2589 if (vss != null) { 2590 vss.checkFixedVolumeDevices(); 2591 } 2592 } 2593 } 2594 checkAllFixedVolumeDevices(int streamType)2595 private void checkAllFixedVolumeDevices(int streamType) { 2596 final VolumeStreamState vss = getVssForStream(streamType); 2597 if (vss == null) { 2598 return; 2599 } 2600 vss.checkFixedVolumeDevices(); 2601 } 2602 checkMuteAffectedStreams()2603 private void checkMuteAffectedStreams() { 2604 // any stream with a min level > 0 is not muteable by definition 2605 // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications 2606 // that has the the MODIFY_PHONE_STATE permission. 2607 for (int i = 0; i < mStreamStates.size(); i++) { 2608 final VolumeStreamState vss = mStreamStates.valueAt(i); 2609 if (vss != null && vss.mIndexMin > 0 2610 && (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL 2611 && vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) { 2612 mMuteAffectedStreams &= ~(1 << vss.mStreamType); 2613 } 2614 } 2615 updateUserMutableStreams(); 2616 } 2617 createStreamStates()2618 private void createStreamStates() { 2619 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2620 mStreamStates = new SparseArray<>(numStreamTypes); 2621 2622 for (int i = 0; i < numStreamTypes; i++) { 2623 final int streamAlias = sStreamVolumeAlias.get(i, /*valueIfKeyNotFound=*/-1); 2624 // a negative sStreamVolumeAlias value means the stream state type is not supported 2625 if (streamAlias >= 0) { 2626 mStreamStates.set(i, 2627 new VolumeStreamState(System.VOLUME_SETTINGS_INT[streamAlias], i)); 2628 } 2629 } 2630 2631 checkAllFixedVolumeDevices(); 2632 checkAllAliasStreamVolumes(); 2633 checkMuteAffectedStreams(); 2634 updateDefaultVolumes(); 2635 } 2636 2637 /** 2638 * Update default indexes from aliased streams. Must be called after mStreamStates is created 2639 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default 2640 * index. Need to make default index configurable and independent of streams. 2641 * Fallback on music stream for default initialization to take benefit of property based default 2642 * initialization. 2643 * For other volume groups not linked to any streams, default music stream index is considered. 2644 */ updateDefaultVolumes()2645 private void updateDefaultVolumes() { 2646 for (int stream = 0; stream < mStreamStates.size(); stream++) { 2647 int streamType = mStreamStates.keyAt(stream); 2648 int streamVolumeAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1); 2649 if (mUseVolumeGroupAliases) { 2650 if (AudioSystem.DEFAULT_STREAM_VOLUME[streamType] != UNSET_INDEX) { 2651 // Already initialized through default property based mecanism. 2652 continue; 2653 } 2654 streamVolumeAlias = AudioSystem.STREAM_MUSIC; 2655 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, streamType); 2656 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[streamType]) 2657 && (defaultAliasVolume <= MAX_STREAM_VOLUME[streamType])) { 2658 AudioSystem.DEFAULT_STREAM_VOLUME[streamType] = defaultAliasVolume; 2659 continue; 2660 } 2661 } 2662 if (streamVolumeAlias >= 0 && streamType != streamVolumeAlias) { 2663 AudioSystem.DEFAULT_STREAM_VOLUME[streamType] = 2664 getUiDefaultRescaledIndex(streamVolumeAlias, streamType); 2665 } 2666 } 2667 } 2668 getUiDefaultRescaledIndex(int srcStream, int dstStream)2669 private int getUiDefaultRescaledIndex(int srcStream, int dstStream) { 2670 return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10, 2671 srcStream, dstStream) + 5) / 10; 2672 } 2673 replaceBtScoStreamWithVoiceCall(int streamType, String caller)2674 private static int replaceBtScoStreamWithVoiceCall(int streamType, String caller) { 2675 if (replaceStreamBtSco() && streamType == AudioSystem.STREAM_BLUETOOTH_SCO) { 2676 if (DEBUG_VOL) { 2677 Log.d(TAG, 2678 "Deprecating STREAM_BLUETOOTH_SCO, using STREAM_VOICE_CALL instead for " 2679 + "caller: " + caller); 2680 } 2681 streamType = AudioSystem.STREAM_VOICE_CALL; 2682 } 2683 return streamType; 2684 } 2685 isStreamBluetoothSco(int streamType)2686 private boolean isStreamBluetoothSco(int streamType) { 2687 if (replaceStreamBtSco()) { 2688 if (streamType == AudioSystem.STREAM_BLUETOOTH_SCO) { 2689 // this should not happen, throwing exception 2690 throw new IllegalArgumentException("STREAM_BLUETOOTH_SCO is deprecated"); 2691 } 2692 return streamType == AudioSystem.STREAM_VOICE_CALL 2693 && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO; 2694 } else { 2695 return streamType == AudioSystem.STREAM_BLUETOOTH_SCO; 2696 } 2697 } 2698 isStreamBluetoothComm(int streamType)2699 private boolean isStreamBluetoothComm(int streamType) { 2700 return (streamType == AudioSystem.STREAM_VOICE_CALL && mBtCommDeviceActive.get() != 0) 2701 || streamType == AudioSystem.STREAM_BLUETOOTH_SCO; 2702 } 2703 dumpStreamStates(PrintWriter pw)2704 private void dumpStreamStates(PrintWriter pw) { 2705 pw.println("\nStream volumes (device: index)"); 2706 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2707 for (int i = 0; i < numStreamTypes; i++) { 2708 if (replaceStreamBtSco() && i == AudioSystem.STREAM_BLUETOOTH_SCO) { 2709 continue; 2710 } 2711 StringBuilder alias = new StringBuilder(); 2712 final int streamAlias = sStreamVolumeAlias.get(i, /*valueIfKeyNotFound*/-1); 2713 if (streamAlias != i && streamAlias != -1) { 2714 alias.append(" (aliased to: ") 2715 .append(AudioSystem.STREAM_NAMES[streamAlias]) 2716 .append(")"); 2717 } 2718 pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":"); 2719 final VolumeStreamState vss = getVssForStream(i); 2720 if (vss != null) { 2721 vss.dump(pw); 2722 } 2723 pw.println(""); 2724 } 2725 pw.print("\n- mute affected streams = 0x"); 2726 pw.println(Integer.toHexString(mMuteAffectedStreams)); 2727 pw.print("\n- user mutable streams = 0x"); 2728 pw.println(Integer.toHexString(mUserMutableStreams)); 2729 } 2730 initStreamVolumeAlias(int[] streamVolumeAlias)2731 private void initStreamVolumeAlias(int[] streamVolumeAlias) { 2732 sStreamVolumeAlias = new SparseIntArray(streamVolumeAlias.length); 2733 for (int i = 0; i < streamVolumeAlias.length; ++i) { 2734 sStreamVolumeAlias.put(i, streamVolumeAlias[i]); 2735 } 2736 } 2737 updateStreamVolumeAlias(boolean updateVolumes, String caller)2738 private void updateStreamVolumeAlias(boolean updateVolumes, String caller) { 2739 int dtmfStreamAlias; 2740 final int a11yStreamAlias = sIndependentA11yVolume ? 2741 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC; 2742 final int assistantStreamAlias = mContext.getResources().getBoolean( 2743 com.android.internal.R.bool.config_useAssistantVolume) ? 2744 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC; 2745 2746 if (mIsSingleVolume) { 2747 initStreamVolumeAlias(STREAM_VOLUME_ALIAS_TELEVISION); 2748 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2749 } else if (mUseVolumeGroupAliases) { 2750 initStreamVolumeAlias(STREAM_VOLUME_ALIAS_NONE); 2751 dtmfStreamAlias = AudioSystem.STREAM_DTMF; 2752 } else { 2753 switch (mPlatformType) { 2754 case AudioSystem.PLATFORM_VOICE: 2755 initStreamVolumeAlias(STREAM_VOLUME_ALIAS_VOICE); 2756 dtmfStreamAlias = AudioSystem.STREAM_RING; 2757 break; 2758 default: 2759 initStreamVolumeAlias(STREAM_VOLUME_ALIAS_DEFAULT); 2760 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 2761 } 2762 if (!mNotifAliasRing) { 2763 sStreamVolumeAlias.put(AudioSystem.STREAM_NOTIFICATION, 2764 AudioSystem.STREAM_NOTIFICATION); 2765 } 2766 } 2767 2768 if (mIsSingleVolume) { 2769 mRingerModeAffectedStreams = 0; 2770 } else { 2771 if (isInCommunication()) { 2772 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL; 2773 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 2774 } else { 2775 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 2776 } 2777 } 2778 2779 sStreamVolumeAlias.put(AudioSystem.STREAM_DTMF, dtmfStreamAlias); 2780 sStreamVolumeAlias.put(AudioSystem.STREAM_ACCESSIBILITY, a11yStreamAlias); 2781 sStreamVolumeAlias.put(AudioSystem.STREAM_ASSISTANT, assistantStreamAlias); 2782 2783 if (replaceStreamBtSco()) { 2784 // we do not support STREAM_BLUETOOTH_SCO, this will lead to having 2785 // mStreanStates.get(STREAM_BLUETOOTH_SCO) == null 2786 sStreamVolumeAlias.delete(AudioSystem.STREAM_BLUETOOTH_SCO); 2787 } 2788 2789 if (updateVolumes && mStreamStates != null) { 2790 updateDefaultVolumes(); 2791 2792 synchronized (mSettingsLock) { 2793 synchronized (mVolumeStateLock) { 2794 getVssForStreamOrDefault(AudioSystem.STREAM_DTMF) 2795 .setAllIndexes(getVssForStreamOrDefault(dtmfStreamAlias), caller); 2796 getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY).setSettingName( 2797 System.VOLUME_SETTINGS_INT[a11yStreamAlias]); 2798 getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY).setAllIndexes( 2799 getVssForStreamOrDefault(a11yStreamAlias), caller); 2800 } 2801 } 2802 if (sIndependentA11yVolume) { 2803 // restore the a11y values from the settings 2804 getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY).readSettings(); 2805 } 2806 2807 // apply stream mute states according to new value of mRingerModeAffectedStreams 2808 setRingerModeInt(getRingerModeInternal(), false); 2809 sendMsg(mAudioHandler, 2810 MSG_SET_ALL_VOLUMES, 2811 SENDMSG_QUEUE, 2812 0, 2813 0, 2814 getVssForStreamOrDefault(AudioSystem.STREAM_DTMF), 0); 2815 sendMsg(mAudioHandler, 2816 MSG_SET_ALL_VOLUMES, 2817 SENDMSG_QUEUE, 2818 0, 2819 0, 2820 getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY), 0); 2821 } 2822 dispatchStreamAliasingUpdate(); 2823 } 2824 readDockAudioSettings(ContentResolver cr)2825 private void readDockAudioSettings(ContentResolver cr) 2826 { 2827 mDockAudioMediaEnabled = mSettings.getGlobalInt( 2828 cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1; 2829 2830 sendMsg(mAudioHandler, 2831 MSG_SET_FORCE_USE, 2832 SENDMSG_QUEUE, 2833 AudioSystem.FOR_DOCK, 2834 mDockAudioMediaEnabled ? 2835 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE, 2836 new String("readDockAudioSettings"), 2837 0); 2838 2839 } 2840 2841 updateMasterMono(ContentResolver cr)2842 private void updateMasterMono(ContentResolver cr) 2843 { 2844 final boolean masterMono = mSettings.getSystemIntForUser( 2845 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1; 2846 if (DEBUG_VOL) { 2847 Log.d(TAG, String.format("Master mono %b", masterMono)); 2848 } 2849 AudioSystem.setMasterMono(masterMono); 2850 } 2851 updateMasterBalance(ContentResolver cr)2852 private void updateMasterBalance(ContentResolver cr) { 2853 final float masterBalance = System.getFloatForUser( 2854 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT); 2855 if (DEBUG_VOL) { 2856 Log.d(TAG, String.format("Master balance %f", masterBalance)); 2857 } 2858 if (AudioSystem.setMasterBalance(masterBalance) != 0) { 2859 Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance)); 2860 } 2861 } 2862 sendEncodedSurroundMode(ContentResolver cr, String eventSource)2863 private void sendEncodedSurroundMode(ContentResolver cr, String eventSource) 2864 { 2865 final int encodedSurroundMode = mSettings.getGlobalInt( 2866 cr, Settings.Global.ENCODED_SURROUND_OUTPUT, 2867 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 2868 sendEncodedSurroundMode(encodedSurroundMode, eventSource); 2869 } 2870 sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2871 private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource) 2872 { 2873 // initialize to guaranteed bad value 2874 int forceSetting = AudioSystem.NUM_FORCE_CONFIG; 2875 switch (encodedSurroundMode) { 2876 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 2877 forceSetting = AudioSystem.FORCE_NONE; 2878 break; 2879 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 2880 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER; 2881 break; 2882 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 2883 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS; 2884 break; 2885 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 2886 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL; 2887 break; 2888 default: 2889 Log.e(TAG, "updateSurroundSoundSettings: illegal value " 2890 + encodedSurroundMode); 2891 break; 2892 } 2893 if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) { 2894 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting, 2895 eventSource); 2896 } 2897 } 2898 2899 @Override onUnhandledException(int code, int flags, Exception e)2900 protected void onUnhandledException(int code, int flags, Exception e) { 2901 Slog.wtf(TAG, "Uncaught exception in AudioService: " + code + ", " + flags, e); 2902 } 2903 2904 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2905 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2906 FileDescriptor err, String[] args, ShellCallback callback, 2907 ResultReceiver resultReceiver) { 2908 if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY) 2909 != PackageManager.PERMISSION_GRANTED) { 2910 throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission"); 2911 } 2912 new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err, 2913 args, callback, resultReceiver); 2914 } 2915 2916 @Override getNativeInterface()2917 public IAudioManagerNative getNativeInterface() { 2918 return mNativeShim; 2919 } 2920 2921 /** @see AudioManager#getSurroundFormats() */ 2922 @Override getSurroundFormats()2923 public Map<Integer, Boolean> getSurroundFormats() { 2924 Map<Integer, Boolean> surroundFormats = new HashMap<>(); 2925 int status = AudioSystem.getSurroundFormats(surroundFormats); 2926 if (status != AudioManager.SUCCESS) { 2927 // fail and bail! 2928 Log.e(TAG, "getSurroundFormats failed:" + status); 2929 return new HashMap<>(); // Always return a map. 2930 } 2931 return surroundFormats; 2932 } 2933 2934 /** @see AudioManager#getReportedSurroundFormats() */ 2935 @Override getReportedSurroundFormats()2936 public List<Integer> getReportedSurroundFormats() { 2937 ArrayList<Integer> reportedSurroundFormats = new ArrayList<>(); 2938 int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats); 2939 if (status != AudioManager.SUCCESS) { 2940 // fail and bail! 2941 Log.e(TAG, "getReportedSurroundFormats failed:" + status); 2942 return new ArrayList<>(); // Always return a list. 2943 } 2944 return reportedSurroundFormats; 2945 } 2946 2947 /** @see AudioManager#isSurroundFormatEnabled(int) */ 2948 @Override isSurroundFormatEnabled(int audioFormat)2949 public boolean isSurroundFormatEnabled(int audioFormat) { 2950 if (!isSurroundFormat(audioFormat)) { 2951 Log.w(TAG, "audioFormat to enable is not a surround format."); 2952 return false; 2953 } 2954 2955 final long token = Binder.clearCallingIdentity(); 2956 try { 2957 synchronized (mSettingsLock) { 2958 HashSet<Integer> enabledFormats = getEnabledFormats(); 2959 return enabledFormats.contains(audioFormat); 2960 } 2961 } finally { 2962 Binder.restoreCallingIdentity(token); 2963 } 2964 } 2965 2966 /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */ 2967 @Override setSurroundFormatEnabled(int audioFormat, boolean enabled)2968 public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) { 2969 if (!isSurroundFormat(audioFormat)) { 2970 Log.w(TAG, "audioFormat to enable is not a surround format."); 2971 return false; 2972 } 2973 if (mContext.checkCallingOrSelfPermission(WRITE_SETTINGS) 2974 != PackageManager.PERMISSION_GRANTED) { 2975 throw new SecurityException("Missing WRITE_SETTINGS permission"); 2976 } 2977 2978 HashSet<Integer> enabledFormats = getEnabledFormats(); 2979 if (enabled) { 2980 enabledFormats.add(audioFormat); 2981 } else { 2982 enabledFormats.remove(audioFormat); 2983 } 2984 final long token = Binder.clearCallingIdentity(); 2985 try { 2986 synchronized (mSettingsLock) { 2987 mSettings.putGlobalString(mContentResolver, 2988 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 2989 TextUtils.join(",", enabledFormats)); 2990 } 2991 } finally { 2992 Binder.restoreCallingIdentity(token); 2993 } 2994 return true; 2995 } 2996 2997 @android.annotation.EnforcePermission(WRITE_SETTINGS) 2998 /** @see AudioManager#setEncodedSurroundMode(int) */ 2999 @Override setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)3000 public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) { 3001 setEncodedSurroundMode_enforcePermission(); 3002 3003 final long token = Binder.clearCallingIdentity(); 3004 try { 3005 synchronized (mSettingsLock) { 3006 mSettings.putGlobalInt(mContentResolver, 3007 Settings.Global.ENCODED_SURROUND_OUTPUT, 3008 toEncodedSurroundSetting(mode)); 3009 } 3010 } finally { 3011 Binder.restoreCallingIdentity(token); 3012 } 3013 return true; 3014 } 3015 3016 /** @see AudioManager#getEncodedSurroundMode() */ 3017 @Override getEncodedSurroundMode(int targetSdkVersion)3018 public int getEncodedSurroundMode(int targetSdkVersion) { 3019 final long token = Binder.clearCallingIdentity(); 3020 try { 3021 synchronized (mSettingsLock) { 3022 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver, 3023 Settings.Global.ENCODED_SURROUND_OUTPUT, 3024 AudioManager.ENCODED_SURROUND_OUTPUT_AUTO); 3025 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion); 3026 } 3027 } finally { 3028 Binder.restoreCallingIdentity(token); 3029 } 3030 } 3031 3032 /** @return the formats that are enabled in global settings */ getEnabledFormats()3033 private HashSet<Integer> getEnabledFormats() { 3034 HashSet<Integer> formats = new HashSet<>(); 3035 String enabledFormats = mSettings.getGlobalString(mContentResolver, 3036 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 3037 if (enabledFormats != null) { 3038 try { 3039 Arrays.stream(TextUtils.split(enabledFormats, ",")) 3040 .mapToInt(Integer::parseInt) 3041 .forEach(formats::add); 3042 } catch (NumberFormatException e) { 3043 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e); 3044 } 3045 } 3046 return formats; 3047 } 3048 3049 @SuppressWarnings("AndroidFrameworkCompatChange") 3050 @AudioManager.EncodedSurroundOutputMode toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)3051 private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) { 3052 if (targetSdkVersion <= Build.VERSION_CODES.S 3053 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) { 3054 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 3055 } 3056 switch (encodedSurroundSetting) { 3057 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 3058 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO; 3059 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 3060 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER; 3061 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 3062 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS; 3063 case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL: 3064 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL; 3065 default: 3066 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN; 3067 } 3068 } 3069 toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)3070 private int toEncodedSurroundSetting( 3071 @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) { 3072 switch (encodedSurroundOutputMode) { 3073 case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER: 3074 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER; 3075 case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS: 3076 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS; 3077 case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL: 3078 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL; 3079 default: 3080 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO; 3081 } 3082 } 3083 isSurroundFormat(int audioFormat)3084 private boolean isSurroundFormat(int audioFormat) { 3085 for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) { 3086 if (sf == audioFormat) { 3087 return true; 3088 } 3089 } 3090 return false; 3091 } 3092 sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)3093 private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) { 3094 if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) { 3095 // Manually enable surround formats only when the setting is in manual mode. 3096 return; 3097 } 3098 String enabledSurroundFormats = mSettings.getGlobalString( 3099 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 3100 if (enabledSurroundFormats == null) { 3101 // Never allow enabledSurroundFormats as a null, which could happen when 3102 // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB. 3103 enabledSurroundFormats = ""; 3104 } 3105 if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) { 3106 // Update enabled surround formats to AudioPolicyManager only when forceUpdate 3107 // is true or enabled surround formats changed. 3108 return; 3109 } 3110 3111 mEnabledSurroundFormats = enabledSurroundFormats; 3112 String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ","); 3113 ArrayList<Integer> formats = new ArrayList<>(); 3114 for (String format : surroundFormats) { 3115 try { 3116 int audioFormat = Integer.valueOf(format); 3117 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) { 3118 formats.add(audioFormat); 3119 } 3120 } catch (Exception e) { 3121 Log.e(TAG, "Invalid enabled surround format:" + format); 3122 } 3123 } 3124 // Set filtered surround formats to settings DB in case 3125 // there are invalid surround formats in original settings. 3126 mSettings.putGlobalString(mContext.getContentResolver(), 3127 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS, 3128 TextUtils.join(",", formats)); 3129 sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0); 3130 } 3131 onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)3132 private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) { 3133 // Set surround format enabled accordingly. 3134 for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) { 3135 boolean enabled = enabledSurroundFormats.contains(surroundFormat); 3136 int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled); 3137 Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret); 3138 } 3139 } 3140 3141 @GuardedBy("mSettingsLock") updateAssistantUIdLocked(boolean forceUpdate)3142 private void updateAssistantUIdLocked(boolean forceUpdate) { 3143 int assistantUid = INVALID_UID; 3144 // Consider assistants in the following order of priority: 3145 // 1) apk in assistant role 3146 // 2) voice interaction service 3147 // 3) assistant service 3148 3149 String packageName = ""; 3150 if (mRoleObserver != null) { 3151 packageName = mRoleObserver.getAssistantRoleHolder(); 3152 } 3153 if (TextUtils.isEmpty(packageName)) { 3154 String assistantName = mSettings.getSecureStringForUser( 3155 mContentResolver, 3156 Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT); 3157 if (TextUtils.isEmpty(assistantName)) { 3158 assistantName = mSettings.getSecureStringForUser( 3159 mContentResolver, 3160 Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT); 3161 } 3162 if (!TextUtils.isEmpty(assistantName)) { 3163 ComponentName componentName = ComponentName.unflattenFromString(assistantName); 3164 if (componentName == null) { 3165 Slog.w(TAG, "Invalid service name for " 3166 + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName); 3167 return; 3168 } 3169 packageName = componentName.getPackageName(); 3170 } 3171 } 3172 if (!TextUtils.isEmpty(packageName)) { 3173 PackageManager pm = mContext.getPackageManager(); 3174 3175 if (pm.checkPermission(CAPTURE_AUDIO_HOTWORD, packageName) 3176 == PackageManager.PERMISSION_GRANTED) { 3177 try { 3178 assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId()); 3179 } catch (PackageManager.NameNotFoundException e) { 3180 Log.e(TAG, 3181 "updateAssistantUId() could not find UID for package: " + packageName); 3182 } 3183 } 3184 } 3185 if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) { 3186 mAssistantUids.remove(mPrimaryAssistantUid); 3187 mPrimaryAssistantUid = assistantUid; 3188 addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid}); 3189 } 3190 } 3191 readPersistedSettings()3192 private void readPersistedSettings() { 3193 if (!mSystemServer.isPrivileged()) { 3194 return; 3195 } 3196 final ContentResolver cr = mContentResolver; 3197 3198 int ringerModeFromSettings = 3199 mSettings.getGlobalInt( 3200 cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); 3201 int ringerMode = ringerModeFromSettings; 3202 // validity check in case the settings are restored from a device with incompatible 3203 // ringer modes 3204 if (!isValidRingerMode(ringerMode)) { 3205 ringerMode = AudioManager.RINGER_MODE_NORMAL; 3206 } 3207 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 3208 ringerMode = AudioManager.RINGER_MODE_SILENT; 3209 } 3210 if (ringerMode != ringerModeFromSettings) { 3211 mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode); 3212 } 3213 if (mUseFixedVolume || mIsSingleVolume) { 3214 ringerMode = AudioManager.RINGER_MODE_NORMAL; 3215 } 3216 synchronized(mSettingsLock) { 3217 mRingerMode = ringerMode; 3218 if (mRingerModeExternal == -1) { 3219 mRingerModeExternal = mRingerMode; 3220 } 3221 3222 // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting 3223 // are still needed while setVibrateSetting() and getVibrateSetting() are being 3224 // deprecated. 3225 mVibrateSetting = AudioSystem.getValueForVibrateSetting(0, 3226 AudioManager.VIBRATE_TYPE_NOTIFICATION, 3227 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 3228 : AudioManager.VIBRATE_SETTING_OFF); 3229 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, 3230 AudioManager.VIBRATE_TYPE_RINGER, 3231 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 3232 : AudioManager.VIBRATE_SETTING_OFF); 3233 3234 updateRingerAndZenModeAffectedStreams(); 3235 readDockAudioSettings(cr); 3236 sendEncodedSurroundMode(cr, "readPersistedSettings"); 3237 sendEnabledSurroundFormats(cr, true); 3238 updateAssistantUIdLocked(/* forceUpdate= */ true); 3239 resetActiveAssistantUidsLocked(); 3240 } 3241 3242 AudioSystem.setRttEnabled(mRttEnabled.get()); 3243 3244 mMuteAffectedStreams = mSettings.getSystemIntForUser(cr, 3245 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, 3246 UserHandle.USER_CURRENT); 3247 updateUserMutableStreams(); 3248 3249 updateMasterMono(cr); 3250 3251 updateMasterBalance(cr); 3252 3253 // Each stream will read its own persisted settings 3254 3255 // Broadcast the sticky intents 3256 synchronized (mSettingsLock) { 3257 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal); 3258 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode); 3259 } 3260 3261 // Broadcast vibrate settings 3262 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); 3263 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION); 3264 3265 // Load settings for the volume controller 3266 mVolumeController.loadSettings(cr); 3267 } 3268 updateUserMutableStreams()3269 private void updateUserMutableStreams() { 3270 mUserMutableStreams = mMuteAffectedStreams; 3271 mUserMutableStreams &= ~(1 << AudioSystem.STREAM_VOICE_CALL); 3272 mUserMutableStreams &= ~(1 << AudioSystem.STREAM_BLUETOOTH_SCO); 3273 } 3274 3275 @GuardedBy("mSettingsLock") resetActiveAssistantUidsLocked()3276 private void resetActiveAssistantUidsLocked() { 3277 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 3278 updateActiveAssistantServiceUids(); 3279 } 3280 readUserRestrictions()3281 private void readUserRestrictions() { 3282 if (!mSystemServer.isPrivileged()) { 3283 return; 3284 } 3285 final int currentUser = getCurrentUserId(); 3286 3287 if (mUseFixedVolume) { 3288 AudioSystem.setMasterVolume(1.0f); 3289 } 3290 3291 // Check the current user restriction. 3292 boolean masterMute = 3293 mUserManagerInternal.getUserRestriction(currentUser, 3294 UserManager.DISALLOW_UNMUTE_DEVICE) 3295 || mUserManagerInternal.getUserRestriction(currentUser, 3296 UserManager.DISALLOW_ADJUST_VOLUME); 3297 setMasterMuteInternalNoCallerCheck( 3298 masterMute, /* flags =*/ 0, currentUser, "readUserRestrictions"); 3299 3300 mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction( 3301 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE); 3302 if (DEBUG_VOL) { 3303 Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions, 3304 currentUser)); 3305 } 3306 setMicrophoneMuteNoCallerCheck(currentUser); 3307 } 3308 getIndexRange(int streamType)3309 private int getIndexRange(int streamType) { 3310 return (getVssForStreamOrDefault(streamType).getMaxIndex() - getVssForStreamOrDefault( 3311 streamType).getMinIndex()); 3312 } 3313 rescaleIndex(VolumeInfo volumeInfo, int dstStream)3314 private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) { 3315 if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET 3316 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 3317 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 3318 Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range"); 3319 return getVssForStreamOrDefault(dstStream).getMinIndex(); 3320 } 3321 return rescaleIndex(volumeInfo.getVolumeIndex(), 3322 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(), 3323 getVssForStreamOrDefault(dstStream).getMinIndex(), 3324 getVssForStreamOrDefault(dstStream).getMaxIndex()); 3325 } 3326 rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)3327 private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) { 3328 int dstMin = dstVolumeInfo.getMinVolumeIndex(); 3329 int dstMax = dstVolumeInfo.getMaxVolumeIndex(); 3330 // Don't rescale index if the VolumeInfo is missing a min or max index 3331 if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) { 3332 return index; 3333 } 3334 return rescaleIndex(index, 3335 getVssForStreamOrDefault(srcStream).getMinIndex(), 3336 getVssForStreamOrDefault(srcStream).getMaxIndex(), 3337 dstMin, dstMax); 3338 } 3339 rescaleIndex(int index, int srcStream, int dstStream)3340 private int rescaleIndex(int index, int srcStream, int dstStream) { 3341 final VolumeStreamState srcVss = getVssForStreamOrDefault(srcStream); 3342 final VolumeStreamState dstVss = getVssForStreamOrDefault(dstStream); 3343 int newIndex = rescaleIndex(index, srcVss.getMinIndex(), srcVss.getMaxIndex(), 3344 dstVss.getMinIndex(), dstVss.getMaxIndex()); 3345 // only apply solution for DTMF stream to make sure that it is not muted when 3346 // re-aliasing to voice call stream. With ringMyCar flag enabled this will be 3347 // automatically solved since we are sending the mute state to APM 3348 // TODO(b/402542630): revisit stream aliasing logic with different min index 3349 // values / mute states 3350 if (!ringMyCar() && dstStream == AudioSystem.STREAM_DTMF 3351 && srcStream == AudioSystem.STREAM_VOICE_CALL 3352 && srcVss.getMinIndex() > dstVss.getMinIndex()) { 3353 newIndex += srcVss.getMinIndex() - dstVss.getMinIndex(); 3354 if (newIndex > dstVss.getMaxIndex()) { 3355 newIndex = dstVss.getMaxIndex(); 3356 } 3357 } 3358 3359 return newIndex; 3360 } 3361 rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)3362 private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) { 3363 int srcRange = srcMax - srcMin; 3364 int dstRange = dstMax - dstMin; 3365 if (srcRange == 0) { 3366 Log.e(TAG, "rescaleIndex : index range should not be zero"); 3367 return dstMin; 3368 } 3369 return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange; 3370 } 3371 rescaleStep(int step, int srcStream, int dstStream)3372 private int rescaleStep(int step, int srcStream, int dstStream) { 3373 int srcRange = getIndexRange(srcStream); 3374 int dstRange = getIndexRange(dstStream); 3375 if (srcRange == 0) { 3376 Log.e(TAG, "rescaleStep : index range should not be zero"); 3377 return 0; 3378 } 3379 3380 return (step * dstRange + srcRange / 2) / srcRange; 3381 } 3382 3383 /////////////////////////////////////////////////////////////////////////// 3384 // IPC methods 3385 /////////////////////////////////////////////////////////////////////////// 3386 /** 3387 * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes) 3388 * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy, 3389 * List<AudioDeviceAttributes>) 3390 */ 3391 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)3392 public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) { 3393 super.setPreferredDevicesForStrategy_enforcePermission(); 3394 if (devices == null) { 3395 return AudioSystem.ERROR; 3396 } 3397 3398 devices = retrieveBluetoothAddresses(devices); 3399 3400 final String logString = String.format( 3401 "setPreferredDevicesForStrategy u/pid:%d/%d strat:%d dev:%s", 3402 Binder.getCallingUid(), Binder.getCallingPid(), strategy, 3403 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 3404 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3405 if (devices.stream().anyMatch(device -> 3406 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) { 3407 Log.e(TAG, "Unsupported input routing in " + logString); 3408 return AudioSystem.ERROR; 3409 } 3410 3411 final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices); 3412 if (status != AudioSystem.SUCCESS) { 3413 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3414 } 3415 3416 return status; 3417 } 3418 3419 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 3420 /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */ removePreferredDevicesForStrategy(int strategy)3421 public int removePreferredDevicesForStrategy(int strategy) { 3422 super.removePreferredDevicesForStrategy_enforcePermission(); 3423 3424 final String logString = 3425 String.format("removePreferredDevicesForStrategy strat:%d", strategy); 3426 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3427 3428 final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy); 3429 if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) { 3430 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3431 } 3432 return status; 3433 } 3434 3435 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 3436 /** 3437 * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy) 3438 * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy) 3439 */ getPreferredDevicesForStrategy(int strategy)3440 public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) { 3441 super.getPreferredDevicesForStrategy_enforcePermission(); 3442 3443 List<AudioDeviceAttributes> devices = new ArrayList<>(); 3444 int status = AudioSystem.SUCCESS; 3445 final long identity = Binder.clearCallingIdentity(); 3446 try { 3447 status = AudioSystem.getDevicesForRoleAndStrategy( 3448 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 3449 } finally { 3450 Binder.restoreCallingIdentity(identity); 3451 } 3452 if (status != AudioSystem.SUCCESS) { 3453 Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)", 3454 status, strategy)); 3455 return new ArrayList<AudioDeviceAttributes>(); 3456 } else { 3457 return anonymizeAudioDeviceAttributesList(devices); 3458 } 3459 } 3460 3461 /** 3462 * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy, 3463 * AudioDeviceAttributes) 3464 * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy, 3465 * List<AudioDeviceAttributes>) 3466 */ 3467 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) setDeviceAsNonDefaultForStrategy(int strategy, @NonNull AudioDeviceAttributes device)3468 public int setDeviceAsNonDefaultForStrategy(int strategy, 3469 @NonNull AudioDeviceAttributes device) { 3470 super.setDeviceAsNonDefaultForStrategy_enforcePermission(); 3471 Objects.requireNonNull(device); 3472 3473 device = retrieveBluetoothAddress(device); 3474 3475 final String logString = String.format( 3476 "setDeviceAsNonDefaultForStrategy u/pid:%d/%d strat:%d dev:%s", 3477 Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString()); 3478 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3479 if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) { 3480 Log.e(TAG, "Unsupported input routing in " + logString); 3481 return AudioSystem.ERROR; 3482 } 3483 3484 final int status = mDeviceBroker.setDeviceAsNonDefaultForStrategySync(strategy, device); 3485 if (status != AudioSystem.SUCCESS) { 3486 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3487 } 3488 3489 return status; 3490 } 3491 3492 /** 3493 * @see AudioManager#removeDeviceAsNonDefaultForStrategy(AudioProductStrategy, 3494 * AudioDeviceAttributes) 3495 */ 3496 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) removeDeviceAsNonDefaultForStrategy(int strategy, AudioDeviceAttributes device)3497 public int removeDeviceAsNonDefaultForStrategy(int strategy, 3498 AudioDeviceAttributes device) { 3499 super.removeDeviceAsNonDefaultForStrategy_enforcePermission(); 3500 Objects.requireNonNull(device); 3501 3502 device = retrieveBluetoothAddress(device); 3503 3504 final String logString = String.format( 3505 "removeDeviceAsNonDefaultForStrategy strat:%d dev:%s", strategy, device.toString()); 3506 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3507 if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) { 3508 Log.e(TAG, "Unsupported input routing in " + logString); 3509 return AudioSystem.ERROR; 3510 } 3511 3512 final int status = mDeviceBroker.removeDeviceAsNonDefaultForStrategySync(strategy, device); 3513 if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) { 3514 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3515 } 3516 return status; 3517 } 3518 3519 /** 3520 * @see AudioManager#getNonDefaultDevicesForStrategy(AudioProductStrategy) 3521 */ 3522 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) getNonDefaultDevicesForStrategy(int strategy)3523 public List<AudioDeviceAttributes> getNonDefaultDevicesForStrategy(int strategy) { 3524 super.getNonDefaultDevicesForStrategy_enforcePermission(); 3525 List<AudioDeviceAttributes> devices = new ArrayList<>(); 3526 int status = AudioSystem.ERROR; 3527 3528 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 3529 status = AudioSystem.getDevicesForRoleAndStrategy( 3530 strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices); 3531 } 3532 3533 if (status != AudioSystem.SUCCESS) { 3534 Log.e(TAG, String.format("Error %d in getNonDefaultDeviceForStrategy(%d)", 3535 status, strategy)); 3536 return new ArrayList<AudioDeviceAttributes>(); 3537 } else { 3538 return anonymizeAudioDeviceAttributesList(devices); 3539 } 3540 } 3541 3542 /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener( 3543 * Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener) 3544 */ registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3545 public void registerStrategyPreferredDevicesDispatcher( 3546 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 3547 if (dispatcher == null) { 3548 return; 3549 } 3550 enforceModifyAudioRoutingPermission(); 3551 mDeviceBroker.registerStrategyPreferredDevicesDispatcher( 3552 dispatcher, isBluetoothPrividged()); 3553 } 3554 3555 /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener( 3556 * AudioManager.OnPreferredDevicesForStrategyChangedListener) 3557 */ unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3558 public void unregisterStrategyPreferredDevicesDispatcher( 3559 @Nullable IStrategyPreferredDevicesDispatcher dispatcher) { 3560 if (dispatcher == null) { 3561 return; 3562 } 3563 enforceModifyAudioRoutingPermission(); 3564 mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher); 3565 } 3566 3567 /** @see AudioManager#addOnNonDefaultDevicesForStrategyChangedListener( 3568 * Executor, AudioManager.OnNonDefaultDevicesForStrategyChangedListener) 3569 */ registerStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3570 public void registerStrategyNonDefaultDevicesDispatcher( 3571 @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) { 3572 if (dispatcher == null) { 3573 return; 3574 } 3575 enforceModifyAudioRoutingPermission(); 3576 mDeviceBroker.registerStrategyNonDefaultDevicesDispatcher( 3577 dispatcher, isBluetoothPrividged()); 3578 } 3579 3580 /** @see AudioManager#removeOnNonDefaultDevicesForStrategyChangedListener( 3581 * AudioManager.OnNonDefaultDevicesForStrategyChangedListener) 3582 */ unregisterStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3583 public void unregisterStrategyNonDefaultDevicesDispatcher( 3584 @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) { 3585 if (dispatcher == null) { 3586 return; 3587 } 3588 enforceModifyAudioRoutingPermission(); 3589 mDeviceBroker.unregisterStrategyNonDefaultDevicesDispatcher(dispatcher); 3590 } 3591 3592 /** 3593 * @see AudioManager#setPreferredDevicesForCapturePreset(int, AudioDeviceAttributes) 3594 */ setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)3595 public int setPreferredDevicesForCapturePreset( 3596 int capturePreset, List<AudioDeviceAttributes> devices) { 3597 if (devices == null) { 3598 return AudioSystem.ERROR; 3599 } 3600 enforceModifyAudioRoutingPermission(); 3601 final String logString = String.format( 3602 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s", 3603 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset, 3604 devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); 3605 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3606 if (devices.stream().anyMatch(device -> 3607 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) { 3608 Log.e(TAG, "Unsupported output routing in " + logString); 3609 return AudioSystem.ERROR; 3610 } 3611 3612 devices = retrieveBluetoothAddresses(devices); 3613 3614 final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync( 3615 capturePreset, devices); 3616 if (status != AudioSystem.SUCCESS) { 3617 Log.e(TAG, String.format("Error %d in %s)", status, logString)); 3618 } 3619 3620 return status; 3621 } 3622 3623 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 3624 /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */ clearPreferredDevicesForCapturePreset(int capturePreset)3625 public int clearPreferredDevicesForCapturePreset(int capturePreset) { 3626 super.clearPreferredDevicesForCapturePreset_enforcePermission(); 3627 3628 final String logString = String.format( 3629 "removePreferredDeviceForCapturePreset source:%d", capturePreset); 3630 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 3631 3632 final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset); 3633 if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) { 3634 Log.e(TAG, String.format("Error %d in %s", status, logString)); 3635 } 3636 return status; 3637 } 3638 3639 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 3640 /** 3641 * @see AudioManager#getPreferredDevicesForCapturePreset(int) 3642 */ getPreferredDevicesForCapturePreset(int capturePreset)3643 public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) { 3644 super.getPreferredDevicesForCapturePreset_enforcePermission(); 3645 3646 List<AudioDeviceAttributes> devices = new ArrayList<>(); 3647 int status = AudioSystem.SUCCESS; 3648 final long identity = Binder.clearCallingIdentity(); 3649 try { 3650 status = AudioSystem.getDevicesForRoleAndCapturePreset( 3651 capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); 3652 } finally { 3653 Binder.restoreCallingIdentity(identity); 3654 } 3655 if (status != AudioSystem.SUCCESS) { 3656 Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)", 3657 status, capturePreset)); 3658 return new ArrayList<AudioDeviceAttributes>(); 3659 } else { 3660 return anonymizeAudioDeviceAttributesList(devices); 3661 } 3662 } 3663 3664 /** 3665 * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener( 3666 * Executor, OnPreferredDevicesForCapturePresetChangedListener) 3667 */ registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3668 public void registerCapturePresetDevicesRoleDispatcher( 3669 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 3670 if (dispatcher == null) { 3671 return; 3672 } 3673 enforceModifyAudioRoutingPermission(); 3674 mDeviceBroker.registerCapturePresetDevicesRoleDispatcher( 3675 dispatcher, isBluetoothPrividged()); 3676 } 3677 3678 /** 3679 * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener( 3680 * AudioManager.OnPreferredDevicesForCapturePresetChangedListener) 3681 */ unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3682 public void unregisterCapturePresetDevicesRoleDispatcher( 3683 @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { 3684 if (dispatcher == null) { 3685 return; 3686 } 3687 enforceModifyAudioRoutingPermission(); 3688 mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher); 3689 } 3690 3691 /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */ getDevicesForAttributes( @onNull AudioAttributes attributes)3692 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( 3693 @NonNull AudioAttributes attributes) { 3694 enforceQueryStateOrModifyRoutingPermission(); 3695 3696 return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList( 3697 getDevicesForAttributesInt(attributes, false /* forVolume */))); 3698 } 3699 3700 /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes) 3701 * This method is similar with AudioService#getDevicesForAttributes, 3702 * only it doesn't enforce permissions because it is used by an unprivileged public API 3703 * instead of the system API. 3704 */ getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3705 public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected( 3706 @NonNull AudioAttributes attributes) { 3707 return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList( 3708 getDevicesForAttributesInt(attributes, false /* forVolume */))); 3709 } 3710 3711 /** 3712 * @see AudioManager#isMusicActive() 3713 * @param remotely true if query is for remote playback (cast), false for local playback. 3714 */ isMusicActive(boolean remotely)3715 public boolean isMusicActive(boolean remotely) { 3716 // no permission required 3717 final long token = Binder.clearCallingIdentity(); 3718 try { 3719 if (remotely) { 3720 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0); 3721 } else { 3722 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0); 3723 } 3724 } finally { 3725 Binder.restoreCallingIdentity(token); 3726 } 3727 } 3728 getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3729 protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt( 3730 @NonNull AudioAttributes attributes, boolean forVolume) { 3731 Objects.requireNonNull(attributes); 3732 return mAudioSystem.getDevicesForAttributes(attributes, forVolume); 3733 } 3734 3735 /** 3736 * @see AudioManager#addOnDevicesForAttributesChangedListener( 3737 * AudioAttributes, Executor, OnDevicesForAttributesChangedListener) 3738 */ 3739 @android.annotation.EnforcePermission(anyOf = { MODIFY_AUDIO_ROUTING, QUERY_AUDIO_STATE }) addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback)3740 public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes, 3741 IDevicesForAttributesCallback callback) { 3742 super.addOnDevicesForAttributesChangedListener_enforcePermission(); 3743 mAudioSystem.addOnDevicesForAttributesChangedListener( 3744 attributes, false /* forVolume */, callback); 3745 } 3746 3747 /** 3748 * @see AudioManager#removeOnDevicesForAttributesChangedListener( 3749 * OnDevicesForAttributesChangedListener) 3750 */ removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback)3751 public void removeOnDevicesForAttributesChangedListener( 3752 IDevicesForAttributesCallback callback) { 3753 mAudioSystem.removeOnDevicesForAttributesChangedListener(callback); 3754 } 3755 3756 // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, 3757 // KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3758 public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv, 3759 @NonNull String callingPackage, @NonNull String caller) { 3760 int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL; 3761 if (isOnTv) { 3762 if (event.getAction() == KeyEvent.ACTION_DOWN) { 3763 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START; 3764 } else { // may catch more than ACTION_UP, but will end vol adjustement 3765 // the vol key is either released (ACTION_UP), or multiple keys are pressed 3766 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end 3767 // the repeated volume adjustement 3768 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END; 3769 } 3770 } else if (event.getAction() != KeyEvent.ACTION_DOWN) { 3771 return; 3772 } 3773 3774 int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND 3775 | AudioManager.FLAG_FROM_KEY; 3776 3777 switch (event.getKeyCode()) { 3778 case KeyEvent.KEYCODE_VOLUME_UP: 3779 adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 3780 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3781 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3782 break; 3783 case KeyEvent.KEYCODE_VOLUME_DOWN: 3784 adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, 3785 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3786 Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode); 3787 break; 3788 case KeyEvent.KEYCODE_VOLUME_MUTE: 3789 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 3790 adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE, 3791 AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller, 3792 Binder.getCallingUid(), Binder.getCallingPid(), 3793 true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3794 } 3795 break; 3796 default: 3797 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage); 3798 return; // not needed but added if code gets added below this switch statement 3799 } 3800 } 3801 setNavigationRepeatSoundEffectsEnabled(boolean enabled)3802 public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) { 3803 mNavigationRepeatSoundEffectsEnabled = enabled; 3804 } 3805 3806 /** 3807 * @return true if the fast scroll sound effects are enabled 3808 */ areNavigationRepeatSoundEffectsEnabled()3809 public boolean areNavigationRepeatSoundEffectsEnabled() { 3810 return mNavigationRepeatSoundEffectsEnabled; 3811 } 3812 setHomeSoundEffectEnabled(boolean enabled)3813 public void setHomeSoundEffectEnabled(boolean enabled) { 3814 mHomeSoundEffectEnabled = enabled; 3815 } 3816 3817 /** 3818 * @return true if the home sound effect is enabled 3819 */ isHomeSoundEffectEnabled()3820 public boolean isHomeSoundEffectEnabled() { 3821 return mHomeSoundEffectEnabled; 3822 } 3823 3824 /** All callers come from platform apps/system server, so no attribution tag is needed */ adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, int keyEventMode)3825 private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 3826 String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, 3827 int keyEventMode) { 3828 if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType 3829 + ", flags=" + flags + ", caller=" + caller 3830 + ", volControlStream=" + mVolumeControlStream 3831 + ", userSelect=" + mUserSelectedVolumeControlStream); 3832 if (direction != AudioManager.ADJUST_SAME) { 3833 sVolumeLogger.enqueue( 3834 new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType, 3835 direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage) 3836 .append("/").append(caller).append(" uid:").append(uid).toString())); 3837 } 3838 3839 boolean hasExternalVolumeController = notifyExternalVolumeController(direction); 3840 3841 new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume") 3842 .setUid(Binder.getCallingUid()) 3843 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 3844 .set(MediaMetrics.Property.CLIENT_NAME, caller) 3845 .set(MediaMetrics.Property.DIRECTION, direction > 0 3846 ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN) 3847 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController 3848 ? MediaMetrics.Value.YES : MediaMetrics.Value.NO) 3849 .set(MediaMetrics.Property.FLAGS, flags) 3850 .record(); 3851 3852 if (hasExternalVolumeController) { 3853 return; 3854 } 3855 3856 int streamType; 3857 synchronized (mForceControlStreamLock) { 3858 // Request lock in case mVolumeControlStream is changed by other thread. 3859 if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1 3860 streamType = mVolumeControlStream; 3861 } else { 3862 // TODO discard activity on a muted stream? 3863 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType); 3864 final boolean activeForReal; 3865 if (maybeActiveStreamType == AudioSystem.STREAM_RING 3866 || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) { 3867 activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0); 3868 } else { 3869 activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0); 3870 } 3871 if (activeForReal || mVolumeControlStream == -1) { 3872 streamType = maybeActiveStreamType; 3873 } else { 3874 streamType = mVolumeControlStream; 3875 } 3876 } 3877 } 3878 3879 final boolean isMute = isMuteAdjust(direction); 3880 3881 streamType = replaceBtScoStreamWithVoiceCall(streamType, "adjustSuggestedStreamVolume"); 3882 3883 ensureValidStreamType(streamType); 3884 final int resolvedStream = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1); 3885 if (resolvedStream == -1) { 3886 Log.e(TAG, "adjustSuggestedStreamVolume: no stream vol alias for stream type " 3887 + streamType); 3888 return; 3889 } 3890 3891 // Play sounds on STREAM_RING only. 3892 if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && 3893 resolvedStream != AudioSystem.STREAM_RING) { 3894 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3895 } 3896 3897 // For notifications/ring, show the ui before making any adjustments 3898 // Don't suppress mute/unmute requests 3899 // Don't suppress adjustments for single volume device 3900 if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute) 3901 && !mIsSingleVolume) { 3902 direction = 0; 3903 flags &= ~AudioManager.FLAG_PLAY_SOUND; 3904 flags &= ~AudioManager.FLAG_VIBRATE; 3905 if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); 3906 } 3907 3908 adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid, 3909 null, hasModifyAudioSettings, keyEventMode); 3910 } 3911 notifyExternalVolumeController(int direction)3912 private boolean notifyExternalVolumeController(int direction) { 3913 final IAudioPolicyCallback externalVolumeController; 3914 synchronized (mExtVolumeControllerLock) { 3915 externalVolumeController = mExtVolumeController; 3916 } 3917 if (externalVolumeController == null) { 3918 return false; 3919 } 3920 3921 sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE, 3922 direction, 0 /*ignored*/, 3923 externalVolumeController, 0 /*delay*/); 3924 return true; 3925 } 3926 3927 /** Retain API for unsupported app usage */ adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3928 public void adjustStreamVolume(int streamType, int direction, int flags, 3929 String callingPackage) { 3930 adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null); 3931 } 3932 3933 /** @see AudioManager#adjustStreamVolume(int, int, int) 3934 * Part of service interface, check permissions here */ adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3935 public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, 3936 String callingPackage, String attributionTag) { 3937 if (mHardeningEnforcer.blockVolumeMethod( 3938 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_STREAM_VOLUME, 3939 callingPackage, 3940 Binder.getCallingUid())) { 3941 return; 3942 } 3943 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 3944 Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without" 3945 + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage); 3946 return; 3947 } 3948 3949 final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType, 3950 direction/*val1*/, flags/*val2*/, callingPackage); 3951 sVolumeLogger.enqueue(evt); 3952 // also logging mute/unmute calls to the dedicated logger 3953 if (isMuteAdjust(direction)) { 3954 sMuteLogger.enqueue(evt); 3955 } 3956 adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, 3957 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag, 3958 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 3959 } 3960 adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3961 protected void adjustStreamVolume(int streamType, int direction, int flags, 3962 String callingPackage, String caller, int uid, int pid, String attributionTag, 3963 boolean hasModifyAudioSettings, int keyEventMode) { 3964 if (mUseFixedVolume) { 3965 return; 3966 } 3967 streamType = replaceBtScoStreamWithVoiceCall(streamType, "adjustStreamVolume"); 3968 3969 if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction 3970 + ", flags=" + flags + ", caller=" + caller); 3971 3972 ensureValidDirection(direction); 3973 ensureValidStreamType(streamType); 3974 3975 boolean isMuteAdjust = isMuteAdjust(direction); 3976 3977 if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { 3978 return; 3979 } 3980 3981 // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure 3982 // that the calling app have the MODIFY_PHONE_STATE permission. 3983 if (isMuteAdjust && 3984 (streamType == AudioSystem.STREAM_VOICE_CALL || 3985 // TODO: when replaceStreamBtSco flag is rolled out remove next condition 3986 isStreamBluetoothSco(streamType)) 3987 && mContext.checkPermission(MODIFY_PHONE_STATE, pid, uid) 3988 != PackageManager.PERMISSION_GRANTED) { 3989 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid=" 3990 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 3991 return; 3992 } 3993 3994 // If the stream is STREAM_ASSISTANT, 3995 // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission. 3996 if (streamType == AudioSystem.STREAM_ASSISTANT && 3997 mContext.checkPermission( 3998 MODIFY_AUDIO_ROUTING, pid, uid) 3999 != PackageManager.PERMISSION_GRANTED) { 4000 Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid=" 4001 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 4002 return; 4003 } 4004 4005 // use stream type alias here so that streams with same alias have the same behavior, 4006 // including with regard to silent mode control (e.g the use of STREAM_RING below and in 4007 // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION) 4008 int streamTypeAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1); 4009 if (streamTypeAlias == -1) { 4010 Log.e(TAG, 4011 "adjustStreamVolume: no stream vol alias for stream type " + streamType); 4012 } 4013 4014 VolumeStreamState streamState = getVssForStreamOrDefault(streamTypeAlias); 4015 4016 final int device = getDeviceForStream(streamTypeAlias); 4017 4018 int aliasIndex = streamState.getIndex(device); 4019 boolean adjustVolume = true; 4020 int step; 4021 4022 // skip a2dp absolute volume control request when the device 4023 // is neither an a2dp device nor BLE device 4024 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4025 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 4026 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 4027 return; 4028 } 4029 4030 // If we are being called by the system (e.g. hardware keys) check for current user 4031 // so we handle user restrictions correctly. 4032 if (uid == android.os.Process.SYSTEM_UID) { 4033 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 4034 } 4035 // validate calling package and app op 4036 if (!checkNoteAppOp( 4037 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 4038 return; 4039 } 4040 4041 mSoundDoseHelper.invalidatePendingVolumeCommand(); 4042 4043 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 4044 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 4045 flags |= AudioManager.FLAG_FIXED_VOLUME; 4046 4047 // Always toggle between max safe volume and 0 for fixed volume devices where safe 4048 // volume is enforced, and max and 0 for the others. 4049 // This is simulated by stepping by the full allowed volume range 4050 step = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 4051 if (step < 0) { 4052 step = streamState.getMaxIndex(); 4053 } 4054 if (aliasIndex != 0) { 4055 aliasIndex = step; 4056 } 4057 } else { 4058 // convert one UI step (+/-1) into a number of internal units on the stream alias 4059 step = rescaleStep((int) (10 * streamState.getIndexStepFactor()), streamType, 4060 streamTypeAlias); 4061 } 4062 4063 // If either the client forces allowing ringer modes for this adjustment, 4064 // or stream is used for UI sonification 4065 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 4066 (isUiSoundsStreamType(streamTypeAlias))) { 4067 int ringerMode = getRingerModeInternal(); 4068 // do not vibrate if already in vibrate mode 4069 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 4070 flags &= ~AudioManager.FLAG_VIBRATE; 4071 } 4072 // Check if the ringer mode handles this adjustment. If it does we don't 4073 // need to adjust the volume further. 4074 final int result = checkForRingerModeChange(aliasIndex, direction, step, 4075 streamState.mIsMuted, callingPackage, flags); 4076 adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; 4077 // If suppressing a volume adjustment in silent mode, display the UI hint 4078 if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { 4079 flags |= AudioManager.FLAG_SHOW_SILENT_HINT; 4080 } 4081 // If suppressing a volume down adjustment in vibrate mode, display the UI hint 4082 if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { 4083 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 4084 } 4085 } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) { 4086 // if the stream is currently muted streams by ringer/zen mode 4087 // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES) with an unmute or raise 4088 if (direction == AudioManager.ADJUST_TOGGLE_MUTE 4089 || direction == AudioManager.ADJUST_UNMUTE 4090 || direction == AudioManager.ADJUST_RAISE) { 4091 adjustVolume = false; 4092 } 4093 } 4094 4095 // If the ringer mode or zen is muting the stream, do not change stream unless 4096 // it'll cause us to exit dnd 4097 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 4098 adjustVolume = false; 4099 } 4100 int oldIndex = getVssForStreamOrDefault(streamType).getIndex(device); 4101 4102 // Check if the volume adjustment should be handled by an absolute volume controller instead 4103 if (isAbsoluteVolumeDevice(device) && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 4104 final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device); 4105 if (info.mHandlesVolumeAdjustment) { 4106 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction, 4107 keyEventMode); 4108 return; 4109 } 4110 } 4111 4112 if (adjustVolume && (direction != AudioManager.ADJUST_SAME) 4113 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) { 4114 mAudioHandler.removeMessages(MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE); 4115 4116 if (isMuteAdjust && !mFullVolumeDevices.contains(device)) { 4117 boolean state; 4118 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) { 4119 state = !streamState.mIsMuted; 4120 } else { 4121 state = direction == AudioManager.ADJUST_MUTE; 4122 } 4123 muteAliasStreams(streamTypeAlias, state); 4124 } else if ((direction == AudioManager.ADJUST_RAISE) 4125 && mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias, 4126 aliasIndex + step, device, flags)) { 4127 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); 4128 } else if (!isFullVolumeDevice(device) 4129 && (streamState.adjustIndex(direction * step, device, caller, 4130 hasModifyAudioSettings) 4131 || streamState.mIsMuted)) { 4132 // Post message to set system volume (it in turn will post a 4133 // message to persist). 4134 if (streamState.mIsMuted) { 4135 // Unmute the stream if it was previously muted 4136 if (direction == AudioManager.ADJUST_RAISE) { 4137 // unmute immediately for volume up 4138 muteAliasStreams(streamTypeAlias, false); 4139 } else if (direction == AudioManager.ADJUST_LOWER) { 4140 if (mIsSingleVolume) { 4141 sendMsg(mAudioHandler, MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE, 4142 SENDMSG_QUEUE, streamTypeAlias, flags, null, 4143 UNMUTE_STREAM_DELAY); 4144 } 4145 } 4146 } 4147 sendMsg(mAudioHandler, 4148 MSG_SET_DEVICE_VOLUME, 4149 SENDMSG_QUEUE, 4150 device, 4151 0, 4152 streamState, 4153 0); 4154 } 4155 4156 int newIndex = getVssForStreamOrDefault(streamType).getIndex(device); 4157 4158 // Check if volume update should be send to AVRCP 4159 if (streamTypeAlias == getBluetoothContextualVolumeStream() 4160 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 4161 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4162 if (DEBUG_VOL) { 4163 Log.d(TAG, "adjustStreamVolume: postSetAvrcpAbsoluteVolumeIndex index=" 4164 + newIndex + "stream=" + streamType); 4165 } 4166 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10); 4167 } else if (isAbsoluteVolumeDevice(device) 4168 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) { 4169 final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device); 4170 dispatchAbsoluteVolumeChanged(streamType, info, newIndex); 4171 } 4172 4173 if (AudioSystem.isLeAudioDeviceType(device) 4174 && streamType == getBluetoothContextualVolumeStream() 4175 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 4176 if (DEBUG_VOL) { 4177 Log.d(TAG, "adjustStreamVolume postSetLeAudioVolumeIndex index=" 4178 + newIndex + " stream=" + streamType); 4179 } 4180 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex, 4181 getVssForStreamOrDefault(streamType).getMaxIndex(), streamType); 4182 } 4183 4184 // Check if volume update should be send to Hearing Aid. 4185 // Only modify the hearing aid attenuation when the stream to modify matches 4186 // the one expected by the hearing aid. 4187 if (device == AudioSystem.DEVICE_OUT_HEARING_AID 4188 && streamType == getBluetoothContextualVolumeStream()) { 4189 if (DEBUG_VOL) { 4190 Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index=" 4191 + newIndex + " stream=" + streamType); 4192 } 4193 int haIndex; 4194 final VolumeStreamState vss = getVssForStreamOrDefault(streamType); 4195 synchronized (mVolumeStateLock) { 4196 haIndex = (int) (vss.getMinIndex() + (newIndex - vss.getMinIndex()) 4197 / vss.getIndexStepFactor()); 4198 } 4199 mDeviceBroker.postSetHearingAidVolumeIndex(haIndex, streamType); 4200 } 4201 } 4202 4203 final int newIndex = getVssForStreamOrDefault(streamType).getIndex(device); 4204 if (adjustVolume) { 4205 synchronized (mHdmiClientLock) { 4206 if (mHdmiManager != null) { 4207 // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null 4208 HdmiClient hdmiClient = mHdmiPlaybackClient; 4209 if (mHdmiTvClient != null) { 4210 hdmiClient = mHdmiTvClient; 4211 } 4212 4213 boolean playbackDeviceConditions = mHdmiPlaybackClient != null 4214 && isFullVolumeDevice(device); 4215 boolean tvConditions = mHdmiTvClient != null 4216 && mHdmiSystemAudioSupported 4217 && !isAbsoluteVolumeDevice(device) 4218 && !isA2dpAbsoluteVolumeDevice(device); 4219 4220 if ((playbackDeviceConditions || tvConditions) 4221 && mHdmiCecVolumeControlEnabled 4222 && streamTypeAlias == AudioSystem.STREAM_MUSIC) { 4223 int keyCode = KeyEvent.KEYCODE_UNKNOWN; 4224 switch (direction) { 4225 case AudioManager.ADJUST_RAISE: 4226 keyCode = KeyEvent.KEYCODE_VOLUME_UP; 4227 break; 4228 case AudioManager.ADJUST_LOWER: 4229 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN; 4230 break; 4231 case AudioManager.ADJUST_TOGGLE_MUTE: 4232 case AudioManager.ADJUST_MUTE: 4233 case AudioManager.ADJUST_UNMUTE: 4234 // Many CEC devices only support toggle mute. Therefore, we send the 4235 // same keycode for all three mute options. 4236 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE; 4237 break; 4238 default: 4239 break; 4240 } 4241 if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { 4242 final long ident = Binder.clearCallingIdentity(); 4243 try { 4244 switch (keyEventMode) { 4245 case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL: 4246 hdmiClient.sendVolumeKeyEvent(keyCode, true); 4247 hdmiClient.sendVolumeKeyEvent(keyCode, false); 4248 break; 4249 case AudioDeviceVolumeManager.ADJUST_MODE_START: 4250 hdmiClient.sendVolumeKeyEvent(keyCode, true); 4251 break; 4252 case AudioDeviceVolumeManager.ADJUST_MODE_END: 4253 hdmiClient.sendVolumeKeyEvent(keyCode, false); 4254 break; 4255 default: 4256 Log.e(TAG, "Invalid keyEventMode " + keyEventMode); 4257 } 4258 } finally { 4259 Binder.restoreCallingIdentity(ident); 4260 } 4261 } 4262 } 4263 4264 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 4265 && (oldIndex != newIndex || isMuteAdjust)) { 4266 maybeSendSystemAudioStatusCommand(isMuteAdjust); 4267 } 4268 } 4269 } 4270 } 4271 sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device); 4272 } 4273 4274 /** 4275 * Loops on aliased stream, update the mute cache attribute of each 4276 * {@see AudioService#VolumeStreamState}, and then apply the change. 4277 * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream 4278 * and aliases before mute change changed and after. 4279 */ muteAliasStreams(int streamAlias, boolean state)4280 private void muteAliasStreams(int streamAlias, boolean state) { 4281 // Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex 4282 synchronized (mSettingsLock) { 4283 synchronized (mVolumeStateLock) { 4284 List<Integer> streamsToMute = new ArrayList<>(); 4285 for (int streamIdx = 0; streamIdx < mStreamStates.size(); streamIdx++) { 4286 final VolumeStreamState vss = mStreamStates.valueAt(streamIdx); 4287 if (vss != null && streamAlias == sStreamVolumeAlias.get(vss.getStreamType()) 4288 && vss.isMutable()) { 4289 if (!(mCameraSoundForced.get() && (vss.getStreamType() 4290 == AudioSystem.STREAM_SYSTEM_ENFORCED))) { 4291 boolean changed = vss.mute(state, /* apply= */ false, 4292 "muteAliasStreams"); 4293 if (changed) { 4294 streamsToMute.add(vss.getStreamType()); 4295 } 4296 } 4297 } 4298 } 4299 streamsToMute.forEach(streamToMute -> { 4300 getVssForStreamOrDefault(streamToMute).doMute(); 4301 broadcastMuteSetting(streamToMute, state); 4302 }); 4303 } 4304 } 4305 } 4306 broadcastMuteSetting(int streamType, boolean isMuted)4307 private void broadcastMuteSetting(int streamType, boolean isMuted) { 4308 // Stream mute changed, fire the intent. 4309 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); 4310 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted); 4311 if (replaceStreamBtSco() && isStreamBluetoothSco(streamType)) { 4312 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, 4313 AudioSystem.STREAM_BLUETOOTH_SCO); 4314 // in this case broadcast for both sco and voice_call streams the mute status 4315 sendBroadcastToAll(intent, null /* options */); 4316 } 4317 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType); 4318 sendBroadcastToAll(intent, null /* options */); 4319 } 4320 4321 // Called after a delay when volume down is pressed while muted onUnmuteStreamOnSingleVolDevice(int streamAlias, int flags)4322 private void onUnmuteStreamOnSingleVolDevice(int streamAlias, int flags) { 4323 boolean wasMuted; 4324 // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute -> 4325 // vss.updateVolumeGroupIndex 4326 synchronized (mSettingsLock) { 4327 synchronized (mVolumeStateLock) { 4328 final VolumeStreamState streamState = getVssForStreamOrDefault(streamAlias); 4329 // if unmuting causes a change, it was muted 4330 wasMuted = streamState.mute(false, "onUnmuteStreamOnSingleVolDevice"); 4331 if (wasMuted) { 4332 // Unmute all aliasted streams 4333 muteAliasStreams(streamAlias, false); 4334 } 4335 final int device = getDeviceForStream(streamAlias); 4336 final int index = streamState.getIndex(device); 4337 sendVolumeUpdate(streamAlias, index, index, flags, device); 4338 } 4339 if (streamAlias == AudioSystem.STREAM_MUSIC && wasMuted) { 4340 synchronized (mHdmiClientLock) { 4341 maybeSendSystemAudioStatusCommand(true); 4342 } 4343 } 4344 } 4345 } 4346 4347 @GuardedBy("mHdmiClientLock") maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)4348 private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) { 4349 if (mHdmiAudioSystemClient == null 4350 || !mHdmiSystemAudioSupported 4351 || !mHdmiCecVolumeControlEnabled) { 4352 return; 4353 } 4354 4355 final long identity = Binder.clearCallingIdentity(); 4356 try { 4357 mHdmiAudioSystemClient.sendReportAudioStatusCecCommand( 4358 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC), 4359 getStreamMaxVolume(AudioSystem.STREAM_MUSIC), 4360 isStreamMute(AudioSystem.STREAM_MUSIC)); 4361 } finally { 4362 Binder.restoreCallingIdentity(identity); 4363 } 4364 } 4365 getNewRingerMode(int stream, int index, int flags)4366 private int getNewRingerMode(int stream, int index, int flags) { 4367 // setRingerMode does nothing if the device is single volume,so the value would be unchanged 4368 if (mIsSingleVolume) { 4369 return getRingerModeExternal(); 4370 } 4371 4372 // setting volume on ui sounds stream type also controls silent mode 4373 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 4374 (stream == getUiSoundsStreamType())) { 4375 int newRingerMode; 4376 if (index == 0) { 4377 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE 4378 : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT 4379 : AudioManager.RINGER_MODE_NORMAL; 4380 } else { 4381 newRingerMode = AudioManager.RINGER_MODE_NORMAL; 4382 } 4383 return newRingerMode; 4384 } 4385 return getRingerModeExternal(); 4386 } 4387 isAndroidNPlus(String caller)4388 private boolean isAndroidNPlus(String caller) { 4389 try { 4390 final ApplicationInfo applicationInfo = 4391 mContext.getPackageManager().getApplicationInfoAsUser( 4392 caller, 0, UserHandle.getUserId(Binder.getCallingUid())); 4393 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 4394 return true; 4395 } 4396 return false; 4397 } catch (PackageManager.NameNotFoundException e) { 4398 return true; 4399 } 4400 } 4401 wouldToggleZenMode(int newMode)4402 private boolean wouldToggleZenMode(int newMode) { 4403 if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT 4404 && newMode != AudioManager.RINGER_MODE_SILENT) { 4405 return true; 4406 } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT 4407 && newMode == AudioManager.RINGER_MODE_SILENT) { 4408 return true; 4409 } 4410 return false; 4411 } 4412 4413 /** 4414 * Update stream volume, ringer mode and mute status after a volume index change 4415 * @param streamType 4416 * @param index 4417 * @param flags 4418 * @param device the device for which the volume is changed 4419 * @param caller 4420 * @param hasModifyAudioSettings 4421 * @param canChangeMute true if the origin of this event is one where the mute state should be 4422 * updated following the change in volume index 4423 */ onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)4424 /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device, 4425 String caller, boolean hasModifyAudioSettings, boolean canChangeMute) { 4426 final int stream = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1); 4427 if (stream == -1) { 4428 Log.e(TAG, "onSetStreamVolume: no stream vol alias for stream type " + stream); 4429 return; 4430 } 4431 // setting volume on ui sounds stream type also controls silent mode 4432 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 4433 (stream == getUiSoundsStreamType())) { 4434 setRingerMode(getNewRingerMode(stream, index, flags), 4435 TAG + ".onSetStreamVolume", false /*external*/); 4436 } 4437 setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings); 4438 // setting non-zero volume for a muted stream unmutes the stream and vice versa 4439 // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements 4440 if (!isStreamBluetoothSco(streamType) && canChangeMute) { 4441 // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams. 4442 muteAliasStreams(stream, index == 0); 4443 } 4444 } 4445 enforceModifyAudioRoutingPermission()4446 private void enforceModifyAudioRoutingPermission() { 4447 if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 4448 != PackageManager.PERMISSION_GRANTED) { 4449 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 4450 } 4451 } 4452 enforceQueryStateOrModifyRoutingPermission()4453 private void enforceQueryStateOrModifyRoutingPermission() { 4454 if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 4455 != PackageManager.PERMISSION_GRANTED 4456 && mContext.checkCallingOrSelfPermission(QUERY_AUDIO_STATE) 4457 != PackageManager.PERMISSION_GRANTED) { 4458 throw new SecurityException( 4459 "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions"); 4460 } 4461 } 4462 4463 //================================ 4464 // Audio Volume Change Dispatcher 4465 //================================ 4466 private final AudioVolumeChangeHandler mAudioVolumeChangeHandler; 4467 4468 /** @see AudioManager#registerVolumeGroupCallback(executor, callback) */ registerAudioVolumeCallback(IAudioVolumeChangeDispatcher callback)4469 public void registerAudioVolumeCallback(IAudioVolumeChangeDispatcher callback) { 4470 mAudioVolumeChangeHandler.registerListener(callback); 4471 } 4472 4473 /** @see AudioManager#unregisterVolumeGroupCallback(callback) */ unregisterAudioVolumeCallback(IAudioVolumeChangeDispatcher callback)4474 public void unregisterAudioVolumeCallback(IAudioVolumeChangeDispatcher callback) { 4475 mAudioVolumeChangeHandler.unregisterListener(callback); 4476 } 4477 4478 @Override 4479 @android.annotation.EnforcePermission(anyOf = { 4480 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) 4481 /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */ setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)4482 public void setVolumeGroupVolumeIndex(int groupId, int index, int flags, 4483 String callingPackage, String attributionTag) { 4484 super.setVolumeGroupVolumeIndex_enforcePermission(); 4485 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4486 Log.e(TAG, ": no volume group found for id " + groupId); 4487 return; 4488 } 4489 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4490 4491 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(), 4492 index, flags, callingPackage + ", user " + getCurrentUserId())); 4493 4494 vgs.setVolumeIndex(index, flags); 4495 4496 // For legacy reason, propagate to all streams associated to this volume group 4497 for (int groupedStream : vgs.getLegacyStreamTypes()) { 4498 try { 4499 ensureValidStreamType(groupedStream); 4500 } catch (IllegalArgumentException e) { 4501 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream 4502 + "), do not change associated stream volume"); 4503 continue; 4504 } 4505 setStreamVolume(groupedStream, index, flags, /*device*/ null, 4506 callingPackage, callingPackage, 4507 attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/, 4508 true /*canChangeMuteAndUpdateController*/); 4509 } 4510 } 4511 4512 @Override 4513 @android.annotation.EnforcePermission(anyOf = { 4514 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) 4515 /** @see AudioManager#getVolumeGroupVolumeIndex(int) */ getVolumeGroupVolumeIndex(int groupId)4516 public int getVolumeGroupVolumeIndex(int groupId) { 4517 super.getVolumeGroupVolumeIndex_enforcePermission(); 4518 synchronized (mVolumeStateLock) { 4519 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4520 Log.e(TAG, "No volume group for id " + groupId); 4521 return 0; 4522 } 4523 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4524 // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero 4525 // min but it mutable on permission condition. 4526 return vgs.isMuted() ? 0 : vgs.getVolumeIndex(); 4527 } 4528 } 4529 4530 /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */ 4531 @android.annotation.EnforcePermission(anyOf = { 4532 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) getVolumeGroupMaxVolumeIndex(int groupId)4533 public int getVolumeGroupMaxVolumeIndex(int groupId) { 4534 super.getVolumeGroupMaxVolumeIndex_enforcePermission(); 4535 synchronized (mVolumeStateLock) { 4536 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4537 Log.e(TAG, "No volume group for id " + groupId); 4538 return 0; 4539 } 4540 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4541 return vgs.getMaxIndex(); 4542 } 4543 } 4544 4545 /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */ 4546 @android.annotation.EnforcePermission(anyOf = { 4547 MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING }) getVolumeGroupMinVolumeIndex(int groupId)4548 public int getVolumeGroupMinVolumeIndex(int groupId) { 4549 super.getVolumeGroupMinVolumeIndex_enforcePermission(); 4550 synchronized (mVolumeStateLock) { 4551 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4552 Log.e(TAG, "No volume group for id " + groupId); 4553 return 0; 4554 } 4555 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4556 return vgs.getMinIndex(); 4557 } 4558 } 4559 4560 @Override 4561 @android.annotation.EnforcePermission(anyOf = { 4562 MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED }) 4563 /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes) 4564 * Part of service interface, check permissions and parameters here 4565 * Note calling package is for logging purposes only, not to be trusted 4566 */ setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)4567 public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, 4568 @NonNull String callingPackage) { 4569 super.setDeviceVolume_enforcePermission(); 4570 Objects.requireNonNull(vi); 4571 Objects.requireNonNull(ada); 4572 Objects.requireNonNull(callingPackage); 4573 4574 if (!vi.hasStreamType()) { 4575 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 4576 return; 4577 } 4578 4579 int index = vi.getVolumeIndex(); 4580 if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) { 4581 throw new IllegalArgumentException( 4582 "changing device volume requires a volume index or mute command"); 4583 } 4584 4585 // force a cache clear to force reevaluating stream type to audio device selection 4586 // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent 4587 mAudioSystem.clearRoutingCache(); 4588 4589 int streamType = replaceBtScoStreamWithVoiceCall(vi.getStreamType(), "setDeviceVolume"); 4590 4591 final VolumeStreamState vss = getVssForStream(streamType); 4592 4593 // log the current device that will be used when evaluating the sending of the 4594 // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified 4595 final int currDev = getDeviceForStream(streamType); 4596 4597 final boolean skipping = (currDev == ada.getInternalType()) || (vss == null); 4598 4599 AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(streamType, index, ada, 4600 currDev, callingPackage, skipping)); 4601 4602 if (skipping) { 4603 // setDeviceVolume was called on a device currently being used or stream state is null 4604 return; 4605 } 4606 4607 // TODO handle unmuting of current audio device 4608 // if a stream is not muted but the VolumeInfo is for muting, set the volume index 4609 // for the device to min volume 4610 if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(streamType)) { 4611 setStreamVolumeWithAttributionInt(streamType, 4612 vss.getMinIndex(), 4613 /*flags*/ 0, 4614 ada, callingPackage, null, 4615 //TODO handle unmuting of current audio device 4616 false /*canChangeMuteAndUpdateController*/); 4617 return; 4618 } 4619 4620 AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage 4621 + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG); 4622 4623 if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET 4624 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) { 4625 // assume index meant to be in stream type range, validate 4626 if ((index * 10) < vss.getMinIndex() 4627 || (index * 10) > vss.getMaxIndex()) { 4628 throw new IllegalArgumentException("invalid volume index " + index 4629 + " not between min/max for stream " + vi.getStreamType()); 4630 } 4631 } else { 4632 // check if index needs to be rescaled 4633 final int min = (vss.getMinIndex() + 5) / 10; 4634 final int max = (vss.getMaxIndex() + 5) / 10; 4635 if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) { 4636 index = rescaleIndex(index, 4637 /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(), 4638 /*dstMin*/ min, /*dstMax*/ max); 4639 } 4640 } 4641 setStreamVolumeWithAttributionInt(streamType, index, /*flags*/ 0, 4642 ada, callingPackage, null, 4643 false /*canChangeMuteAndUpdateController*/); 4644 } 4645 4646 /** Retain API for unsupported app usage */ setStreamVolume(int streamType, int index, int flags, String callingPackage)4647 public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { 4648 setStreamVolumeWithAttribution(streamType, index, flags, 4649 callingPackage, /*attributionTag*/ null); 4650 } 4651 4652 /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */ adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)4653 public void adjustVolumeGroupVolume(int groupId, int direction, int flags, 4654 String callingPackage) { 4655 ensureValidDirection(direction); 4656 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4657 Log.e(TAG, ": no volume group found for id " + groupId); 4658 return; 4659 } 4660 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4661 // For compatibility reason, use stream API if group linked to a valid stream 4662 boolean fallbackOnStream = false; 4663 for (int stream : vgs.getLegacyStreamTypes()) { 4664 try { 4665 ensureValidStreamType(stream); 4666 } catch (IllegalArgumentException e) { 4667 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream 4668 + "), do not change associated stream volume"); 4669 continue; 4670 } 4671 // Note: Group and Stream does not share same convention, 0 is mute for stream, 4672 // min index is acting as mute for Groups 4673 if (vgs.isVssMuteBijective(stream)) { 4674 adjustStreamVolume(stream, direction, flags, callingPackage); 4675 if (isMuteAdjust(direction)) { 4676 // will be propagated to all aliased streams 4677 return; 4678 } 4679 fallbackOnStream = true; 4680 } 4681 } 4682 if (fallbackOnStream) { 4683 // Handled by at least one stream, will be propagated to group, bailing out. 4684 return; 4685 } 4686 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(), 4687 direction, flags, callingPackage)); 4688 vgs.adjustVolume(direction, flags); 4689 } 4690 4691 /** @see AudioManager#getLastAudibleVolumeForVolumeGroup(int) */ 4692 @android.annotation.EnforcePermission(QUERY_AUDIO_STATE) getLastAudibleVolumeForVolumeGroup(int groupId)4693 public int getLastAudibleVolumeForVolumeGroup(int groupId) { 4694 super.getLastAudibleVolumeForVolumeGroup_enforcePermission(); 4695 synchronized (mVolumeStateLock) { 4696 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4697 Log.e(TAG, ": no volume group found for id " + groupId); 4698 return 0; 4699 } 4700 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4701 return vgs.getVolumeIndex(); 4702 } 4703 } 4704 4705 /** @see AudioManager#isVolumeGroupMuted(int) */ isVolumeGroupMuted(int groupId)4706 public boolean isVolumeGroupMuted(int groupId) { 4707 synchronized (mVolumeStateLock) { 4708 if (sVolumeGroupStates.indexOfKey(groupId) < 0) { 4709 Log.e(TAG, ": no volume group found for id " + groupId); 4710 return false; 4711 } 4712 VolumeGroupState vgs = sVolumeGroupStates.get(groupId); 4713 return vgs.isMuted(); 4714 } 4715 } 4716 4717 /** @see AudioManager#setStreamVolume(int, int, int) 4718 * Part of service interface, check permissions here */ setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)4719 public void setStreamVolumeWithAttribution(int streamType, int index, int flags, 4720 String callingPackage, String attributionTag) { 4721 if (mHardeningEnforcer.blockVolumeMethod( 4722 HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_STREAM_VOLUME, 4723 callingPackage, 4724 Binder.getCallingUid())) { 4725 return; 4726 } 4727 setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null, 4728 callingPackage, attributionTag, true /*canChangeMuteAndUpdateController*/); 4729 } 4730 4731 /** 4732 * Internal method for a stream type volume change. Can be used to change the volume on a 4733 * given device only 4734 * @param streamType the stream type whose volume is to be changed 4735 * @param index the volume index 4736 * @param flags options for volume handling 4737 * @param device null when controlling volume for the current routing, otherwise the device 4738 * for which volume is being changed 4739 * @param callingPackage client side-provided package name of caller, not to be trusted 4740 * @param attributionTag client side-provided attribution name, not to be trusted 4741 * @param canChangeMuteAndUpdateController true if the calling method is a path where 4742 * the volume change is allowed to update the mute state as well as update 4743 * the volume controller (the UI). This is intended to be true for a call coming 4744 * from AudioManager.setStreamVolume (which is here 4745 * {@link #setStreamVolumeForUid(int, int, int, String, int, int, UserHandle, int)}, 4746 * and false when coming from AudioDeviceVolumeManager.setDeviceVolume (which is here 4747 * {@link #setDeviceVolume(VolumeInfo, AudioDeviceAttributes, String)} 4748 */ setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String attributionTag, boolean canChangeMuteAndUpdateController)4749 protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags, 4750 @Nullable AudioDeviceAttributes ada, 4751 String callingPackage, String attributionTag, 4752 boolean canChangeMuteAndUpdateController) { 4753 streamType = replaceBtScoStreamWithVoiceCall(streamType, 4754 "setStreamVolumeWithAttributionInt"); 4755 4756 if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) { 4757 Log.w(TAG, "Trying to call setStreamVolume() for a11y without" 4758 + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage); 4759 return; 4760 } 4761 if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0) 4762 && (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 4763 != PackageManager.PERMISSION_GRANTED) && !isStreamBluetoothSco(streamType)) { 4764 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without" 4765 + " MODIFY_PHONE_STATE callingPackage=" + callingPackage); 4766 return; 4767 } 4768 if ((streamType == AudioManager.STREAM_ASSISTANT) 4769 && (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 4770 != PackageManager.PERMISSION_GRANTED)) { 4771 Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without" 4772 + " MODIFY_AUDIO_ROUTING callingPackage=" + callingPackage); 4773 return; 4774 } 4775 4776 if (ada == null) { 4777 // call was already logged in setDeviceVolume() 4778 final int deviceType = getDeviceForStream(streamType); 4779 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType, 4780 index/*val1*/, flags/*val2*/, getStreamVolume(streamType, deviceType) /*val3*/, 4781 callingPackage)); 4782 ada = new AudioDeviceAttributes(deviceType /*nativeType*/, "" /*address*/); 4783 } 4784 setStreamVolume(streamType, index, flags, ada, 4785 callingPackage, callingPackage, attributionTag, 4786 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission(), 4787 canChangeMuteAndUpdateController); 4788 } 4789 4790 @android.annotation.EnforcePermission(Manifest.permission.ACCESS_ULTRASOUND) 4791 /** @see AudioManager#isUltrasoundSupported() */ isUltrasoundSupported()4792 public boolean isUltrasoundSupported() { 4793 super.isUltrasoundSupported_enforcePermission(); 4794 4795 return AudioSystem.isUltrasoundSupported(); 4796 } 4797 4798 /** @see AudioManager#isHotwordStreamSupported(boolean) */ 4799 @android.annotation.EnforcePermission(CAPTURE_AUDIO_HOTWORD) isHotwordStreamSupported(boolean lookbackAudio)4800 public boolean isHotwordStreamSupported(boolean lookbackAudio) { 4801 super.isHotwordStreamSupported_enforcePermission(); 4802 try { 4803 return mAudioPolicy.isHotwordStreamSupported(lookbackAudio); 4804 } catch (IllegalStateException e) { 4805 // Suppress connection failure to APM, since the method is purely informative 4806 Log.e(TAG, "Suppressing exception calling into AudioPolicy", e); 4807 return false; 4808 } 4809 } 4810 4811 canChangeAccessibilityVolume()4812 private boolean canChangeAccessibilityVolume() { 4813 synchronized (mAccessibilityServiceUidsLock) { 4814 if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 4815 Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) { 4816 return true; 4817 } 4818 if (mAccessibilityServiceUids != null) { 4819 int callingUid = Binder.getCallingUid(); 4820 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 4821 if (mAccessibilityServiceUids[i] == callingUid) { 4822 return true; 4823 } 4824 } 4825 } 4826 return false; 4827 } 4828 } 4829 4830 /** only public for mocking/spying, do not call outside of AudioService */ 4831 @VisibleForTesting getBluetoothContextualVolumeStream()4832 public int getBluetoothContextualVolumeStream() { 4833 return getBluetoothContextualVolumeStream(mMode.get()); 4834 } 4835 getBluetoothContextualVolumeStream(int mode)4836 private int getBluetoothContextualVolumeStream(int mode) { 4837 boolean voiceActivityCanOverride = true; 4838 switch (mode) { 4839 case AudioSystem.MODE_IN_COMMUNICATION: 4840 case AudioSystem.MODE_IN_CALL: 4841 // TODO(b/382704431): remove to allow STREAM_VOICE_CALL to drive abs volume 4842 // over A2DP 4843 if (getDeviceForStream(AudioSystem.STREAM_VOICE_CALL) 4844 == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { 4845 return AudioSystem.STREAM_MUSIC; 4846 } 4847 return AudioSystem.STREAM_VOICE_CALL; 4848 case AudioSystem.MODE_CALL_SCREENING: 4849 case AudioSystem.MODE_COMMUNICATION_REDIRECT: 4850 case AudioSystem.MODE_CALL_REDIRECT: 4851 voiceActivityCanOverride = false; 4852 // intended fallthrough 4853 case AudioSystem.MODE_NORMAL: 4854 default: 4855 // other conditions will influence the stream type choice, read on... 4856 break; 4857 } 4858 4859 if (voiceActivityCanOverride && mVoicePlaybackActive.get()) { 4860 // TODO(b/382704431): remove to allow STREAM_VOICE_CALL to drive abs volume over A2DP 4861 if (getDeviceForStream(AudioSystem.STREAM_VOICE_CALL) 4862 == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { 4863 return AudioSystem.STREAM_MUSIC; 4864 } 4865 return AudioSystem.STREAM_VOICE_CALL; 4866 } 4867 return AudioSystem.STREAM_MUSIC; 4868 } 4869 4870 private final AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false); 4871 private final AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false); 4872 4873 private final IPlaybackConfigDispatcher mPlaybackActivityMonitor = 4874 new IPlaybackConfigDispatcher.Stub() { 4875 @Override 4876 public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs, 4877 boolean flush) { 4878 sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE, 4879 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 4880 configs /*obj*/, 0 /*delay*/); 4881 } 4882 }; 4883 onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4884 private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) { 4885 boolean voiceActive = false; 4886 boolean mediaActive = false; 4887 for (AudioPlaybackConfiguration config : configs) { 4888 final int usage = config.getAudioAttributes().getUsage(); 4889 if (!config.isActive()) { 4890 continue; 4891 } 4892 if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4893 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) { 4894 voiceActive = true; 4895 } 4896 if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME 4897 || usage == AudioAttributes.USAGE_UNKNOWN) { 4898 mediaActive = true; 4899 } 4900 } 4901 if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) { 4902 postUpdateContextualVolumes(); 4903 } 4904 if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) { 4905 mSoundDoseHelper.scheduleMusicActiveCheck(); 4906 } 4907 4908 mLoudnessCodecHelper.updateCodecParameters(configs); 4909 4910 // Update playback active state for all apps in audio mode stack. 4911 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 4912 // and request an audio mode update immediately. Upon any other change, queue the message 4913 // and request an audio mode update after a grace period. 4914 updateAudioModeHandlers( 4915 configs /* playbackConfigs */, null /* recordConfigs */); 4916 mDeviceBroker.updateCommunicationRouteClientsActivity( 4917 configs /* playbackConfigs */, null /* recordConfigs */); 4918 } 4919 updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, List<AudioRecordingConfiguration> recordConfigs)4920 void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, 4921 List<AudioRecordingConfiguration> recordConfigs) { 4922 synchronized (mDeviceBroker.mSetModeLock) { 4923 boolean updateAudioMode = false; 4924 int existingMsgPolicy = SENDMSG_QUEUE; 4925 int delay = CHECK_MODE_FOR_UID_PERIOD_MS; 4926 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 4927 boolean wasActive = h.isActive(); 4928 if (playbackConfigs != null) { 4929 h.setPlaybackActive(false); 4930 for (AudioPlaybackConfiguration config : playbackConfigs) { 4931 final int usage = config.getAudioAttributes().getUsage(); 4932 if (config.getClientUid() == h.getUid() 4933 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION 4934 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) 4935 && config.isActive()) { 4936 h.setPlaybackActive(true); 4937 break; 4938 } 4939 } 4940 } 4941 if (recordConfigs != null) { 4942 h.setRecordingActive(false); 4943 for (AudioRecordingConfiguration config : recordConfigs) { 4944 if (config.getClientUid() == h.getUid() && !config.isClientSilenced() 4945 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) { 4946 h.setRecordingActive(true); 4947 break; 4948 } 4949 } 4950 } 4951 if (wasActive != h.isActive()) { 4952 updateAudioMode = true; 4953 if (h.isActive() && h == getAudioModeOwnerHandler()) { 4954 existingMsgPolicy = SENDMSG_REPLACE; 4955 delay = 0; 4956 } 4957 } 4958 } 4959 if (updateAudioMode) { 4960 postUpdateAudioMode(existingMsgPolicy, AudioSystem.MODE_CURRENT, 4961 android.os.Process.myPid(), mContext.getPackageName(), 4962 false /*signal*/, delay); 4963 } 4964 } 4965 } 4966 4967 static class UpdateAudioModeInfo { UpdateAudioModeInfo(int mode, int pid, String packageName)4968 UpdateAudioModeInfo(int mode, int pid, String packageName) { 4969 mMode = mode; 4970 mPid = pid; 4971 mPackageName = packageName; 4972 } 4973 private final int mMode; 4974 private final int mPid; 4975 private final String mPackageName; 4976 getMode()4977 int getMode() { 4978 return mMode; 4979 } getPid()4980 int getPid() { 4981 return mPid; 4982 } getPackageName()4983 String getPackageName() { 4984 return mPackageName; 4985 } 4986 } 4987 postUpdateAudioMode(int msgPolicy, int mode, int pid, String packageName, boolean signal, int delay)4988 void postUpdateAudioMode(int msgPolicy, int mode, int pid, String packageName, 4989 boolean signal, int delay) { 4990 synchronized (mAudioModeResetLock) { 4991 if (signal) { 4992 mAudioModeResetCount++; 4993 } 4994 sendMsg(mAudioHandler, signal ? MSG_UPDATE_AUDIO_MODE_SIGNAL : MSG_UPDATE_AUDIO_MODE, 4995 msgPolicy, 0, 0, new UpdateAudioModeInfo(mode, pid, packageName), delay); 4996 } 4997 } 4998 4999 private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor = 5000 new IRecordingConfigDispatcher.Stub() { 5001 @Override 5002 public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 5003 sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE, 5004 0 /*arg1 ignored*/, 0 /*arg2 ignored*/, 5005 configs /*obj*/, 0 /*delay*/); 5006 } 5007 }; 5008 onRecordingConfigChange(List<AudioRecordingConfiguration> configs)5009 private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) { 5010 // Update recording active state for all apps in audio mode stack. 5011 // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE 5012 // and request an audio mode update immediately. Upon any other change, queue the message 5013 // and request an audio mode update after a grace period. 5014 updateAudioModeHandlers( 5015 null /* playbackConfigs */, configs /* recordConfigs */); 5016 mDeviceBroker.updateCommunicationRouteClientsActivity( 5017 null /* playbackConfigs */, configs /* recordConfigs */); 5018 } 5019 dumpFlags(PrintWriter pw)5020 private void dumpFlags(PrintWriter pw) { 5021 5022 pw.println("\nFun with Flags:"); 5023 pw.println("\tcom.android.media.audio.as_device_connection_failure:" 5024 + asDeviceConnectionFailure()); 5025 pw.println("\tandroid.media.audio.autoPublicVolumeApiHardening:" 5026 + autoPublicVolumeApiHardening()); 5027 pw.println("\tandroid.media.audio.automaticBtDeviceType - EOL"); 5028 pw.println("\tandroid.media.audio.featureSpatialAudioHeadtrackingLowLatency:" 5029 + featureSpatialAudioHeadtrackingLowLatency()); 5030 pw.println("\tandroid.media.audio.focusFreezeTestApi:" 5031 + focusFreezeTestApi()); 5032 pw.println("\tcom.android.media.audio.audioserverPermissions:" 5033 + audioserverPermissions()); 5034 pw.println("\tcom.android.media.audio.disablePrescaleAbsoluteVolume:" 5035 + disablePrescaleAbsoluteVolume()); 5036 pw.println("\tcom.android.media.audio.setStreamVolumeOrder - EOL"); 5037 pw.println("\tandroid.media.audio.ringtoneUserUriCheck:" 5038 + android.media.audio.Flags.ringtoneUserUriCheck()); 5039 pw.println("\tandroid.media.audio.roForegroundAudioControl:" 5040 + roForegroundAudioControl()); 5041 pw.println("\tandroid.media.audio.scoManagedByAudio:" 5042 + scoManagedByAudio()); 5043 pw.println("\tcom.android.media.audio.absVolumeIndexFix - EOL"); 5044 pw.println("\tcom.android.media.audio.vgsVssSyncMuteOrder - EOL"); 5045 pw.println("\tcom.android.media.audio.replaceStreamBtSco:" 5046 + replaceStreamBtSco()); 5047 pw.println("\tcom.android.media.audio.equalScoLeaVcIndexRange:" 5048 + equalScoLeaVcIndexRange()); 5049 pw.println("\tcom.android.media.audio.ringMyCar:" 5050 + ringMyCar()); 5051 pw.println("\tandroid.media.audio.Flags.concurrentAudioRecordBypassPermission:" 5052 + concurrentAudioRecordBypassPermission()); 5053 pw.println("\tandroid.media.audio.Flags.cacheGetStreamMinMaxVolume:" 5054 + cacheGetStreamMinMaxVolume()); 5055 pw.println("\tandroid.media.audio.Flags.cacheGetStreamVolume:" 5056 + cacheGetStreamVolume()); 5057 pw.println("\tcom.android.media.audio.optimizeBtDeviceSwitch:" 5058 + optimizeBtDeviceSwitch()); 5059 } 5060 dumpAudioMode(PrintWriter pw)5061 private void dumpAudioMode(PrintWriter pw) { 5062 pw.println("\nAudio mode: "); 5063 pw.println("- Requested mode = " + AudioSystem.modeToString(getMode())); 5064 pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get())); 5065 pw.println("- Mode owner: "); 5066 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 5067 if (hdlr != null) { 5068 hdlr.dump(pw, -1); 5069 } else { 5070 pw.println(" None"); 5071 } 5072 pw.println("- Mode owner stack: "); 5073 if (mSetModeDeathHandlers.isEmpty()) { 5074 pw.println(" Empty"); 5075 } else { 5076 for (int i = 0; i < mSetModeDeathHandlers.size(); i++) { 5077 mSetModeDeathHandlers.get(i).dump(pw, i); 5078 } 5079 } 5080 } 5081 5082 5083 // delay between audio playback configuration update and checking 5084 // actual stream activity to take async playback stop into account 5085 private static final int UPDATE_CONTEXTUAL_VOLUME_DELAY_MS = 500; 5086 postUpdateContextualVolumes()5087 /*package*/ void postUpdateContextualVolumes() { 5088 sendMsg(mAudioHandler, MSG_UPDATE_CONTEXTUAL_VOLUMES, SENDMSG_REPLACE, 5089 /*arg1*/ 0, /*arg2*/ 0, TAG, UPDATE_CONTEXTUAL_VOLUME_DELAY_MS); 5090 } 5091 onUpdateContextualVolumes()5092 private void onUpdateContextualVolumes() { 5093 final int streamType = getBluetoothContextualVolumeStream(); 5094 5095 Slog.i(TAG, 5096 "onUpdateContextualVolumes: absolute volume driving streams " + streamType 5097 + " avrcp supported: " + mAvrcpAbsVolSupported); 5098 synchronized (mCachedAbsVolDrivingStreamsLock) { 5099 mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> { 5100 boolean enabled = true; 5101 if (absDev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { 5102 enabled = mAvrcpAbsVolSupported; 5103 if (!enabled) { 5104 Slog.w(TAG, "Updating avrcp not supported in onUpdateContextualVolumes"); 5105 } 5106 } 5107 if (stream != streamType) { 5108 final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, 5109 /*address=*/"", enabled, streamType); 5110 if (result != AudioSystem.AUDIO_STATUS_OK) { 5111 sVolumeLogger.enqueueAndSlog( 5112 new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR, 5113 result, absDev, enabled, streamType).eventToString(), ALOGE, 5114 TAG); 5115 } 5116 } 5117 return streamType; 5118 }); 5119 } 5120 5121 final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType); 5122 Set<Integer> absVolumeDeviceTypes = new ArraySet<>( 5123 AudioSystem.DEVICE_OUT_ALL_A2DP_SET); 5124 absVolumeDeviceTypes.addAll(mAbsVolumeMultiModeCaseDevices); 5125 5126 final Set<Integer> absVolumeDevices = 5127 AudioSystem.intersectionAudioDeviceTypes(absVolumeDeviceTypes, deviceTypes); 5128 if (absVolumeDevices.isEmpty()) { 5129 return; 5130 } 5131 if (absVolumeDevices.size() > 1) { 5132 Slog.w(TAG, "onUpdateContextualVolumes too many active devices: " 5133 + absVolumeDevices.stream().map(AudioSystem::getOutputDeviceName) 5134 .collect(Collectors.joining(",")) 5135 + ", for stream: " + streamType); 5136 return; 5137 } 5138 5139 final int device = absVolumeDevices.toArray(new Integer[0])[0].intValue(); 5140 final int index = (getVolumeForDeviceIgnoreMute(streamType, device) + 5) / 10; 5141 5142 if (DEBUG_VOL) { 5143 Slog.i(TAG, "onUpdateContextualVolumes streamType: " + streamType 5144 + ", device: " + AudioSystem.getOutputDeviceName(device) 5145 + ", index: " + index); 5146 } 5147 5148 if (AudioSystem.isLeAudioDeviceType(device)) { 5149 mDeviceBroker.postSetLeAudioVolumeIndex(index * 10, 5150 getVssForStreamOrDefault(streamType).getMaxIndex(), streamType); 5151 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 5152 int haIndex = index * 10; 5153 final VolumeStreamState vss = getVssForStreamOrDefault(streamType); 5154 synchronized (mVolumeStateLock) { 5155 haIndex = (int) (vss.getMinIndex() 5156 + (haIndex - vss.getMinIndex()) / vss.getIndexStepFactor()); 5157 } 5158 mDeviceBroker.postSetHearingAidVolumeIndex(haIndex, streamType); 5159 } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)) { 5160 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index); 5161 } else { 5162 return; 5163 } 5164 5165 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME, 5166 mVoicePlaybackActive.get(), streamType, index, device)); 5167 } 5168 setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings, boolean canChangeMuteAndUpdateController)5169 private void setStreamVolume(int streamType, int index, int flags, 5170 @Nullable AudioDeviceAttributes ada, 5171 String callingPackage, String caller, String attributionTag, int uid, 5172 boolean hasModifyAudioSettings, 5173 boolean canChangeMuteAndUpdateController) { 5174 5175 if (DEBUG_VOL) { 5176 Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index 5177 + ", dev=" + ada 5178 + ", calling=" + callingPackage + ")"); 5179 } 5180 if (mUseFixedVolume) { 5181 return; 5182 } 5183 streamType = replaceBtScoStreamWithVoiceCall(streamType, "setStreamVolume"); 5184 5185 ensureValidStreamType(streamType); 5186 int streamTypeAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound*/-1); 5187 if (streamTypeAlias == -1) { 5188 Log.e(TAG, "setStreamVolume: no stream vol alias for stream type " + streamType); 5189 return; 5190 } 5191 final VolumeStreamState streamState = getVssForStreamOrDefault(streamTypeAlias); 5192 5193 if (!replaceStreamBtSco() && (streamType == AudioManager.STREAM_VOICE_CALL) 5194 && isInCommunication() && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) { 5195 Log.i(TAG, "setStreamVolume for STREAM_VOICE_CALL, switching to STREAM_BLUETOOTH_SCO"); 5196 streamType = AudioManager.STREAM_BLUETOOTH_SCO; 5197 } 5198 5199 final int device = (ada == null) 5200 ? getDeviceForStream(streamType) 5201 : ada.getInternalType(); 5202 int oldIndex; 5203 5204 // skip a2dp absolute volume control request when the device 5205 // is neither an a2dp device nor BLE device 5206 if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 5207 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) 5208 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 5209 return; 5210 } 5211 // If we are being called by the system (e.g. hardware keys) check for current user 5212 // so we handle user restrictions correctly. 5213 if (uid == android.os.Process.SYSTEM_UID) { 5214 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 5215 } 5216 if (!checkNoteAppOp( 5217 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) { 5218 return; 5219 } 5220 5221 if (isAndroidNPlus(callingPackage) 5222 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) 5223 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { 5224 throw new SecurityException("Not allowed to change Do Not Disturb state"); 5225 } 5226 5227 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 5228 return; 5229 } 5230 5231 mSoundDoseHelper.invalidatePendingVolumeCommand(); 5232 5233 oldIndex = streamState.getIndex(device); 5234 5235 index = rescaleIndex(index * 10, streamType, streamTypeAlias); 5236 5237 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 5238 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) { 5239 flags |= AudioManager.FLAG_FIXED_VOLUME; 5240 5241 // volume is either 0 or max allowed for fixed volume devices 5242 if (index != 0) { 5243 index = mSoundDoseHelper.getSafeMediaVolumeIndex(device); 5244 if (index < 0) { 5245 index = streamState.getMaxIndex(); 5246 } 5247 } 5248 } 5249 5250 if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device, 5251 flags)) { 5252 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings, 5253 // ada is non-null when called from setDeviceVolume, 5254 // which shouldn't update the mute state 5255 canChangeMuteAndUpdateController /*canChangeMute*/); 5256 index = getVssForStreamOrDefault(streamType).getIndex(device); 5257 } 5258 5259 if (streamTypeAlias == getBluetoothContextualVolumeStream() 5260 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) 5261 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 5262 if (DEBUG_VOL) { 5263 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index 5264 + "stream=" + streamType); 5265 } 5266 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10); 5267 } else if (isAbsoluteVolumeDevice(device) 5268 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) { 5269 final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device); 5270 5271 dispatchAbsoluteVolumeChanged(streamType, info, index); 5272 } 5273 5274 if (AudioSystem.isLeAudioDeviceType(device) 5275 && streamType == getBluetoothContextualVolumeStream() 5276 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 5277 if (DEBUG_VOL) { 5278 Log.d(TAG, "setStreamVolume postSetLeAudioVolumeIndex index=" 5279 + index + " stream=" + streamType); 5280 } 5281 mDeviceBroker.postSetLeAudioVolumeIndex(index, 5282 getVssForStreamOrDefault(streamType).getMaxIndex(), streamType); 5283 } 5284 5285 if (device == AudioSystem.DEVICE_OUT_HEARING_AID 5286 && streamType == getBluetoothContextualVolumeStream()) { 5287 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index 5288 + " stream=" + streamType); 5289 int haIndex; 5290 final VolumeStreamState vss = getVssForStreamOrDefault(streamType); 5291 synchronized (mVolumeStateLock) { 5292 haIndex = (int) (vss.getMinIndex() 5293 + (index - vss.getMinIndex()) / vss.getIndexStepFactor()); 5294 } 5295 mDeviceBroker.postSetHearingAidVolumeIndex(haIndex, streamType); 5296 } 5297 5298 synchronized (mHdmiClientLock) { 5299 if (streamTypeAlias == AudioSystem.STREAM_MUSIC 5300 && (oldIndex != index)) { 5301 maybeSendSystemAudioStatusCommand(false); 5302 } 5303 } 5304 if (canChangeMuteAndUpdateController) { 5305 // only non-null when coming here from setDeviceVolume 5306 // TODO change test to check early if device is current device or not 5307 sendVolumeUpdate(streamType, oldIndex, index, flags, device); 5308 } 5309 } 5310 dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)5311 private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, 5312 int index) { 5313 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 5314 if (volumeInfo != null) { 5315 try { 5316 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice, 5317 new VolumeInfo.Builder(volumeInfo) 5318 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 5319 .build()); 5320 } catch (RemoteException e) { 5321 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change"); 5322 } 5323 } 5324 } 5325 dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)5326 private void dispatchAbsoluteVolumeAdjusted(int streamType, 5327 AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) { 5328 VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType); 5329 if (volumeInfo != null) { 5330 try { 5331 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice, 5332 new VolumeInfo.Builder(volumeInfo) 5333 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo)) 5334 .build(), 5335 direction, 5336 mode); 5337 } catch (RemoteException e) { 5338 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment"); 5339 } 5340 } 5341 } 5342 5343 // No ringer or zen muted stream volumes can be changed unless it'll exit dnd volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)5344 private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { 5345 switch (mNm.getZenMode()) { 5346 case Settings.Global.ZEN_MODE_OFF: 5347 return true; 5348 case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: 5349 case Settings.Global.ZEN_MODE_ALARMS: 5350 case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: 5351 return !isStreamMutedByRingerOrZenMode(streamTypeAlias) 5352 || isUiSoundsStreamType(streamTypeAlias) 5353 || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0; 5354 } 5355 5356 return true; 5357 } 5358 5359 /** @see AudioManager#forceVolumeControlStream(int) */ forceVolumeControlStream(int streamType, IBinder cb)5360 public void forceVolumeControlStream(int streamType, IBinder cb) { 5361 if (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 5362 != PackageManager.PERMISSION_GRANTED) { 5363 return; 5364 } 5365 5366 streamType = replaceBtScoStreamWithVoiceCall(streamType, "forceVolumeControlStream"); 5367 5368 if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); } 5369 synchronized(mForceControlStreamLock) { 5370 if (mVolumeControlStream != -1 && streamType != -1) { 5371 mUserSelectedVolumeControlStream = true; 5372 } 5373 mVolumeControlStream = streamType; 5374 if (mVolumeControlStream == -1) { 5375 if (mForceControlStreamClient != null) { 5376 mForceControlStreamClient.release(); 5377 mForceControlStreamClient = null; 5378 } 5379 mUserSelectedVolumeControlStream = false; 5380 } else { 5381 if (null == mForceControlStreamClient) { 5382 mForceControlStreamClient = new ForceControlStreamClient(cb); 5383 } else { 5384 if (mForceControlStreamClient.getBinder() == cb) { 5385 Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked."); 5386 } else { 5387 mForceControlStreamClient.release(); 5388 mForceControlStreamClient = new ForceControlStreamClient(cb); 5389 } 5390 } 5391 } 5392 } 5393 } 5394 5395 private class ForceControlStreamClient implements IBinder.DeathRecipient { 5396 private IBinder mCb; // To be notified of client's death 5397 ForceControlStreamClient(IBinder cb)5398 ForceControlStreamClient(IBinder cb) { 5399 if (cb != null) { 5400 try { 5401 cb.linkToDeath(this, 0); 5402 } catch (RemoteException e) { 5403 // Client has died! 5404 Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); 5405 cb = null; 5406 } 5407 } 5408 mCb = cb; 5409 } 5410 binderDied()5411 public void binderDied() { 5412 synchronized(mForceControlStreamLock) { 5413 Log.w(TAG, "SCO client died"); 5414 if (mForceControlStreamClient != this) { 5415 Log.w(TAG, "unregistered control stream client died"); 5416 } else { 5417 mForceControlStreamClient = null; 5418 mVolumeControlStream = -1; 5419 mUserSelectedVolumeControlStream = false; 5420 } 5421 } 5422 } 5423 release()5424 public void release() { 5425 if (mCb != null) { 5426 mCb.unlinkToDeath(this, 0); 5427 mCb = null; 5428 } 5429 } 5430 getBinder()5431 public IBinder getBinder() { 5432 return mCb; 5433 } 5434 } 5435 sendBroadcastToAll(Intent intent, Bundle options)5436 private void sendBroadcastToAll(Intent intent, Bundle options) { 5437 if (!mSystemServer.isPrivileged()) { 5438 return; 5439 } 5440 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 5441 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 5442 final long ident = Binder.clearCallingIdentity(); 5443 try { 5444 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 5445 null /* receiverPermission */, options); 5446 } finally { 5447 Binder.restoreCallingIdentity(ident); 5448 } 5449 } 5450 sendStickyBroadcastToAll(Intent intent)5451 private void sendStickyBroadcastToAll(Intent intent) { 5452 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 5453 final long ident = Binder.clearCallingIdentity(); 5454 try { 5455 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 5456 } finally { 5457 Binder.restoreCallingIdentity(ident); 5458 } 5459 } 5460 getCurrentUserId()5461 private int getCurrentUserId() { 5462 final long ident = Binder.clearCallingIdentity(); 5463 try { 5464 UserInfo currentUser = ActivityManager.getService().getCurrentUser(); 5465 return currentUser.id; 5466 } catch (RemoteException e) { 5467 // Activity manager not running, nothing we can do assume user 0. 5468 } finally { 5469 Binder.restoreCallingIdentity(ident); 5470 } 5471 return UserHandle.USER_SYSTEM; 5472 } 5473 5474 // UI update and Broadcast Intent sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)5475 protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device) 5476 { 5477 streamType = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1); 5478 if (streamType == -1) { 5479 Slog.e(TAG, "Invalid stream type. No update to IVolumeController", new Exception()); 5480 return; 5481 } 5482 5483 if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) { 5484 flags &= ~AudioManager.FLAG_SHOW_UI; 5485 } 5486 mVolumeController.postVolumeChanged(streamType, flags); 5487 } 5488 5489 // Don't show volume UI when: 5490 // - Hdmi-CEC system audio mode is on and we are a TV panel updateFlagsForTvPlatform(int flags)5491 private int updateFlagsForTvPlatform(int flags) { 5492 synchronized (mHdmiClientLock) { 5493 if (mHdmiTvClient != null && mHdmiSystemAudioSupported 5494 && mHdmiCecVolumeControlEnabled) { 5495 flags &= ~AudioManager.FLAG_SHOW_UI; 5496 } 5497 } 5498 return flags; 5499 } 5500 // UI update and Broadcast Intent sendMasterMuteUpdate(boolean muted, int flags)5501 private void sendMasterMuteUpdate(boolean muted, int flags) { 5502 mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags)); 5503 sendMsg(mAudioHandler, MSG_BROADCAST_MASTER_MUTE, 5504 SENDMSG_QUEUE, muted ? 1 : 0, 0, null, 0); 5505 } 5506 5507 5508 /** 5509 * Sets the stream state's index, and posts a message to set system volume. 5510 * This will not call out to the UI. Assumes a valid stream type. 5511 * 5512 * @param streamType Type of the stream 5513 * @param index Desired volume index of the stream 5514 * @param device the device whose volume must be changed 5515 * @param force If true, set the volume even if the desired volume is same 5516 * @param caller 5517 * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or 5518 * MODIFY_AUDIO_ROUTING permission 5519 * as the current volume. 5520 */ setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)5521 private void setStreamVolumeInt(int streamType, 5522 int index, 5523 int device, 5524 boolean force, 5525 String caller, boolean hasModifyAudioSettings) { 5526 if (isFullVolumeDevice(device)) { 5527 return; 5528 } 5529 final VolumeStreamState streamState = getVssForStreamOrDefault(streamType); 5530 5531 if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) { 5532 // Post message to set system volume (it in turn will post a message 5533 // to persist). 5534 sendMsg(mAudioHandler, 5535 MSG_SET_DEVICE_VOLUME, 5536 SENDMSG_QUEUE, 5537 device, 5538 0, 5539 streamState, 5540 0); 5541 } 5542 } 5543 5544 /** get stream mute state. */ isStreamMute(int streamType)5545 public boolean isStreamMute(int streamType) { 5546 if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 5547 streamType = getActiveStreamType(streamType); 5548 } 5549 streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamMute"); 5550 5551 synchronized (mVolumeStateLock) { 5552 ensureValidStreamType(streamType); 5553 return getVssForStreamOrDefault(streamType).mIsMuted; 5554 } 5555 } 5556 5557 private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient { 5558 private IBinder mICallback; // To be notified of client's death 5559 RmtSbmxFullVolDeathHandler(IBinder cb)5560 RmtSbmxFullVolDeathHandler(IBinder cb) { 5561 mICallback = cb; 5562 try { 5563 cb.linkToDeath(this, 0/*flags*/); 5564 } catch (RemoteException e) { 5565 Log.e(TAG, "can't link to death", e); 5566 } 5567 } 5568 isHandlerFor(IBinder cb)5569 boolean isHandlerFor(IBinder cb) { 5570 return mICallback.equals(cb); 5571 } 5572 forget()5573 void forget() { 5574 try { 5575 mICallback.unlinkToDeath(this, 0/*flags*/); 5576 } catch (NoSuchElementException e) { 5577 Log.e(TAG, "error unlinking to death", e); 5578 } 5579 } 5580 binderDied()5581 public void binderDied() { 5582 Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback); 5583 forceRemoteSubmixFullVolume(false, mICallback); 5584 } 5585 } 5586 5587 /** 5588 * call must be synchronized on mRmtSbmxFullVolDeathHandlers 5589 * @return true if there is a registered death handler, false otherwise */ discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)5590 private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 5591 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 5592 while (it.hasNext()) { 5593 final RmtSbmxFullVolDeathHandler handler = it.next(); 5594 if (handler.isHandlerFor(cb)) { 5595 handler.forget(); 5596 mRmtSbmxFullVolDeathHandlers.remove(handler); 5597 return true; 5598 } 5599 } 5600 return false; 5601 } 5602 5603 /** call synchronized on mRmtSbmxFullVolDeathHandlers */ hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)5604 private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 5605 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 5606 while (it.hasNext()) { 5607 if (it.next().isHandlerFor(cb)) { 5608 return true; 5609 } 5610 } 5611 return false; 5612 } 5613 5614 private int mRmtSbmxFullVolRefCount = 0; 5615 private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers = 5616 new ArrayList<RmtSbmxFullVolDeathHandler>(); 5617 forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)5618 public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) { 5619 if (cb == null) { 5620 return; 5621 } 5622 if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 5623 CAPTURE_AUDIO_OUTPUT))) { 5624 Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT"); 5625 return; 5626 } 5627 synchronized(mRmtSbmxFullVolDeathHandlers) { 5628 boolean applyRequired = false; 5629 if (startForcing) { 5630 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { 5631 mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); 5632 if (mRmtSbmxFullVolRefCount == 0) { 5633 mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 5634 mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 5635 applyRequired = true; 5636 } 5637 mRmtSbmxFullVolRefCount++; 5638 } 5639 } else { 5640 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { 5641 mRmtSbmxFullVolRefCount--; 5642 if (mRmtSbmxFullVolRefCount == 0) { 5643 mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 5644 mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); 5645 applyRequired = true; 5646 } 5647 } 5648 } 5649 if (applyRequired) { 5650 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX 5651 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC); 5652 getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).applyAllVolumes(); 5653 } 5654 } 5655 } 5656 setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)5657 private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, 5658 int userId, int pid, String attributionTag) { 5659 // If we are being called by the system check for user we are going to change 5660 // so we handle user restrictions correctly. 5661 if (uid == android.os.Process.SYSTEM_UID) { 5662 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 5663 } 5664 // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. 5665 if (!mute && !checkNoteAppOp( 5666 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) { 5667 return; 5668 } 5669 if (userId != UserHandle.getCallingUserId() && 5670 mContext.checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid) 5671 != PackageManager.PERMISSION_GRANTED) { 5672 return; 5673 } 5674 setMasterMuteInternalNoCallerCheck(mute, flags, userId, "setMasterMute"); 5675 } 5676 setMasterMuteInternalNoCallerCheck( boolean mute, int flags, int userId, String eventSource)5677 private void setMasterMuteInternalNoCallerCheck( 5678 boolean mute, int flags, int userId, String eventSource) { 5679 if (DEBUG_VOL) { 5680 Log.d(TAG, TextUtils.formatSimple("Master mute %s, flags 0x%x, userId=%d from %s", 5681 mute, flags, userId, eventSource)); 5682 } 5683 5684 if (!isPlatformAutomotive() && mUseFixedVolume) { 5685 // If using fixed volume, we don't mute. 5686 // TODO: remove the isPlatformAutomotive check here. 5687 // The isPlatformAutomotive check is added for safety but may not be necessary. 5688 mute = false; 5689 } 5690 // For automotive, 5691 // - the car service is always running as system user 5692 // - foreground users are non-system users 5693 // Car service is in charge of dispatching the key event include global mute to Android. 5694 // Therefore, the getCurrentUser() is always different to the foreground user. 5695 if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM) 5696 || (getCurrentUserId() == userId)) { 5697 if (mute != mMasterMute.getAndSet(mute)) { 5698 sVolumeLogger.enqueue(new VolumeEvent( 5699 VolumeEvent.VOL_MASTER_MUTE, mute)); 5700 mAudioSystem.setMasterMute(mute); 5701 sendMasterMuteUpdate(mute, flags); 5702 } 5703 } 5704 } 5705 5706 /** get global mute state. */ isMasterMute()5707 public boolean isMasterMute() { 5708 return mMasterMute.get(); 5709 } 5710 5711 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 5712 /** @see AudioManager#setMasterMute(boolean, int) */ setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)5713 public void setMasterMute(boolean mute, int flags, String callingPackage, int userId, 5714 String attributionTag) { 5715 5716 super.setMasterMute_enforcePermission(); 5717 5718 setMasterMuteInternal(mute, flags, callingPackage, 5719 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag); 5720 } 5721 5722 /** @see AudioManager#getStreamVolume(int) */ getStreamVolume(int streamType)5723 public int getStreamVolume(int streamType) { 5724 streamType = replaceBtScoStreamWithVoiceCall(streamType, "getStreamVolume"); 5725 5726 ensureValidStreamType(streamType); 5727 int device = getDeviceForStream(streamType); 5728 return getStreamVolume(streamType, device); 5729 } 5730 getStreamVolume(int streamType, int device)5731 private int getStreamVolume(int streamType, int device) { 5732 synchronized (mVolumeStateLock) { 5733 final VolumeStreamState vss = getVssForStreamOrDefault(streamType); 5734 int index = vss.getIndex(device); 5735 5736 // by convention getStreamVolume() returns 0 when a stream is muted. 5737 if (vss.mIsMuted) { 5738 index = 0; 5739 } 5740 if (index != 0 && (sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_MUSIC) 5741 && isFixedVolumeDevice(device)) { 5742 index = vss.getMaxIndex(); 5743 } 5744 return (index + 5) / 10; 5745 } 5746 } 5747 5748 @Override 5749 @android.annotation.EnforcePermission(anyOf = { 5750 MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED }) 5751 /** 5752 * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes) 5753 */ getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)5754 public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi, 5755 @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) { 5756 super.getDeviceVolume_enforcePermission(); 5757 Objects.requireNonNull(vi); 5758 Objects.requireNonNull(ada); 5759 Objects.requireNonNull(callingPackage); 5760 if (!vi.hasStreamType()) { 5761 Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception()); 5762 return getDefaultVolumeInfo(); 5763 } 5764 5765 int streamType = replaceBtScoStreamWithVoiceCall(vi.getStreamType(), "getStreamMaxVolume"); 5766 final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi); 5767 final VolumeStreamState vss = getVssForStream(streamType); 5768 if (vss == null) { 5769 Log.w(TAG, 5770 "getDeviceVolume unsupported stream type " + streamType + ". Return default"); 5771 return getDefaultVolumeInfo(); 5772 } 5773 5774 vib.setMinVolumeIndex((vss.mIndexMin + 5) / 10); 5775 vib.setMaxVolumeIndex((vss.mIndexMax + 5) / 10); 5776 synchronized (mVolumeStateLock) { 5777 final int index; 5778 if (isFixedVolumeDevice(ada.getInternalType())) { 5779 index = (vss.mIndexMax + 5) / 10; 5780 } else { 5781 index = (vss.getIndex(ada.getInternalType()) + 5) / 10; 5782 } 5783 vib.setVolumeIndex(index); 5784 // only set as a mute command if stream muted 5785 if (vss.mIsMuted) { 5786 vib.setMuted(true); 5787 } 5788 return vib.build(); 5789 } 5790 } 5791 5792 /** @see AudioManager#getStreamMaxVolume(int) */ getStreamMaxVolume(int streamType)5793 public int getStreamMaxVolume(int streamType) { 5794 streamType = replaceBtScoStreamWithVoiceCall(streamType, "getStreamMaxVolume"); 5795 ensureValidStreamType(streamType); 5796 return (getVssForStreamOrDefault(streamType).getMaxIndex() + 5) / 10; 5797 } 5798 5799 /** @see AudioManager#getStreamMinVolumeInt(int) 5800 * Part of service interface, check permissions here */ getStreamMinVolume(int streamType)5801 public int getStreamMinVolume(int streamType) { 5802 streamType = replaceBtScoStreamWithVoiceCall(streamType, "getStreamMinVolume"); 5803 ensureValidStreamType(streamType); 5804 final boolean isPrivileged = 5805 Binder.getCallingUid() == Process.SYSTEM_UID 5806 || callingHasAudioSettingsPermission() 5807 || (mContext.checkCallingPermission(MODIFY_AUDIO_ROUTING) 5808 == PackageManager.PERMISSION_GRANTED); 5809 return (getVssForStreamOrDefault(streamType).getMinIndex(isPrivileged) + 5) / 10; 5810 } 5811 5812 @android.annotation.EnforcePermission(QUERY_AUDIO_STATE) 5813 /** Get last audible volume before stream was muted. */ getLastAudibleStreamVolume(int streamType)5814 public int getLastAudibleStreamVolume(int streamType) { 5815 super.getLastAudibleStreamVolume_enforcePermission(); 5816 5817 streamType = replaceBtScoStreamWithVoiceCall(streamType, "getLastAudibleStreamVolume"); 5818 5819 ensureValidStreamType(streamType); 5820 5821 int device = getDeviceForStream(streamType); 5822 return (getVssForStreamOrDefault(streamType).getIndex(device) + 5) / 10; 5823 } 5824 5825 /** 5826 * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()} 5827 * Lazily initialized in {@link #getDefaultVolumeInfo()} 5828 */ 5829 static VolumeInfo sDefaultVolumeInfo; 5830 5831 /** @see VolumeInfo#getDefaultVolumeInfo() */ getDefaultVolumeInfo()5832 public VolumeInfo getDefaultVolumeInfo() { 5833 if (sDefaultVolumeInfo == null) { 5834 sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC) 5835 .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC)) 5836 .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC)) 5837 .build(); 5838 } 5839 return sDefaultVolumeInfo; 5840 } 5841 5842 /** 5843 * list of callback dispatchers for stream aliasing updates 5844 */ 5845 final RemoteCallbackList<IStreamAliasingDispatcher> mStreamAliasingDispatchers = 5846 new RemoteCallbackList<IStreamAliasingDispatcher>(); 5847 5848 /** 5849 * Register/unregister a callback for stream aliasing updates 5850 * @param isad the callback dispatcher 5851 * @param register whether this for a registration or unregistration 5852 * @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable) 5853 * @see AudioManager#removeOnStreamAliasingChangedListener(Runnable) 5854 */ 5855 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register)5856 public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) { 5857 super.registerStreamAliasingDispatcher_enforcePermission(); 5858 Objects.requireNonNull(isad); 5859 5860 if (register) { 5861 mStreamAliasingDispatchers.register(isad); 5862 } else { 5863 mStreamAliasingDispatchers.unregister(isad); 5864 } 5865 } 5866 dispatchStreamAliasingUpdate()5867 protected void dispatchStreamAliasingUpdate() { 5868 final int nbDispatchers = mStreamAliasingDispatchers.beginBroadcast(); 5869 for (int i = 0; i < nbDispatchers; i++) { 5870 try { 5871 mStreamAliasingDispatchers.getBroadcastItem(i).dispatchStreamAliasingChanged(); 5872 } catch (RemoteException e) { 5873 Log.e(TAG, "Error on stream alias update dispatch", e); 5874 } 5875 } 5876 mStreamAliasingDispatchers.finishBroadcast(); 5877 } 5878 5879 /** 5880 * @see AudioManager#getIndependentStreamTypes() 5881 * @return the list of non-aliased stream types 5882 */ 5883 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getIndependentStreamTypes()5884 public ArrayList<Integer> getIndependentStreamTypes() { 5885 super.getIndependentStreamTypes_enforcePermission(); 5886 5887 if (mUseVolumeGroupAliases) { 5888 return new ArrayList<>(Arrays.stream(AudioManager.getPublicStreamTypes()) 5889 .boxed().toList()); 5890 } 5891 ArrayList<Integer> res = new ArrayList<>(1); 5892 for (int streamIdx = 0; streamIdx < sStreamVolumeAlias.size(); ++streamIdx) { 5893 final int streamAlias = sStreamVolumeAlias.valueAt(streamIdx); 5894 if (!res.contains(streamAlias)) { 5895 res.add(streamAlias); 5896 } 5897 } 5898 return res; 5899 } 5900 5901 /** 5902 * @see AudioManager#getStreamTypeAlias(int) 5903 * @param sourceStreamType the stream type for which the alias is queried 5904 * @return the stream alias 5905 */ 5906 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 5907 public @AudioManager.PublicStreamTypes getStreamTypeAlias(@udioManager.PublicStreamTypes int sourceStreamType)5908 int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) { 5909 super.getStreamTypeAlias_enforcePermission(); 5910 5911 sourceStreamType = replaceBtScoStreamWithVoiceCall(sourceStreamType, "getStreamTypeAlias"); 5912 5913 // verify parameters 5914 ensureValidStreamType(sourceStreamType); 5915 5916 return sStreamVolumeAlias.get(sourceStreamType, /*valueIfKeyNotFound=*/-1); 5917 } 5918 5919 /** 5920 * @see AudioManager#isVolumeControlUsingVolumeGroups() 5921 * @return true when volume control is performed through volume groups, false if it uses 5922 * stream types. 5923 */ 5924 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isVolumeControlUsingVolumeGroups()5925 public boolean isVolumeControlUsingVolumeGroups() { 5926 super.isVolumeControlUsingVolumeGroups_enforcePermission(); 5927 5928 return mUseVolumeGroupAliases; 5929 } 5930 5931 /** @see AudioManager#getUiSoundsStreamType() 5932 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 5933 * UI Sounds identification. 5934 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 5935 */ getUiSoundsStreamType()5936 public int getUiSoundsStreamType() { 5937 return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 5938 : sStreamVolumeAlias.get(AudioSystem.STREAM_SYSTEM); 5939 } 5940 5941 /** 5942 * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for 5943 * UI Sounds identification. 5944 * Fallback on Voice configuration to ensure correct behavior of DnD feature. 5945 */ isUiSoundsStreamType(int aliasStreamType)5946 private boolean isUiSoundsStreamType(int aliasStreamType) { 5947 return mUseVolumeGroupAliases 5948 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType] 5949 == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM] 5950 : aliasStreamType == sStreamVolumeAlias.get(AudioSystem.STREAM_SYSTEM); 5951 } 5952 5953 /** 5954 * @see AudioDeviceVolumeManager#setInputGainIndex(AudioDeviceAttributes, int) 5955 */ 5956 @Override 5957 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setInputGainIndex(@onNull AudioDeviceAttributes ada, int index)5958 public void setInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) { 5959 super.setInputGainIndex_enforcePermission(); 5960 5961 if (mInputDeviceVolumeHelper.setInputGainIndex(ada, index)) { 5962 // Post message to set system volume (it in turn will post a message 5963 // to persist). 5964 sendMsg( 5965 mAudioHandler, 5966 MSG_APPLY_INPUT_GAIN_INDEX, 5967 SENDMSG_QUEUE, 5968 /*arg1*/ index, 5969 /*arg2*/ 0, 5970 /*obj*/ ada, 5971 /*delay*/ 0); 5972 } 5973 } 5974 onApplyInputGainIndex(@onNull AudioDeviceAttributes ada, int index)5975 private void onApplyInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) { 5976 // TODO(b/364923030): call AudioSystem to apply input gain in native layer. 5977 5978 // Post a persist input gain msg. 5979 sendMsg( 5980 mAudioHandler, 5981 MSG_PERSIST_INPUT_GAIN_INDEX, 5982 SENDMSG_REPLACE, 5983 /*arg1*/ 0, 5984 /*arg2*/ 0, 5985 /*obj*/ ada, 5986 PERSIST_DELAY); 5987 } 5988 onPersistInputGainIndex(@onNull AudioDeviceAttributes ada)5989 private void onPersistInputGainIndex(@NonNull AudioDeviceAttributes ada) { 5990 mInputDeviceVolumeHelper.persistInputGainIndex(ada); 5991 } 5992 5993 /** 5994 * @see AudioDeviceVolumeManager#getInputGainIndex(AudioDeviceAttributes) 5995 */ 5996 @Override 5997 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getInputGainIndex(@onNull AudioDeviceAttributes ada)5998 public int getInputGainIndex(@NonNull AudioDeviceAttributes ada) { 5999 super.getInputGainIndex_enforcePermission(); 6000 6001 return mInputDeviceVolumeHelper.getInputGainIndex(ada); 6002 } 6003 6004 /** 6005 * @see AudioDeviceVolumeManager#getMaxInputGainIndex() 6006 */ 6007 @Override 6008 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getMaxInputGainIndex()6009 public int getMaxInputGainIndex() { 6010 super.getMaxInputGainIndex_enforcePermission(); 6011 6012 return mInputDeviceVolumeHelper.getMaxInputGainIndex(); 6013 } 6014 6015 /** 6016 * @see AudioDeviceVolumeManager#getMinInputGainIndex() 6017 */ 6018 @Override 6019 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getMinInputGainIndex()6020 public int getMinInputGainIndex() { 6021 super.getMinInputGainIndex_enforcePermission(); 6022 6023 return mInputDeviceVolumeHelper.getMinInputGainIndex(); 6024 } 6025 6026 /** 6027 * @see AudioDeviceVolumeManager#isInputGainFixed(AudioDeviceAttributes) 6028 */ 6029 @Override 6030 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isInputGainFixed(@onNull AudioDeviceAttributes ada)6031 public boolean isInputGainFixed(@NonNull AudioDeviceAttributes ada) { 6032 super.isInputGainFixed_enforcePermission(); 6033 6034 return mInputDeviceVolumeHelper.isInputGainFixed(ada); 6035 } 6036 6037 /** @see AudioManager#setMicrophoneMute(boolean) */ 6038 @Override setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)6039 public void setMicrophoneMute(boolean on, String callingPackage, int userId, 6040 String attributionTag) { 6041 // If we are being called by the system check for user we are going to change 6042 // so we handle user restrictions correctly. 6043 int uid = Binder.getCallingUid(); 6044 if (uid == android.os.Process.SYSTEM_UID) { 6045 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 6046 } 6047 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 6048 .setUid(uid) 6049 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage) 6050 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute") 6051 .set(MediaMetrics.Property.REQUEST, on 6052 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE); 6053 6054 // If OP_MUTE_MICROPHONE is set, disallow unmuting. 6055 if (!on && !checkNoteAppOp( 6056 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) { 6057 mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record(); 6058 return; 6059 } 6060 if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 6061 mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record(); 6062 return; 6063 } 6064 if (userId != UserHandle.getCallingUserId() && 6065 mContext.checkCallingOrSelfPermission(INTERACT_ACROSS_USERS_FULL) 6066 != PackageManager.PERMISSION_GRANTED) { 6067 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record(); 6068 return; 6069 } 6070 mMicMuteFromApi = on; 6071 mmi.record(); // record now, the no caller check will set the mute state. 6072 setMicrophoneMuteNoCallerCheck(userId); 6073 } 6074 6075 /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */ setMicrophoneMuteFromSwitch(boolean on)6076 public void setMicrophoneMuteFromSwitch(boolean on) { 6077 int callingUid = Binder.getCallingUid(); 6078 if (callingUid != android.os.Process.SYSTEM_UID) { 6079 Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!"); 6080 return; 6081 } 6082 mMicMuteFromSwitch = on; 6083 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 6084 .setUid(callingUid) 6085 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch") 6086 .set(MediaMetrics.Property.REQUEST, on 6087 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 6088 .record(); 6089 setMicrophoneMuteNoCallerCheck(UserHandle.getCallingUserId()); 6090 } 6091 setMicMuteFromSwitchInput()6092 private void setMicMuteFromSwitchInput() { 6093 InputManager im = mContext.getSystemService(InputManager.class); 6094 final int isMicMuted = im.isMicMuted(); 6095 if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) { 6096 setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF); 6097 } 6098 } 6099 6100 /** 6101 * Returns the microphone mute state as seen from the native audio system 6102 * @return true if microphone is reported as muted by primary HAL 6103 */ isMicrophoneMuted()6104 public boolean isMicrophoneMuted() { 6105 return mMicMuteFromSystemCached 6106 && (!mMicMuteFromPrivacyToggle 6107 || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch); 6108 } 6109 isMicrophoneSupposedToBeMuted()6110 private boolean isMicrophoneSupposedToBeMuted() { 6111 return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi 6112 || mMicMuteFromPrivacyToggle; 6113 } 6114 setMicrophoneMuteNoCallerCheck(int userId)6115 private void setMicrophoneMuteNoCallerCheck(int userId) { 6116 final boolean muted = isMicrophoneSupposedToBeMuted(); 6117 if (DEBUG_VOL) { 6118 Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId)); 6119 } 6120 // only mute for the current user or for the system user. 6121 if (getCurrentUserId() == userId || userId == UserHandle.USER_SYSTEM) { 6122 final boolean currentMute = mAudioSystem.isMicrophoneMuted(); 6123 int callingUid = Binder.getCallingUid(); 6124 final long identity = Binder.clearCallingIdentity(); 6125 try { 6126 final int ret = mAudioSystem.muteMicrophone(muted); 6127 6128 // update cache with the real state independently from what was set 6129 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); 6130 if (ret != AudioSystem.AUDIO_STATUS_OK) { 6131 Log.e(TAG, "Error changing mic mute state to " + muted + " current:" 6132 + mMicMuteFromSystemCached); 6133 } 6134 6135 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC) 6136 .setUid(callingUid) 6137 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck") 6138 .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached 6139 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 6140 .set(MediaMetrics.Property.REQUEST, muted 6141 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE) 6142 .set(MediaMetrics.Property.STATUS, ret) 6143 .record(); 6144 6145 // send the intent even if there was a failure to change the actual mute state: 6146 // the AudioManager.setMicrophoneMute API doesn't have a return value to 6147 // indicate if the call failed to successfully change the mute state, and receiving 6148 // the intent may be the only time an application can resynchronize its mic mute 6149 // state with the actual system mic mute state 6150 if (muted != currentMute) { 6151 sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE, 6152 SENDMSG_NOOP, 0, 0, null, 0); 6153 } 6154 } finally { 6155 Binder.restoreCallingIdentity(identity); 6156 } 6157 } 6158 } 6159 6160 @Override getRingerModeExternal()6161 public int getRingerModeExternal() { 6162 synchronized(mSettingsLock) { 6163 return mRingerModeExternal; 6164 } 6165 } 6166 6167 @Override getRingerModeInternal()6168 public int getRingerModeInternal() { 6169 synchronized(mSettingsLock) { 6170 return mRingerMode; 6171 } 6172 } 6173 ensureValidRingerMode(int ringerMode)6174 private void ensureValidRingerMode(int ringerMode) { 6175 if (!isValidRingerMode(ringerMode)) { 6176 throw new IllegalArgumentException("Bad ringer mode " + ringerMode); 6177 } 6178 } 6179 6180 /** @see AudioManager#isValidRingerMode(int) */ isValidRingerMode(int ringerMode)6181 public boolean isValidRingerMode(int ringerMode) { 6182 return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; 6183 } 6184 setRingerModeExternal(int ringerMode, String caller)6185 public void setRingerModeExternal(int ringerMode, String caller) { 6186 if (mHardeningEnforcer.blockVolumeMethod( 6187 HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_RINGER_MODE, 6188 getPackageNameForUid(Binder.getCallingUid()), 6189 Binder.getCallingUid())) { 6190 return; 6191 } 6192 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 6193 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) { 6194 throw new SecurityException("Not allowed to change Do Not Disturb state"); 6195 } 6196 6197 setRingerMode(ringerMode, caller, true /*external*/); 6198 } 6199 setRingerModeInternal(int ringerMode, String caller)6200 public void setRingerModeInternal(int ringerMode, String caller) { 6201 enforceVolumeController("setRingerModeInternal"); 6202 setRingerMode(ringerMode, caller, false /*external*/); 6203 } 6204 silenceRingerModeInternal(String reason)6205 public void silenceRingerModeInternal(String reason) { 6206 VibrationEffect effect = null; 6207 int ringerMode = AudioManager.RINGER_MODE_SILENT; 6208 int toastText = 0; 6209 6210 int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF; 6211 if (mContext.getResources() 6212 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { 6213 silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver, 6214 Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, 6215 UserHandle.USER_CURRENT); 6216 } 6217 6218 switch(silenceRingerSetting) { 6219 case VOLUME_HUSH_MUTE: 6220 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); 6221 ringerMode = AudioManager.RINGER_MODE_SILENT; 6222 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent; 6223 break; 6224 case VOLUME_HUSH_VIBRATE: 6225 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); 6226 ringerMode = AudioManager.RINGER_MODE_VIBRATE; 6227 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate; 6228 break; 6229 } 6230 maybeVibrate(effect, reason); 6231 setRingerModeInternal(ringerMode, reason); 6232 Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show(); 6233 } 6234 maybeVibrate(VibrationEffect effect, String reason)6235 private boolean maybeVibrate(VibrationEffect effect, String reason) { 6236 if (!mHasVibrator) { 6237 return false; 6238 } 6239 if (effect == null) { 6240 return false; 6241 } 6242 mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect, 6243 reason, TOUCH_VIBRATION_ATTRIBUTES); 6244 return true; 6245 } 6246 setRingerMode(int ringerMode, String caller, boolean external)6247 private void setRingerMode(int ringerMode, String caller, boolean external) { 6248 if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) { 6249 return; 6250 } 6251 if (caller == null || caller.length() == 0) { 6252 throw new IllegalArgumentException("Bad caller: " + caller); 6253 } 6254 ensureValidRingerMode(ringerMode); 6255 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 6256 ringerMode = AudioManager.RINGER_MODE_SILENT; 6257 } 6258 final long identity = Binder.clearCallingIdentity(); 6259 try { 6260 synchronized (mSettingsLock) { 6261 final int ringerModeInternal = getRingerModeInternal(); 6262 final int ringerModeExternal = getRingerModeExternal(); 6263 if (external) { 6264 setRingerModeExt(ringerMode); 6265 if (mRingerModeDelegate != null) { 6266 ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, 6267 ringerMode, caller, ringerModeInternal, mVolumePolicy); 6268 } 6269 if (ringerMode != ringerModeInternal) { 6270 setRingerModeInt(ringerMode, true /*persist*/); 6271 } 6272 } else /*internal*/ { 6273 if (ringerMode != ringerModeInternal) { 6274 setRingerModeInt(ringerMode, true /*persist*/); 6275 } 6276 if (mRingerModeDelegate != null) { 6277 ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, 6278 ringerMode, caller, ringerModeExternal, mVolumePolicy); 6279 } 6280 setRingerModeExt(ringerMode); 6281 } 6282 } 6283 } finally { 6284 Binder.restoreCallingIdentity(identity); 6285 } 6286 } 6287 setRingerModeExt(int ringerMode)6288 private void setRingerModeExt(int ringerMode) { 6289 synchronized(mSettingsLock) { 6290 if (ringerMode == mRingerModeExternal) return; 6291 mRingerModeExternal = ringerMode; 6292 } 6293 // Send sticky broadcast 6294 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode); 6295 } 6296 6297 @GuardedBy("mSettingsLock") muteRingerModeStreams()6298 private void muteRingerModeStreams() { 6299 // Mute stream if not previously muted by ringer mode and (ringer mode 6300 // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. 6301 // Unmute stream if previously muted by ringer/zen mode and ringer mode 6302 // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. 6303 int numStreamTypes = AudioSystem.getNumStreamTypes(); 6304 6305 if (mNm == null) { 6306 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 6307 } 6308 6309 final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic 6310 final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE 6311 || ringerMode == AudioManager.RINGER_MODE_SILENT; 6312 final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE 6313 && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO; 6314 final boolean shouldRingBle = ringerMode == AudioManager.RINGER_MODE_VIBRATE 6315 && (mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_BLE_HEADSET 6316 || mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER); 6317 // Ask audio policy engine to force use Bluetooth SCO/BLE channel if needed 6318 final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() 6319 + "/" + Binder.getCallingPid(); 6320 int forceUse = AudioSystem.FORCE_NONE; 6321 if (shouldRingSco) { 6322 forceUse = AudioSystem.FORCE_BT_SCO; 6323 } else if (shouldRingBle) { 6324 forceUse = AudioSystem.FORCE_BT_BLE; 6325 } 6326 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING, 6327 forceUse, eventSource, 0); 6328 6329 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 6330 final VolumeStreamState vss = getVssForStream(streamType); 6331 if (vss == null) { 6332 continue; 6333 } 6334 final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType); 6335 final boolean muteAllowedBySco = 6336 !((shouldRingSco || shouldRingBle) && streamType == AudioSystem.STREAM_RING); 6337 final boolean shouldZenMute = isStreamAffectedByCurrentZen(streamType); 6338 final boolean shouldMute = shouldZenMute || (ringerModeMute 6339 && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco); 6340 if (isMuted == shouldMute) continue; 6341 if (!shouldMute) { 6342 // unmute 6343 // ring and notifications volume should never be 0 when not silenced 6344 if (sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_RING 6345 || sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_NOTIFICATION) { 6346 synchronized (mVolumeStateLock) { 6347 for (int i = 0; i < vss.mIndexMap.size(); i++) { 6348 int device = vss.mIndexMap.keyAt(i); 6349 int value = vss.mIndexMap.valueAt(i); 6350 if (value == 0) { 6351 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/); 6352 } 6353 } 6354 // Persist volume for stream ring when it is changed here 6355 final int device = getDeviceForStream(streamType); 6356 sendMsg(mAudioHandler, 6357 MSG_PERSIST_VOLUME, 6358 SENDMSG_QUEUE, 6359 device, 6360 0, 6361 vss, 6362 PERSIST_DELAY); 6363 } 6364 } 6365 sRingerAndZenModeMutedStreams &= ~(1 << streamType); 6366 vss.mute(false, "muteRingerModeStreams"); 6367 } else { 6368 // mute 6369 sRingerAndZenModeMutedStreams |= (1 << streamType); 6370 vss.mute(true, "muteRingerModeStreams"); 6371 } 6372 } 6373 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( 6374 sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); 6375 } 6376 isAlarm(int streamType)6377 private boolean isAlarm(int streamType) { 6378 return streamType == AudioSystem.STREAM_ALARM; 6379 } 6380 isNotificationOrRinger(int streamType)6381 private boolean isNotificationOrRinger(int streamType) { 6382 return streamType == AudioSystem.STREAM_NOTIFICATION 6383 || streamType == AudioSystem.STREAM_RING; 6384 } 6385 isMedia(int streamType)6386 private boolean isMedia(int streamType) { 6387 return streamType == AudioSystem.STREAM_MUSIC; 6388 } 6389 6390 isSystem(int streamType)6391 private boolean isSystem(int streamType) { 6392 return streamType == AudioSystem.STREAM_SYSTEM; 6393 } 6394 setRingerModeInt(int ringerMode, boolean persist)6395 private void setRingerModeInt(int ringerMode, boolean persist) { 6396 final boolean change; 6397 synchronized(mSettingsLock) { 6398 change = mRingerMode != ringerMode; 6399 mRingerMode = ringerMode; 6400 muteRingerModeStreams(); 6401 } 6402 6403 // Post a persist ringer mode msg 6404 if (persist) { 6405 sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, 6406 SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY); 6407 } 6408 if (change) { 6409 // Send sticky broadcast 6410 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode); 6411 } 6412 } 6413 postUpdateRingerModeServiceInt()6414 /*package*/ void postUpdateRingerModeServiceInt() { 6415 sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0); 6416 } 6417 onUpdateRingerModeServiceInt()6418 private void onUpdateRingerModeServiceInt() { 6419 setRingerModeInt(getRingerModeInternal(), false); 6420 } 6421 6422 /** @see AudioManager#shouldVibrate(int) */ shouldVibrate(int vibrateType)6423 public boolean shouldVibrate(int vibrateType) { 6424 if (!mHasVibrator) return false; 6425 6426 switch (getVibrateSetting(vibrateType)) { 6427 6428 case AudioManager.VIBRATE_SETTING_ON: 6429 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT; 6430 6431 case AudioManager.VIBRATE_SETTING_ONLY_SILENT: 6432 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE; 6433 6434 case AudioManager.VIBRATE_SETTING_OFF: 6435 // return false, even for incoming calls 6436 return false; 6437 6438 default: 6439 return false; 6440 } 6441 } 6442 6443 /** @see AudioManager#getVibrateSetting(int) */ getVibrateSetting(int vibrateType)6444 public int getVibrateSetting(int vibrateType) { 6445 if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF; 6446 return (mVibrateSetting >> (vibrateType * 2)) & 3; 6447 } 6448 6449 /** @see AudioManager#setVibrateSetting(int, int) */ setVibrateSetting(int vibrateType, int vibrateSetting)6450 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 6451 6452 if (!mHasVibrator) return; 6453 6454 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType, 6455 vibrateSetting); 6456 6457 // Broadcast change 6458 broadcastVibrateSetting(vibrateType); 6459 6460 } 6461 6462 private class SetModeDeathHandler implements IBinder.DeathRecipient { 6463 private final IBinder mCb; // To be notified of client's death 6464 private final int mPid; 6465 private final int mUid; 6466 private final boolean mIsPrivileged; 6467 private final String mPackage; 6468 private int mMode; 6469 private long mUpdateTime; 6470 private boolean mPlaybackActive = false; 6471 private boolean mRecordingActive = false; 6472 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)6473 SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, 6474 String caller, int mode) { 6475 mMode = mode; 6476 mCb = cb; 6477 mPid = pid; 6478 mUid = uid; 6479 mPackage = caller; 6480 mIsPrivileged = isPrivileged; 6481 mUpdateTime = java.lang.System.currentTimeMillis(); 6482 } 6483 binderDied()6484 public void binderDied() { 6485 synchronized (mDeviceBroker.mSetModeLock) { 6486 Log.w(TAG, "SetModeDeathHandler client died"); 6487 int index = mSetModeDeathHandlers.indexOf(this); 6488 if (index < 0) { 6489 Log.w(TAG, "unregistered SetModeDeathHandler client died"); 6490 } else { 6491 SetModeDeathHandler h = mSetModeDeathHandlers.get(index); 6492 mSetModeDeathHandlers.remove(index); 6493 postUpdateAudioMode(SENDMSG_QUEUE, AudioSystem.MODE_CURRENT, 6494 android.os.Process.myPid(), mContext.getPackageName(), 6495 false /*signal*/, 0); 6496 } 6497 } 6498 } 6499 getPid()6500 public int getPid() { 6501 return mPid; 6502 } 6503 setMode(int mode)6504 public void setMode(int mode) { 6505 mMode = mode; 6506 mUpdateTime = java.lang.System.currentTimeMillis(); 6507 } 6508 getMode()6509 public int getMode() { 6510 return mMode; 6511 } 6512 getBinder()6513 public IBinder getBinder() { 6514 return mCb; 6515 } 6516 getUid()6517 public int getUid() { 6518 return mUid; 6519 } 6520 getPackage()6521 public String getPackage() { 6522 return mPackage; 6523 } 6524 isPrivileged()6525 public boolean isPrivileged() { 6526 return mIsPrivileged; 6527 } 6528 getUpdateTime()6529 public long getUpdateTime() { 6530 return mUpdateTime; 6531 } 6532 setPlaybackActive(boolean active)6533 public void setPlaybackActive(boolean active) { 6534 mPlaybackActive = active; 6535 } 6536 setRecordingActive(boolean active)6537 public void setRecordingActive(boolean active) { 6538 mRecordingActive = active; 6539 } 6540 6541 /** 6542 * An app is considered active if: 6543 * - It is privileged (has MODIFY_PHONE_STATE permission) 6544 * or 6545 * - It requests mode MODE_IN_COMMUNICATION, and it is either playing 6546 * or recording for VOICE_COMMUNICATION. 6547 * or 6548 * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL 6549 * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT 6550 * or MODE_COMMUNICATION_REDIRECT. 6551 */ isActive()6552 public boolean isActive() { 6553 return mIsPrivileged 6554 || ((mMode == AudioSystem.MODE_IN_COMMUNICATION) 6555 && (mRecordingActive || mPlaybackActive)) 6556 || mMode == AudioSystem.MODE_RINGTONE 6557 || mMode == AudioSystem.MODE_CALL_SCREENING; 6558 } 6559 dump(PrintWriter pw, int index)6560 public void dump(PrintWriter pw, int index) { 6561 SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); 6562 6563 if (index >= 0) { 6564 pw.println(" Requester # " + (index + 1) + ":"); 6565 } 6566 pw.println(" - Mode: " + AudioSystem.modeToString(mMode)); 6567 pw.println(" - Binder: " + mCb); 6568 pw.println(" - Pid: " + mPid); 6569 pw.println(" - Uid: " + mUid); 6570 pw.println(" - Package: " + mPackage); 6571 pw.println(" - Privileged: " + mIsPrivileged); 6572 pw.println(" - Active: " + isActive()); 6573 pw.println(" Playback active: " + mPlaybackActive); 6574 pw.println(" Recording active: " + mRecordingActive); 6575 pw.println(" - update time: " + format.format(new Date(mUpdateTime))); 6576 } 6577 } 6578 6579 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwnerHandler()6580 private SetModeDeathHandler getAudioModeOwnerHandler() { 6581 // The Audio mode owner is: 6582 // 1) the most recent privileged app in the stack 6583 // 2) the most recent active app in the tack 6584 SetModeDeathHandler modeOwner = null; 6585 SetModeDeathHandler privilegedModeOwner = null; 6586 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 6587 if (h.isActive()) { 6588 // privileged apps are always active 6589 if (h.isPrivileged()) { 6590 if (privilegedModeOwner == null 6591 || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) { 6592 privilegedModeOwner = h; 6593 } 6594 } else { 6595 if (modeOwner == null 6596 || h.getUpdateTime() > modeOwner.getUpdateTime()) { 6597 modeOwner = h; 6598 } 6599 } 6600 } 6601 } 6602 return privilegedModeOwner != null ? privilegedModeOwner : modeOwner; 6603 } 6604 6605 /** 6606 * Return information on the current audio mode owner 6607 * @return 0 if nobody owns the mode 6608 */ 6609 @GuardedBy("mDeviceBroker.mSetModeLock") getAudioModeOwner()6610 /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() { 6611 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 6612 if (hdlr != null) { 6613 return new AudioDeviceBroker.AudioModeInfo( 6614 hdlr.getMode(), hdlr.getPid(), hdlr.getUid()); 6615 } 6616 return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0); 6617 } 6618 6619 /** 6620 * Return the uid of the current audio mode owner 6621 * @return 0 if nobody owns the mode 6622 */ 6623 @GuardedBy("mDeviceBroker.mSetModeLock") getModeOwnerUid()6624 /*package*/ int getModeOwnerUid() { 6625 SetModeDeathHandler hdlr = getAudioModeOwnerHandler(); 6626 if (hdlr != null) { 6627 return hdlr.getUid(); 6628 } 6629 return 0; 6630 } 6631 6632 /** @see AudioManager#setMode(int) */ setMode(int mode, IBinder cb, String callingPackage)6633 public void setMode(int mode, IBinder cb, String callingPackage) { 6634 int pid = Binder.getCallingPid(); 6635 int uid = Binder.getCallingUid(); 6636 if (DEBUG_MODE) { 6637 Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid 6638 + ", uid=" + uid + ", caller=" + callingPackage + ")"); 6639 } 6640 if (!checkAudioSettingsPermission("setMode()")) { 6641 return; 6642 } 6643 if (cb == null) { 6644 Log.e(TAG, "setMode() called with null binder"); 6645 return; 6646 } 6647 if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { 6648 Log.w(TAG, "setMode() invalid mode: " + mode); 6649 return; 6650 } 6651 6652 if (mode == AudioSystem.MODE_CURRENT) { 6653 mode = getMode(); 6654 } 6655 6656 if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) { 6657 Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted " 6658 + "when call screening is not supported"); 6659 return; 6660 } 6661 6662 final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission( 6663 MODIFY_PHONE_STATE) 6664 == PackageManager.PERMISSION_GRANTED; 6665 if ((mode == AudioSystem.MODE_IN_CALL 6666 || mode == AudioSystem.MODE_CALL_REDIRECT 6667 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT) 6668 && !hasModifyPhoneStatePermission) { 6669 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(" 6670 + AudioSystem.modeToString(mode) + ") from pid=" + pid 6671 + ", uid=" + Binder.getCallingUid()); 6672 return; 6673 } 6674 6675 SetModeDeathHandler currentModeHandler = null; 6676 synchronized (mDeviceBroker.mSetModeLock) { 6677 for (SetModeDeathHandler h : mSetModeDeathHandlers) { 6678 if (h.getPid() == pid) { 6679 currentModeHandler = h; 6680 break; 6681 } 6682 } 6683 6684 if (mode == AudioSystem.MODE_NORMAL) { 6685 if (currentModeHandler != null) { 6686 if (!currentModeHandler.isPrivileged() 6687 && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) { 6688 mAudioHandler.removeEqualMessages( 6689 MSG_CHECK_MODE_FOR_UID, currentModeHandler); 6690 } 6691 mSetModeDeathHandlers.remove(currentModeHandler); 6692 if (DEBUG_MODE) { 6693 Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid); 6694 } 6695 try { 6696 currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0); 6697 } catch (NoSuchElementException e) { 6698 Log.w(TAG, "setMode link does not exist ..."); 6699 } 6700 } 6701 } else { 6702 if (currentModeHandler != null) { 6703 currentModeHandler.setMode(mode); 6704 if (DEBUG_MODE) { 6705 Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid); 6706 } 6707 } else { 6708 currentModeHandler = new SetModeDeathHandler(cb, pid, uid, 6709 hasModifyPhoneStatePermission, callingPackage, mode); 6710 // Register for client death notification 6711 try { 6712 cb.linkToDeath(currentModeHandler, 0); 6713 } catch (RemoteException e) { 6714 // Client has died! 6715 Log.w(TAG, "setMode() could not link to " + cb + " binder death"); 6716 return; 6717 } 6718 mSetModeDeathHandlers.add(currentModeHandler); 6719 if (DEBUG_MODE) { 6720 Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid); 6721 } 6722 } 6723 if (mode == AudioSystem.MODE_IN_COMMUNICATION) { 6724 // Force active state when entering/updating the stack to avoid glitches when 6725 // an app starts playing/recording after settng the audio mode, 6726 // and send a reminder to check activity after a grace period. 6727 if (!currentModeHandler.isPrivileged()) { 6728 currentModeHandler.setPlaybackActive(true); 6729 currentModeHandler.setRecordingActive(true); 6730 sendMsg(mAudioHandler, 6731 MSG_CHECK_MODE_FOR_UID, 6732 SENDMSG_QUEUE, 6733 0, 6734 0, 6735 currentModeHandler, 6736 CHECK_MODE_FOR_UID_PERIOD_MS); 6737 } 6738 } 6739 } 6740 6741 postUpdateAudioMode(SENDMSG_REPLACE, mode, pid, callingPackage, 6742 hasModifyPhoneStatePermission && mode == AudioSystem.MODE_NORMAL, 0); 6743 } 6744 } 6745 6746 @GuardedBy("mDeviceBroker.mSetModeLock") onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force, boolean signal)6747 void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, 6748 boolean force, boolean signal) { 6749 if (requestedMode == AudioSystem.MODE_CURRENT) { 6750 requestedMode = getMode(); 6751 } 6752 int mode = AudioSystem.MODE_NORMAL; 6753 int uid = 0; 6754 int pid = 0; 6755 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 6756 if (currentModeHandler != null) { 6757 mode = currentModeHandler.getMode(); 6758 uid = currentModeHandler.getUid(); 6759 pid = currentModeHandler.getPid(); 6760 } 6761 if (DEBUG_MODE) { 6762 Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: " 6763 + mMode.get() + " requested mode: " + requestedMode + " signal: " + signal); 6764 } 6765 if (mode != mMode.get() || force) { 6766 int status = AudioSystem.SUCCESS; 6767 final long identity = Binder.clearCallingIdentity(); 6768 try { 6769 status = mAudioSystem.setPhoneState(mode, uid); 6770 } finally { 6771 Binder.restoreCallingIdentity(identity); 6772 } 6773 if (status == AudioSystem.AUDIO_STATUS_OK) { 6774 if (DEBUG_MODE) { 6775 Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode); 6776 } 6777 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0, 6778 /*obj*/ null, /*delay*/ 0); 6779 int previousMode = mMode.getAndSet(mode); 6780 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL 6781 mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid, 6782 requestedMode, pid, mode)); 6783 6784 final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); 6785 final int device = getDeviceForStream(streamType); 6786 final int streamAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/ 6787 -1); 6788 if (streamAlias == -1) { 6789 Log.e(TAG, 6790 "onUpdateAudioMode: no stream vol alias for stream type " + streamType); 6791 } 6792 6793 if (DEBUG_MODE) { 6794 Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType 6795 + ", streamAlias=" + streamAlias); 6796 } 6797 6798 final int index = getVssForStreamOrDefault(streamAlias).getIndex(device); 6799 setStreamVolumeInt(streamAlias, index, device, true, 6800 requesterPackage, true /*hasModifyAudioSettings*/); 6801 6802 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage); 6803 6804 // change of mode may require volume to be re-applied on some devices 6805 onUpdateContextualVolumes(); 6806 6807 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO 6808 // connections not started by the application changing the mode when pid changes 6809 mDeviceBroker.postSetModeOwner(mode, pid, uid, signal); 6810 } else { 6811 // reset here to avoid sticky out of sync condition (would have been reset 6812 // by AudioDeviceBroker processing MSG_L_SET_MODE_OWNER_SIGNAL message) 6813 resetAudioModeResetCount(); 6814 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode); 6815 } 6816 } 6817 } 6818 6819 /** @see AudioManager#getMode() */ getMode()6820 public int getMode() { 6821 synchronized (mDeviceBroker.mSetModeLock) { 6822 SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler(); 6823 if (currentModeHandler != null) { 6824 return currentModeHandler.getMode(); 6825 } 6826 return AudioSystem.MODE_NORMAL; 6827 } 6828 } 6829 6830 /** cached value read from audiopolicy manager after initialization. */ 6831 private boolean mIsCallScreeningModeSupported = false; 6832 6833 /** @see AudioManager#isCallScreeningModeSupported() */ isCallScreeningModeSupported()6834 public boolean isCallScreeningModeSupported() { 6835 return mIsCallScreeningModeSupported; 6836 } 6837 dispatchMode(int mode)6838 protected void dispatchMode(int mode) { 6839 final int nbDispatchers = mModeDispatchers.beginBroadcast(); 6840 for (int i = 0; i < nbDispatchers; i++) { 6841 try { 6842 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode); 6843 } catch (RemoteException e) { 6844 } 6845 } 6846 mModeDispatchers.finishBroadcast(); 6847 } 6848 6849 final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers = 6850 new RemoteCallbackList<IAudioModeDispatcher>(); 6851 6852 /** 6853 * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)} 6854 * @param dispatcher 6855 */ registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6856 public void registerModeDispatcher( 6857 @NonNull IAudioModeDispatcher dispatcher) { 6858 mModeDispatchers.register(dispatcher); 6859 } 6860 6861 /** 6862 * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)} 6863 * @param dispatcher 6864 */ unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6865 public void unregisterModeDispatcher( 6866 @NonNull IAudioModeDispatcher dispatcher) { 6867 mModeDispatchers.unregister(dispatcher); 6868 } 6869 6870 @android.annotation.EnforcePermission(CALL_AUDIO_INTERCEPTION) 6871 /** @see AudioManager#isPstnCallAudioInterceptable() */ isPstnCallAudioInterceptable()6872 public boolean isPstnCallAudioInterceptable() { 6873 6874 super.isPstnCallAudioInterceptable_enforcePermission(); 6875 6876 boolean uplinkDeviceFound = false; 6877 boolean downlinkDeviceFound = false; 6878 AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL); 6879 for (AudioDeviceInfo device : devices) { 6880 if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) { 6881 uplinkDeviceFound = true; 6882 } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) { 6883 downlinkDeviceFound = true; 6884 } 6885 if (uplinkDeviceFound && downlinkDeviceFound) { 6886 return true; 6887 } 6888 } 6889 return false; 6890 } 6891 6892 /** @see AudioManager#setRttEnabled(boolean) */ 6893 @Override setRttEnabled(boolean rttEnabled)6894 public void setRttEnabled(boolean rttEnabled) { 6895 if (mContext.checkCallingOrSelfPermission( 6896 MODIFY_PHONE_STATE) 6897 != PackageManager.PERMISSION_GRANTED) { 6898 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid=" 6899 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 6900 return; 6901 } 6902 synchronized (this) { 6903 mRttEnabled.set(rttEnabled); 6904 final long identity = Binder.clearCallingIdentity(); 6905 try { 6906 AudioSystem.setRttEnabled(rttEnabled); 6907 } finally { 6908 Binder.restoreCallingIdentity(identity); 6909 } 6910 } 6911 } 6912 6913 @VisibleForTesting(visibility = PACKAGE) isRttEnabled()6914 protected boolean isRttEnabled() { 6915 return mRttEnabled.get(); 6916 } 6917 6918 /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */ 6919 @Override adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6920 public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, 6921 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6922 int targetSdkVersion) { 6923 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6924 throw new SecurityException("Should only be called from system process"); 6925 } 6926 6927 // direction and stream type swap here because the public 6928 // adjustSuggested has a different order than the other methods. 6929 adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, 6930 uid, pid, hasAudioSettingsPermission(uid, pid), 6931 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 6932 } 6933 6934 /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */ 6935 @Override adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6936 public void adjustStreamVolumeForUid(int streamType, int direction, int flags, 6937 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6938 int targetSdkVersion) { 6939 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6940 throw new SecurityException("Should only be called from system process"); 6941 } 6942 6943 if (direction != AudioManager.ADJUST_SAME) { 6944 sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, 6945 direction/*val1*/, flags/*val2*/, 6946 new StringBuilder(packageName).append(" uid:").append(uid) 6947 .toString())); 6948 } 6949 6950 adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid, 6951 null, hasAudioSettingsPermission(uid, pid), 6952 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL); 6953 } 6954 6955 /** 6956 * @see AudioManager#adjustVolume(int, int) 6957 * This method is redirected from AudioManager to AudioService for API hardening rules 6958 * enforcement then to MediaSession for implementation. 6959 */ 6960 @Override adjustVolume(int direction, int flags)6961 public void adjustVolume(int direction, int flags) { 6962 if (mHardeningEnforcer.blockVolumeMethod( 6963 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_VOLUME, 6964 getPackageNameForUid(Binder.getCallingUid()), 6965 Binder.getCallingUid())) { 6966 return; 6967 } 6968 getMediaSessionManager().dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, 6969 direction, flags); 6970 } 6971 6972 /** 6973 * @see AudioManager#adjustSuggestedStreamVolume(int, int, int) 6974 * This method is redirected from AudioManager to AudioService for API hardening rules 6975 * enforcement then to MediaSession for implementation. 6976 */ 6977 @Override adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags)6978 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) { 6979 if (mHardeningEnforcer.blockVolumeMethod( 6980 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_SUGGESTED_STREAM_VOLUME, 6981 getPackageNameForUid(Binder.getCallingUid()), 6982 Binder.getCallingUid())) { 6983 return; 6984 } 6985 getMediaSessionManager().dispatchAdjustVolume(suggestedStreamType, direction, flags); 6986 } 6987 6988 /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ 6989 @Override setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6990 public void setStreamVolumeForUid(int streamType, int index, int flags, 6991 @NonNull String packageName, int uid, int pid, UserHandle userHandle, 6992 int targetSdkVersion) { 6993 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 6994 throw new SecurityException("Should only be called from system process"); 6995 } 6996 6997 setStreamVolume(streamType, index, flags, /*device*/ null, 6998 packageName, packageName, null, uid, 6999 hasAudioSettingsPermission(uid, pid), 7000 true /*canChangeMuteAndUpdateController*/); 7001 } 7002 7003 //========================================================================================== 7004 // Sound Effects 7005 //========================================================================================== 7006 private static final class LoadSoundEffectReply 7007 implements SoundEffectsHelper.OnEffectsLoadCompleteHandler { 7008 private static final int SOUND_EFFECTS_LOADING = 1; 7009 private static final int SOUND_EFFECTS_LOADED = 0; 7010 private static final int SOUND_EFFECTS_ERROR = -1; 7011 private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000; 7012 7013 private int mStatus = SOUND_EFFECTS_LOADING; 7014 7015 @Override run(boolean success)7016 public synchronized void run(boolean success) { 7017 mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR; 7018 notify(); 7019 } 7020 waitForLoaded(int attempts)7021 public synchronized boolean waitForLoaded(int attempts) { 7022 while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) { 7023 try { 7024 wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 7025 } catch (InterruptedException e) { 7026 Log.w(TAG, "Interrupted while waiting sound pool loaded."); 7027 } 7028 } 7029 return mStatus == SOUND_EFFECTS_LOADED; 7030 } 7031 } 7032 7033 /** @see AudioManager#playSoundEffect(int, int) */ playSoundEffect(int effectType, int userId)7034 public void playSoundEffect(int effectType, int userId) { 7035 if (querySoundEffectsEnabled(userId)) { 7036 playSoundEffectVolume(effectType, -1.0f); 7037 } 7038 } 7039 7040 /** 7041 * Settings has an in memory cache, so this is fast. 7042 */ querySoundEffectsEnabled(int user)7043 private boolean querySoundEffectsEnabled(int user) { 7044 return mSettings.getSystemIntForUser(getContentResolver(), 7045 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0; 7046 } 7047 7048 /** @see AudioManager#playSoundEffect(int, float) */ playSoundEffectVolume(int effectType, float volume)7049 public void playSoundEffectVolume(int effectType, float volume) { 7050 // do not try to play the sound effect if the system stream is muted 7051 if (isStreamMute(STREAM_SYSTEM)) { 7052 return; 7053 } 7054 7055 if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { 7056 Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); 7057 return; 7058 } 7059 7060 sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE, 7061 effectType, (int) (volume * 1000), null, 0); 7062 } 7063 7064 /** 7065 * Loads samples into the soundpool. 7066 * This method must be called at first when sound effects are enabled 7067 */ loadSoundEffects()7068 public boolean loadSoundEffects() { 7069 LoadSoundEffectReply reply = new LoadSoundEffectReply(); 7070 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0); 7071 return reply.waitForLoaded(3 /*attempts*/); 7072 } 7073 7074 /** 7075 * Schedule loading samples into the soundpool. 7076 * This method can be overridden to schedule loading at a later time. 7077 */ scheduleLoadSoundEffects()7078 protected void scheduleLoadSoundEffects() { 7079 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 7080 } 7081 7082 /** 7083 * Unloads samples from the sound pool. 7084 * This method can be called to free some memory when 7085 * sound effects are disabled. 7086 */ unloadSoundEffects()7087 public void unloadSoundEffects() { 7088 sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 7089 } 7090 7091 /** @see AudioManager#reloadAudioSettings() */ reloadAudioSettings()7092 public void reloadAudioSettings() { 7093 readAudioSettings(false /*userSwitch*/); 7094 } 7095 readAudioSettings(boolean userSwitch)7096 private void readAudioSettings(boolean userSwitch) { 7097 // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings 7098 readPersistedSettings(); 7099 readUserRestrictions(); 7100 7101 // restore volume settings 7102 int numStreamTypes = AudioSystem.getNumStreamTypes(); 7103 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 7104 final VolumeStreamState streamState = getVssForStream(streamType); 7105 7106 if (streamState == null) { 7107 continue; 7108 } 7109 7110 if (userSwitch && sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_MUSIC) { 7111 continue; 7112 } 7113 7114 streamState.readSettings(); 7115 synchronized (mVolumeStateLock) { 7116 // unmute stream that was muted but is not affect by mute anymore 7117 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && 7118 !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) { 7119 streamState.mIsMuted = false; 7120 } 7121 } 7122 if (cacheGetStreamVolume()) { 7123 if (DEBUG_VOL) { 7124 Log.d(TAG, 7125 "Clear volume cache after possibly changing mute in readAudioSettings"); 7126 } 7127 AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API); 7128 } 7129 } 7130 7131 readVolumeGroupsSettings(userSwitch); 7132 7133 // apply new ringer mode before checking volume for alias streams so that streams 7134 // muted by ringer mode have the correct volume 7135 setRingerModeInt(getRingerModeInternal(), false); 7136 7137 checkAllFixedVolumeDevices(); 7138 checkAllAliasStreamVolumes(); 7139 checkMuteAffectedStreams(); 7140 7141 mSoundDoseHelper.restoreMusicActiveMs(); 7142 mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG); 7143 7144 if (DEBUG_VOL) { 7145 Log.d(TAG, "Restoring device volume behavior"); 7146 } 7147 restoreDeviceVolumeBehavior(); 7148 } 7149 7150 /** @see AudioManager#getAvailableCommunicationDevices(int) */ getAvailableCommunicationDeviceIds()7151 public int[] getAvailableCommunicationDeviceIds() { 7152 List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices(); 7153 return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray(); 7154 } 7155 7156 /** 7157 * @see AudioManager#setCommunicationDevice(int) 7158 * @see AudioManager#clearCommunicationDevice() 7159 */ setCommunicationDevice(IBinder cb, int portId, @NonNull AttributionSource attributionSource)7160 public boolean setCommunicationDevice(IBinder cb, int portId, 7161 @NonNull AttributionSource attributionSource) { 7162 if (attributionSource == null) { 7163 return false; 7164 } 7165 final int uid = attributionSource.getUid(); 7166 final int pid = attributionSource.getPid(); 7167 7168 AudioDeviceInfo device = null; 7169 if (portId != 0) { 7170 device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS); 7171 if (device == null) { 7172 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId); 7173 return false; 7174 } 7175 if (!AudioDeviceBroker.isValidCommunicationDevice(device)) { 7176 if (!device.isSink()) { 7177 throw new IllegalArgumentException("device must have sink role"); 7178 } else { 7179 throw new IllegalArgumentException("invalid device type: " + device.getType()); 7180 } 7181 } 7182 } 7183 final String eventSource = new StringBuilder() 7184 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(") 7185 .append(") from u/pid:").append(uid).append("/") 7186 .append(pid).toString(); 7187 7188 int deviceType = AudioSystem.DEVICE_OUT_DEFAULT; 7189 String deviceAddress = null; 7190 if (device != null) { 7191 deviceType = device.getPort().type(); 7192 deviceAddress = device.getAddress(); 7193 } else { 7194 AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice(); 7195 if (curDevice != null) { 7196 deviceType = curDevice.getPort().type(); 7197 deviceAddress = curDevice.getAddress(); 7198 } 7199 } 7200 // do not log metrics if clearing communication device while no communication device 7201 // was selected 7202 if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) { 7203 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 7204 + MediaMetrics.SEPARATOR + "setCommunicationDevice") 7205 .set(MediaMetrics.Property.DEVICE, 7206 AudioSystem.getDeviceName(deviceType)) 7207 .set(MediaMetrics.Property.ADDRESS, deviceAddress) 7208 .set(MediaMetrics.Property.STATE, device != null 7209 ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED) 7210 .record(); 7211 } 7212 final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 7213 == PackageManager.PERMISSION_GRANTED; 7214 final long ident = Binder.clearCallingIdentity(); 7215 try { 7216 return mDeviceBroker.setCommunicationDevice( 7217 cb, attributionSource, device, isPrivileged, eventSource); 7218 } finally { 7219 Binder.restoreCallingIdentity(ident); 7220 } 7221 } 7222 7223 /** @see AudioManager#getCommunicationDevice() */ getCommunicationDevice()7224 public int getCommunicationDevice() { 7225 int deviceId = 0; 7226 final long ident = Binder.clearCallingIdentity(); 7227 try { 7228 AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice(); 7229 deviceId = device != null ? device.getId() : 0; 7230 } finally { 7231 Binder.restoreCallingIdentity(ident); 7232 } 7233 return deviceId; 7234 } 7235 7236 /** @see AudioManager#addOnCommunicationDeviceChangedListener( 7237 * Executor, AudioManager.OnCommunicationDeviceChangedListener) 7238 */ registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)7239 public void registerCommunicationDeviceDispatcher( 7240 @Nullable ICommunicationDeviceDispatcher dispatcher) { 7241 if (dispatcher == null) { 7242 return; 7243 } 7244 mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher); 7245 } 7246 7247 /** @see AudioManager#removeOnCommunicationDeviceChangedListener( 7248 * AudioManager.OnCommunicationDeviceChangedListener) 7249 */ unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)7250 public void unregisterCommunicationDeviceDispatcher( 7251 @Nullable ICommunicationDeviceDispatcher dispatcher) { 7252 if (dispatcher == null) { 7253 return; 7254 } 7255 mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher); 7256 } 7257 7258 /** @see AudioManager#setSpeakerphoneOn(boolean) */ setSpeakerphoneOn(IBinder cb, boolean on, @NonNull AttributionSource attributionSource)7259 public void setSpeakerphoneOn(IBinder cb, boolean on, 7260 @NonNull AttributionSource attributionSource) { 7261 if (attributionSource == null) { 7262 return; 7263 } 7264 if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 7265 return; 7266 } 7267 final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 7268 == PackageManager.PERMISSION_GRANTED; 7269 7270 // for logging only 7271 final int uid = attributionSource.getUid(); 7272 final int pid = attributionSource.getPid(); 7273 7274 final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) 7275 .append(") from u/pid:").append(uid).append("/") 7276 .append(pid).toString(); 7277 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 7278 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn") 7279 .setUid(uid) 7280 .setPid(pid) 7281 .set(MediaMetrics.Property.STATE, on 7282 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 7283 .record(); 7284 7285 final long ident = Binder.clearCallingIdentity(); 7286 try { 7287 mDeviceBroker.setSpeakerphoneOn(cb, attributionSource, on, isPrivileged, eventSource); 7288 } finally { 7289 Binder.restoreCallingIdentity(ident); 7290 } 7291 } 7292 7293 /** @see AudioManager#isSpeakerphoneOn() */ isSpeakerphoneOn()7294 public boolean isSpeakerphoneOn() { 7295 return mDeviceBroker.isSpeakerphoneOn(); 7296 } 7297 7298 7299 /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn(). 7300 * @see isBluetoothScoOn() */ 7301 private boolean mBtScoOnByApp; 7302 7303 /** @see AudioManager#setBluetoothScoOn(boolean) */ setBluetoothScoOn(boolean on)7304 public void setBluetoothScoOn(boolean on) { 7305 if (!checkAudioSettingsPermission("setBluetoothScoOn()")) { 7306 return; 7307 } 7308 7309 // Only enable calls from system components 7310 if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) { 7311 mBtScoOnByApp = on; 7312 return; 7313 } 7314 7315 // for logging only 7316 final int uid = Binder.getCallingUid(); 7317 final int pid = Binder.getCallingPid(); 7318 final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on) 7319 .append(") from u/pid:").append(uid).append("/").append(pid).toString(); 7320 7321 //bt sco 7322 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 7323 + MediaMetrics.SEPARATOR + "setBluetoothScoOn") 7324 .setUid(uid) 7325 .setPid(pid) 7326 .set(MediaMetrics.Property.STATE, on 7327 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 7328 .record(); 7329 7330 mDeviceBroker.setBluetoothScoOn(on, eventSource); 7331 } 7332 7333 /** @see AudioManager#setA2dpSuspended(boolean) */ 7334 @android.annotation.EnforcePermission(BLUETOOTH_STACK) setA2dpSuspended(boolean enable)7335 public void setA2dpSuspended(boolean enable) { 7336 super.setA2dpSuspended_enforcePermission(); 7337 final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable) 7338 .append(") from u/pid:").append(Binder.getCallingUid()).append("/") 7339 .append(Binder.getCallingPid()).toString(); 7340 mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource); 7341 } 7342 7343 /** @see AudioManager#setA2dpSuspended(boolean) */ 7344 @android.annotation.EnforcePermission(BLUETOOTH_STACK) setLeAudioSuspended(boolean enable)7345 public void setLeAudioSuspended(boolean enable) { 7346 super.setLeAudioSuspended_enforcePermission(); 7347 final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable) 7348 .append(") from u/pid:").append(Binder.getCallingUid()).append("/") 7349 .append(Binder.getCallingPid()).toString(); 7350 mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource); 7351 } 7352 7353 /** @see AudioManager#isBluetoothScoOn() 7354 * Note that it doesn't report internal state, but state seen by apps (which may have 7355 * called setBluetoothScoOn() */ isBluetoothScoOn()7356 public boolean isBluetoothScoOn() { 7357 return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn(); 7358 } 7359 7360 // TODO investigate internal users due to deprecation of SDK API 7361 /** @see AudioManager#setBluetoothA2dpOn(boolean) */ setBluetoothA2dpOn(boolean on)7362 public void setBluetoothA2dpOn(boolean on) { 7363 if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) { 7364 return; 7365 } 7366 7367 // for logging only 7368 final int uid = Binder.getCallingUid(); 7369 final int pid = Binder.getCallingPid(); 7370 final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on) 7371 .append(") from u/pid:").append(uid).append("/") 7372 .append(pid).append(" src:AudioService.setBtA2dpOn").toString(); 7373 7374 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE 7375 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn") 7376 .setUid(uid) 7377 .setPid(pid) 7378 .set(MediaMetrics.Property.STATE, on 7379 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF) 7380 .record(); 7381 7382 mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource); 7383 } 7384 7385 /** @see AudioManager#isBluetoothA2dpOn() */ isBluetoothA2dpOn()7386 public boolean isBluetoothA2dpOn() { 7387 return mDeviceBroker.isBluetoothA2dpOn(); 7388 } 7389 7390 /** @see AudioManager#startBluetoothSco() */ startBluetoothSco(IBinder cb, int targetSdkVersion, @NonNull AttributionSource attributionSource)7391 public void startBluetoothSco(IBinder cb, int targetSdkVersion, 7392 @NonNull AttributionSource attributionSource) { 7393 if (attributionSource == null) { 7394 return; 7395 } 7396 if (!checkAudioSettingsPermission("startBluetoothSco()")) { 7397 return; 7398 } 7399 7400 final int uid = attributionSource.getUid(); 7401 final int pid = attributionSource.getPid(); 7402 final int scoAudioMode = 7403 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? 7404 BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED; 7405 final String eventSource = new StringBuilder("startBluetoothSco()") 7406 .append(") from u/pid:").append(uid).append("/") 7407 .append(pid).toString(); 7408 7409 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 7410 .setUid(uid) 7411 .setPid(pid) 7412 .set(MediaMetrics.Property.EVENT, "startBluetoothSco") 7413 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 7414 BtHelper.scoAudioModeToString(scoAudioMode)) 7415 .record(); 7416 startBluetoothScoInt(cb, attributionSource, scoAudioMode, eventSource); 7417 7418 } 7419 7420 /** @see AudioManager#startBluetoothScoVirtualCall() */ startBluetoothScoVirtualCall(IBinder cb, @NonNull AttributionSource attributionSource)7421 public void startBluetoothScoVirtualCall(IBinder cb, 7422 @NonNull AttributionSource attributionSource) { 7423 if (attributionSource == null) { 7424 return; 7425 } 7426 if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) { 7427 return; 7428 } 7429 7430 final int uid = attributionSource.getUid(); 7431 final int pid = attributionSource.getPid(); 7432 final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()") 7433 .append(") from u/pid:").append(uid).append("/") 7434 .append(pid).toString(); 7435 7436 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 7437 .setUid(uid) 7438 .setPid(pid) 7439 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall") 7440 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 7441 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL)) 7442 .record(); 7443 startBluetoothScoInt(cb, attributionSource, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource); 7444 } 7445 startBluetoothScoInt(IBinder cb, AttributionSource attributionSource, int scoAudioMode, @NonNull String eventSource)7446 void startBluetoothScoInt(IBinder cb, AttributionSource attributionSource, 7447 int scoAudioMode, @NonNull String eventSource) { 7448 MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 7449 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt") 7450 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 7451 BtHelper.scoAudioModeToString(scoAudioMode)); 7452 7453 if (!checkAudioSettingsPermission("startBluetoothSco()") || 7454 !mSystemReady) { 7455 mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record(); 7456 return; 7457 } 7458 final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 7459 == PackageManager.PERMISSION_GRANTED; 7460 final long ident = Binder.clearCallingIdentity(); 7461 try { 7462 mDeviceBroker.startBluetoothScoForClient( 7463 cb, attributionSource, scoAudioMode, isPrivileged, eventSource); 7464 } finally { 7465 Binder.restoreCallingIdentity(ident); 7466 } 7467 mmi.record(); 7468 } 7469 7470 /** @see AudioManager#stopBluetoothSco() */ stopBluetoothSco(IBinder cb, @NonNull AttributionSource attributionSource)7471 public void stopBluetoothSco(IBinder cb, 7472 @NonNull AttributionSource attributionSource) { 7473 if (attributionSource == null) { 7474 return; 7475 } 7476 if (!checkAudioSettingsPermission("stopBluetoothSco()") || 7477 !mSystemReady) { 7478 return; 7479 } 7480 final int uid = attributionSource.getUid(); 7481 final int pid = attributionSource.getPid(); 7482 final String eventSource = new StringBuilder("stopBluetoothSco()") 7483 .append(") from u/pid:").append(uid).append("/") 7484 .append(pid).toString(); 7485 final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 7486 == PackageManager.PERMISSION_GRANTED; 7487 final long ident = Binder.clearCallingIdentity(); 7488 try { 7489 mDeviceBroker.stopBluetoothScoForClient( 7490 cb, attributionSource, isPrivileged, eventSource); 7491 } finally { 7492 Binder.restoreCallingIdentity(ident); 7493 } 7494 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH) 7495 .setUid(uid) 7496 .setPid(pid) 7497 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco") 7498 .set(MediaMetrics.Property.SCO_AUDIO_MODE, 7499 BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED)) 7500 .record(); 7501 } 7502 7503 getContentResolver()7504 /*package*/ ContentResolver getContentResolver() { 7505 return mContentResolver; 7506 } 7507 7508 @VisibleForTesting(visibility = PACKAGE) getSettings()7509 public SettingsAdapter getSettings() { 7510 return mSettings; 7511 } 7512 7513 /////////////////////////////////////////////////////////////////////////// 7514 // Internal methods 7515 /////////////////////////////////////////////////////////////////////////// 7516 7517 /** 7518 * Checks if the adjustment should change ringer mode instead of just 7519 * adjusting volume. If so, this will set the proper ringer mode and volume 7520 * indices on the stream states. 7521 */ checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)7522 private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, 7523 String caller, int flags) { 7524 int result = FLAG_ADJUST_VOLUME; 7525 if (isPlatformTelevision() || mIsSingleVolume) { 7526 return result; 7527 } 7528 7529 int ringerMode = getRingerModeInternal(); 7530 7531 switch (ringerMode) { 7532 case RINGER_MODE_NORMAL: 7533 if (direction == AudioManager.ADJUST_LOWER) { 7534 if (mHasVibrator) { 7535 // "step" is the delta in internal index units corresponding to a 7536 // change of 1 in UI index units. 7537 // Because of rounding when rescaling from one stream index range to its alias 7538 // index range, we cannot simply test oldIndex == step: 7539 // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1) 7540 if (step <= oldIndex && oldIndex < 2 * step) { 7541 ringerMode = RINGER_MODE_VIBRATE; 7542 mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis(); 7543 } 7544 } else { 7545 if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) { 7546 ringerMode = RINGER_MODE_SILENT; 7547 } 7548 } 7549 } 7550 break; 7551 case RINGER_MODE_VIBRATE: 7552 if (!mHasVibrator) { 7553 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" + 7554 "but no vibrator is present"); 7555 break; 7556 } 7557 if (direction == AudioManager.ADJUST_LOWER) { 7558 if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { 7559 if (mVolumePolicy.volumeDownToEnterSilent) { 7560 final long diff = SystemClock.uptimeMillis() 7561 - mLoweredFromNormalToVibrateTime; 7562 if (diff > mVolumePolicy.vibrateToSilentDebounce 7563 && mRingerModeDelegate.canVolumeDownEnterSilent()) { 7564 ringerMode = RINGER_MODE_SILENT; 7565 } 7566 } else { 7567 result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 7568 } 7569 } 7570 } else if (direction == AudioManager.ADJUST_RAISE 7571 || direction == AudioManager.ADJUST_TOGGLE_MUTE 7572 || direction == AudioManager.ADJUST_UNMUTE) { 7573 ringerMode = RINGER_MODE_NORMAL; 7574 } 7575 result &= ~FLAG_ADJUST_VOLUME; 7576 break; 7577 case RINGER_MODE_SILENT: 7578 if (direction == AudioManager.ADJUST_RAISE 7579 || direction == AudioManager.ADJUST_TOGGLE_MUTE 7580 || direction == AudioManager.ADJUST_UNMUTE) { 7581 if (!mVolumePolicy.volumeUpToExitSilent) { 7582 result |= AudioManager.FLAG_SHOW_SILENT_HINT; 7583 } else { 7584 if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) { 7585 ringerMode = RINGER_MODE_VIBRATE; 7586 } else { 7587 // If we don't have a vibrator or they were toggling mute 7588 // go straight back to normal. 7589 ringerMode = RINGER_MODE_NORMAL; 7590 } 7591 } 7592 } 7593 result &= ~FLAG_ADJUST_VOLUME; 7594 break; 7595 default: 7596 Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode); 7597 break; 7598 } 7599 7600 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 7601 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller) 7602 && (flags & AudioManager.FLAG_FROM_KEY) == 0) { 7603 throw new SecurityException("Not allowed to change Do Not Disturb state"); 7604 } 7605 7606 setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/); 7607 7608 mPrevVolDirection = direction; 7609 7610 return result; 7611 } 7612 7613 @Override isStreamAffectedByRingerMode(int streamType)7614 public boolean isStreamAffectedByRingerMode(int streamType) { 7615 streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamAffectedByRingerMode"); 7616 return (mRingerModeAffectedStreams & (1 << streamType)) != 0; 7617 } 7618 isStreamAffectedByCurrentZen(int streamType)7619 public boolean isStreamAffectedByCurrentZen(int streamType) { 7620 streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamAffectedByCurrentZen"); 7621 return (mZenModeAffectedStreams & (1 << streamType)) != 0; 7622 } 7623 isStreamMutedByRingerOrZenMode(int streamType)7624 private boolean isStreamMutedByRingerOrZenMode(int streamType) { 7625 streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamMutedByRingerOrZenMode"); 7626 return (sRingerAndZenModeMutedStreams & (1 << streamType)) != 0; 7627 } 7628 7629 /** 7630 * Volume streams can be muted based on the current DND state: 7631 * DND total silence: ringer, notification, system, media and alarms streams muted by DND 7632 * DND alarms only: ringer, notification, system streams muted by DND 7633 * DND priority only: alarms, media, system, ringer and notification streams can be muted by 7634 * DND. The current applied zenPolicy determines which streams will be muted by DND. 7635 * @return true if changed, else false 7636 */ updateZenModeAffectedStreams()7637 private boolean updateZenModeAffectedStreams() { 7638 if (!mSystemReady) { 7639 return false; 7640 } 7641 7642 // If DND is off, no streams are muted by DND 7643 int zenModeAffectedStreams = 0; 7644 final int zenMode = mNm.getZenMode(); 7645 7646 if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) { 7647 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 7648 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 7649 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 7650 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 7651 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 7652 } else if (zenMode == Settings.Global.ZEN_MODE_ALARMS) { 7653 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 7654 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 7655 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 7656 } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { 7657 NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy(); 7658 if ((zenPolicy.priorityCategories 7659 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) { 7660 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM; 7661 } 7662 7663 if ((zenPolicy.priorityCategories 7664 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) { 7665 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC; 7666 } 7667 7668 // even if zen isn't muting the system stream, the ringer mode can still mute 7669 // the system stream 7670 if ((zenPolicy.priorityCategories 7671 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { 7672 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; 7673 } 7674 7675 if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) { 7676 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; 7677 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; 7678 } 7679 } 7680 7681 if (mZenModeAffectedStreams != zenModeAffectedStreams) { 7682 mZenModeAffectedStreams = zenModeAffectedStreams; 7683 return true; 7684 } 7685 7686 return false; 7687 } 7688 7689 @GuardedBy("mSettingsLock") updateRingerAndZenModeAffectedStreams()7690 private boolean updateRingerAndZenModeAffectedStreams() { 7691 boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams(); 7692 int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver, 7693 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 7694 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)| 7695 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)), 7696 UserHandle.USER_CURRENT); 7697 if (mIsSingleVolume) { 7698 ringerModeAffectedStreams = 0; 7699 } else if (mRingerModeDelegate != null) { 7700 ringerModeAffectedStreams = mRingerModeDelegate 7701 .getRingerModeAffectedStreams(ringerModeAffectedStreams); 7702 } 7703 if (mCameraSoundForced.get()) { 7704 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 7705 } else { 7706 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 7707 } 7708 if (sStreamVolumeAlias.get(AudioSystem.STREAM_DTMF) == AudioSystem.STREAM_RING) { 7709 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 7710 } else { 7711 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 7712 } 7713 7714 if (ringerModeAffectsAlarm()) { 7715 if (mRingerModeAffectsAlarm) { 7716 boolean muteAlarmWithRinger = 7717 mSettings.getGlobalInt(mContentResolver, 7718 Settings.Global.MUTE_ALARM_STREAM_WITH_RINGER_MODE, 7719 /* def= */ 0) != 0; 7720 if (muteAlarmWithRinger) { 7721 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_ALARM); 7722 } else { 7723 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_ALARM); 7724 } 7725 } 7726 } 7727 if (ringerModeAffectedStreams != mRingerModeAffectedStreams) { 7728 mSettings.putSystemIntForUser(mContentResolver, 7729 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 7730 ringerModeAffectedStreams, 7731 UserHandle.USER_CURRENT); 7732 mRingerModeAffectedStreams = ringerModeAffectedStreams; 7733 return true; 7734 } 7735 return updatedZenModeAffectedStreams; 7736 } 7737 7738 @Override isStreamAffectedByMute(int streamType)7739 public boolean isStreamAffectedByMute(int streamType) { 7740 streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamAffectedByMute"); 7741 return (mMuteAffectedStreams & (1 << streamType)) != 0; 7742 } 7743 7744 @Override isStreamMutableByUi(int streamType)7745 public boolean isStreamMutableByUi(int streamType) { 7746 return (mUserMutableStreams & (1 << streamType)) != 0; 7747 } 7748 ensureValidDirection(int direction)7749 private void ensureValidDirection(int direction) { 7750 switch (direction) { 7751 case AudioManager.ADJUST_LOWER: 7752 case AudioManager.ADJUST_RAISE: 7753 case AudioManager.ADJUST_SAME: 7754 case AudioManager.ADJUST_MUTE: 7755 case AudioManager.ADJUST_UNMUTE: 7756 case AudioManager.ADJUST_TOGGLE_MUTE: 7757 break; 7758 default: 7759 throw new IllegalArgumentException("Bad direction " + direction); 7760 } 7761 } 7762 ensureValidStreamType(int streamType)7763 private void ensureValidStreamType(int streamType) { 7764 if (streamType < 0 || streamType >= AudioSystem.getNumStreamTypes()) { 7765 throw new IllegalArgumentException("Bad stream type " + streamType); 7766 } 7767 } 7768 isMuteAdjust(int adjust)7769 private boolean isMuteAdjust(int adjust) { 7770 return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE 7771 || adjust == AudioManager.ADJUST_TOGGLE_MUTE; 7772 } 7773 7774 /** only public for mocking/spying, do not call outside of AudioService */ 7775 @VisibleForTesting isInCommunication()7776 public boolean isInCommunication() { 7777 boolean IsInCall = false; 7778 7779 TelecomManager telecomManager = 7780 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 7781 7782 final long ident = Binder.clearCallingIdentity(); 7783 try { 7784 IsInCall = telecomManager.isInCall(); 7785 } finally { 7786 Binder.restoreCallingIdentity(ident); 7787 } 7788 7789 int mode = mMode.get(); 7790 return (IsInCall 7791 || mode == AudioManager.MODE_IN_COMMUNICATION 7792 || mode == AudioManager.MODE_IN_CALL); 7793 } 7794 7795 /** 7796 * For code clarity for getActiveStreamType(int) 7797 * @param delay_ms max time since last stream activity to consider 7798 * @return true if stream is active in streams handled by AudioFlinger now or 7799 * in the last "delay_ms" ms. 7800 */ wasStreamActiveRecently(int stream, int delay_ms)7801 private boolean wasStreamActiveRecently(int stream, int delay_ms) { 7802 return mAudioSystem.isStreamActive(stream, delay_ms) 7803 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms); 7804 } 7805 getActiveStreamType(int suggestedStreamType)7806 private int getActiveStreamType(int suggestedStreamType) { 7807 if (mIsSingleVolume 7808 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 7809 return AudioSystem.STREAM_MUSIC; 7810 } 7811 7812 switch (mPlatformType) { 7813 case AudioSystem.PLATFORM_VOICE: 7814 if (isInCommunication() 7815 || mAudioSystem.isStreamActive(AudioManager.STREAM_VOICE_CALL, 0)) { 7816 if (!replaceStreamBtSco() 7817 && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) { 7818 if (DEBUG_VOL) { 7819 Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO..."); 7820 } 7821 return AudioSystem.STREAM_BLUETOOTH_SCO; 7822 } else { 7823 if (DEBUG_VOL) { 7824 Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL..."); 7825 } 7826 return AudioSystem.STREAM_VOICE_CALL; 7827 } 7828 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 7829 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 7830 if (DEBUG_VOL) 7831 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 7832 return AudioSystem.STREAM_RING; 7833 } else if (wasStreamActiveRecently( 7834 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 7835 if (DEBUG_VOL) { 7836 Log.v( 7837 TAG, 7838 "getActiveStreamType: Forcing STREAM_NOTIFICATION stream" 7839 + " active"); 7840 } 7841 return AudioSystem.STREAM_NOTIFICATION; 7842 } else { 7843 if (DEBUG_VOL) { 7844 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 7845 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 7846 } 7847 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 7848 } 7849 } else if ( 7850 wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 7851 if (DEBUG_VOL) 7852 Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active"); 7853 return AudioSystem.STREAM_NOTIFICATION; 7854 } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 7855 if (DEBUG_VOL) 7856 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active"); 7857 return AudioSystem.STREAM_RING; 7858 } 7859 default: 7860 if (isInCommunication() 7861 || mAudioSystem.isStreamActive(AudioManager.STREAM_VOICE_CALL, 0)) { 7862 if (!replaceStreamBtSco() 7863 && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) { 7864 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO"); 7865 return AudioSystem.STREAM_BLUETOOTH_SCO; 7866 } else { 7867 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL"); 7868 return AudioSystem.STREAM_VOICE_CALL; 7869 } 7870 } else if (mAudioSystem.isStreamActive( 7871 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 7872 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 7873 return AudioSystem.STREAM_NOTIFICATION; 7874 } else if (mAudioSystem.isStreamActive( 7875 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 7876 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 7877 return AudioSystem.STREAM_RING; 7878 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 7879 if (mAudioSystem.isStreamActive( 7880 AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) { 7881 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 7882 return AudioSystem.STREAM_NOTIFICATION; 7883 } 7884 if (mAudioSystem.isStreamActive( 7885 AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) { 7886 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING"); 7887 return AudioSystem.STREAM_RING; 7888 } 7889 if (DEBUG_VOL) { 7890 Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK(" 7891 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default"); 7892 } 7893 return DEFAULT_VOL_STREAM_NO_PLAYBACK; 7894 } 7895 break; 7896 } 7897 7898 suggestedStreamType = replaceBtScoStreamWithVoiceCall(suggestedStreamType, 7899 "getActiveStreamType"); 7900 7901 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type " 7902 + suggestedStreamType); 7903 return suggestedStreamType; 7904 } 7905 broadcastRingerMode(String action, int ringerMode)7906 private void broadcastRingerMode(String action, int ringerMode) { 7907 if (!mSystemServer.isPrivileged()) { 7908 return; 7909 } 7910 // Send sticky broadcast 7911 Intent broadcast = new Intent(action); 7912 broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode); 7913 broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 7914 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 7915 sendStickyBroadcastToAll(broadcast); 7916 } 7917 broadcastVibrateSetting(int vibrateType)7918 private void broadcastVibrateSetting(int vibrateType) { 7919 if (!mSystemServer.isPrivileged()) { 7920 return; 7921 } 7922 // Send broadcast 7923 if (mActivityManagerInternal.isSystemReady()) { 7924 Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); 7925 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType); 7926 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType)); 7927 sendBroadcastToAll(broadcast, null /* options */); 7928 } 7929 } 7930 7931 // Message helper methods 7932 /** 7933 * Queue a message on the given handler's message queue, after acquiring the service wake lock. 7934 * Note that the wake lock needs to be released after the message has been handled. 7935 */ queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)7936 private void queueMsgUnderWakeLock(Handler handler, int msg, 7937 int arg1, int arg2, Object obj, int delay) { 7938 final long ident = Binder.clearCallingIdentity(); 7939 try { 7940 // Always acquire the wake lock as AudioService because it is released by the 7941 // message handler. 7942 mAudioEventWakeLock.acquire(); 7943 } finally { 7944 Binder.restoreCallingIdentity(ident); 7945 } 7946 sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay); 7947 } 7948 sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)7949 private static void sendMsg(Handler handler, int msg, 7950 int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { 7951 if (existingMsgPolicy == SENDMSG_REPLACE) { 7952 handler.removeMessages(msg); 7953 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 7954 return; 7955 } 7956 7957 final long time = SystemClock.uptimeMillis() + delay; 7958 handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time); 7959 } 7960 sendBundleMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay)7961 private static void sendBundleMsg(Handler handler, int msg, 7962 int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay) { 7963 if (existingMsgPolicy == SENDMSG_REPLACE) { 7964 handler.removeMessages(msg); 7965 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 7966 return; 7967 } 7968 7969 final long time = SystemClock.uptimeMillis() + delay; 7970 Message message = handler.obtainMessage(msg, arg1, arg2, obj); 7971 message.setData(bundle); 7972 handler.sendMessageAtTime(message, time); 7973 } 7974 checkAudioSettingsPermission(String method)7975 boolean checkAudioSettingsPermission(String method) { 7976 if (callingOrSelfHasAudioSettingsPermission()) { 7977 return true; 7978 } 7979 String msg = "Audio Settings Permission Denial: " + method + " from pid=" 7980 + Binder.getCallingPid() 7981 + ", uid=" + Binder.getCallingUid(); 7982 Log.w(TAG, msg); 7983 return false; 7984 } 7985 callingOrSelfHasAudioSettingsPermission()7986 private boolean callingOrSelfHasAudioSettingsPermission() { 7987 return mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS) 7988 == PackageManager.PERMISSION_GRANTED; 7989 } 7990 callingHasAudioSettingsPermission()7991 private boolean callingHasAudioSettingsPermission() { 7992 return mContext.checkCallingPermission(MODIFY_AUDIO_SETTINGS) 7993 == PackageManager.PERMISSION_GRANTED; 7994 } 7995 hasAudioSettingsPermission(int uid, int pid)7996 private boolean hasAudioSettingsPermission(int uid, int pid) { 7997 return mContext.checkPermission(MODIFY_AUDIO_SETTINGS, pid, uid) 7998 == PackageManager.PERMISSION_GRANTED; 7999 } 8000 8001 /** 8002 * Minimum attenuation that can be set for alarms over speaker by an application that 8003 * doesn't have the MODIFY_AUDIO_SETTINGS permission. 8004 */ 8005 protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f; 8006 8007 /** 8008 * Configures the VolumeStreamState instances for minimum stream index that can be accessed 8009 * without MODIFY_AUDIO_SETTINGS permission. 8010 * Can only be done successfully once audio policy has finished reading its configuration files 8011 * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will 8012 * remain at the stream min index value. 8013 */ initMinStreamVolumeWithoutModifyAudioSettings()8014 protected void initMinStreamVolumeWithoutModifyAudioSettings() { 8015 int idx; 8016 int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 8017 if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, 8018 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) { 8019 deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER; 8020 } 8021 for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; 8022 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) { 8023 if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm) 8024 < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) { 8025 break; 8026 } 8027 } 8028 final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 8029 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] 8030 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]); 8031 // update the VolumeStreamState for STREAM_ALARM and its aliases 8032 for (int streamIdx = 0; streamIdx < sStreamVolumeAlias.size(); ++streamIdx) { 8033 final int streamAlias = sStreamVolumeAlias.valueAt(streamIdx); 8034 if (streamAlias == AudioSystem.STREAM_ALARM) { 8035 getVssForStreamOrDefault(streamAlias).updateNoPermMinIndex(safeIndex); 8036 } 8037 } 8038 } 8039 8040 /** 8041 * Returns device associated with the stream volume. 8042 * 8043 * Only public for mocking/spying, do not call outside of AudioService. 8044 * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for 8045 * DEVICE_OUT_SPEAKER_SAFE. 8046 */ 8047 @VisibleForTesting getDeviceForStream(int stream)8048 public int getDeviceForStream(int stream) { 8049 stream = replaceBtScoStreamWithVoiceCall(stream, "getDeviceForStream"); 8050 return selectOneAudioDevice(getDeviceSetForStream(stream)); 8051 } 8052 8053 /* 8054 * Must match native apm_extract_one_audio_device() used in getDeviceForVolume() 8055 * or the wrong device volume may be adjusted. 8056 */ selectOneAudioDevice(Set<Integer> deviceSet)8057 private int selectOneAudioDevice(Set<Integer> deviceSet) { 8058 if (deviceSet.isEmpty()) { 8059 return AudioSystem.DEVICE_NONE; 8060 } else if (deviceSet.size() == 1) { 8061 return deviceSet.iterator().next(); 8062 } else { 8063 // Multiple device selection is either: 8064 // - dock + one other device: give priority to dock in this case. 8065 // - speaker + one other device: give priority to speaker in this case. 8066 // - one A2DP device + another device: happens with duplicated output. In this case 8067 // retain the device on the A2DP output as the other must not correspond to an active 8068 // selection if not the speaker. 8069 // - HDMI-CEC system audio mode only output: give priority to available item in order. 8070 8071 if (deviceSet.contains(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET)) { 8072 return AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; 8073 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) { 8074 return AudioSystem.DEVICE_OUT_SPEAKER; 8075 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) { 8076 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect 8077 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE; 8078 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) { 8079 return AudioSystem.DEVICE_OUT_HDMI_ARC; 8080 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) { 8081 return AudioSystem.DEVICE_OUT_HDMI_EARC; 8082 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) { 8083 return AudioSystem.DEVICE_OUT_AUX_LINE; 8084 } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) { 8085 return AudioSystem.DEVICE_OUT_SPDIF; 8086 } else { 8087 // At this point, deviceSet should contain exactly one removable device; 8088 // regardless, return the first removable device in numeric order. 8089 // If there is no removable device, this falls through to log an error. 8090 for (int deviceType : deviceSet) { 8091 if (AudioSystem.DEVICE_OUT_PICK_FOR_VOLUME_SET.contains(deviceType)) { 8092 return deviceType; 8093 } 8094 } 8095 } 8096 } 8097 Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination " 8098 + AudioSystem.deviceSetToString(deviceSet)); 8099 return AudioSystem.DEVICE_NONE; 8100 } 8101 8102 /** 8103 * @see AudioManager#getDevicesForStream(int) 8104 * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices 8105 * will have multi-bit device types since S. 8106 * Use {@link #getDevicesForAttributes()} instead. 8107 */ 8108 @Override 8109 @Deprecated getDeviceMaskForStream(int streamType)8110 public int getDeviceMaskForStream(int streamType) { 8111 streamType = replaceBtScoStreamWithVoiceCall(streamType, "getDeviceMaskForStream"); 8112 8113 ensureValidStreamType(streamType); 8114 // no permission required 8115 final long token = Binder.clearCallingIdentity(); 8116 try { 8117 return AudioSystem.getDeviceMaskFromSet( 8118 getDeviceSetForStreamDirect(streamType)); 8119 } finally { 8120 Binder.restoreCallingIdentity(token); 8121 } 8122 } 8123 8124 /** 8125 * Returns the devices associated with a stream type. 8126 * 8127 * SPEAKER_SAFE will alias to SPEAKER. 8128 */ 8129 @NonNull getDeviceSetForStreamDirect(int stream)8130 private Set<Integer> getDeviceSetForStreamDirect(int stream) { 8131 final AudioAttributes attr = 8132 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 8133 Set<Integer> deviceSet = 8134 AudioSystem.generateAudioDeviceTypesSet( 8135 getDevicesForAttributesInt(attr, true /* forVolume */)); 8136 return deviceSet; 8137 } 8138 8139 /** 8140 * Returns a reference to the list of devices for the stream, do not modify. 8141 * 8142 * The device returned may be aliased to the actual device whose volume curve 8143 * will be used. For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER. 8144 */ 8145 @NonNull getDeviceSetForStream(int stream)8146 public Set<Integer> getDeviceSetForStream(int stream) { 8147 stream = replaceBtScoStreamWithVoiceCall(stream, "getDeviceSetForStream"); 8148 ensureValidStreamType(stream); 8149 synchronized (mVolumeStateLock) { 8150 return getVssForStreamOrDefault(stream).observeDevicesForStream_syncVSS(true); 8151 } 8152 } 8153 onObserveDevicesForAllStreams(int skipStream)8154 private void onObserveDevicesForAllStreams(int skipStream) { 8155 synchronized (mSettingsLock) { 8156 synchronized (mVolumeStateLock) { 8157 for (int stream = 0; stream < mStreamStates.size(); stream++) { 8158 final VolumeStreamState vss = mStreamStates.valueAt(stream); 8159 if (vss != null && vss.getStreamType() != skipStream) { 8160 Set<Integer> deviceSet = 8161 vss.observeDevicesForStream_syncVSS(false /*checkOthers*/); 8162 for (Integer device : deviceSet) { 8163 // Update volume states for devices routed for the stream 8164 updateVolumeStates(device, vss.getStreamType(), 8165 "AudioService#onObserveDevicesForAllStreams"); 8166 } 8167 } 8168 } 8169 } 8170 } 8171 } 8172 8173 /** only public for mocking/spying, do not call outside of AudioService */ 8174 @VisibleForTesting postObserveDevicesForAllStreams()8175 public void postObserveDevicesForAllStreams() { 8176 postObserveDevicesForAllStreams(-1); 8177 } 8178 8179 /** only public for mocking/spying, do not call outside of AudioService */ 8180 @VisibleForTesting postObserveDevicesForAllStreams(int skipStream)8181 public void postObserveDevicesForAllStreams(int skipStream) { 8182 sendMsg(mAudioHandler, 8183 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS, 8184 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/, 8185 0 /*delay*/); 8186 } 8187 postBtCommDeviceActive(@tCommDeviceActiveType int btCommDeviceActive)8188 /*package*/ void postBtCommDeviceActive(@BtCommDeviceActiveType int btCommDeviceActive) { 8189 sendMsg(mAudioHandler, 8190 MSG_BT_COMM_DEVICE_ACTIVE_UPDATE, 8191 SENDMSG_QUEUE, btCommDeviceActive /*arg1*/, 0 /*arg2*/, null /*obj*/, 8192 0 /*delay*/); 8193 } 8194 onUpdateBtCommDeviceActive(@tCommDeviceActiveType int btCommDeviceActive)8195 private void onUpdateBtCommDeviceActive(@BtCommDeviceActiveType int btCommDeviceActive) { 8196 if (mBtCommDeviceActive.getAndSet(btCommDeviceActive) != btCommDeviceActive) { 8197 getVssForStreamOrDefault(AudioSystem.STREAM_VOICE_CALL).updateIndexFactors(); 8198 } 8199 } 8200 8201 /** 8202 * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior 8203 * 8204 * @param register Whether the listener is to be registered or unregistered. If false, the 8205 * device adopts variable volume behavior. 8206 */ 8207 @RequiresPermission(anyOf = { MODIFY_AUDIO_ROUTING, BLUETOOTH_PRIVILEGED }) registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment, @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior)8208 public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, 8209 IAudioDeviceVolumeDispatcher cb, String packageName, 8210 AudioDeviceAttributes device, List<VolumeInfo> volumes, 8211 boolean handlesVolumeAdjustment, 8212 @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) { 8213 // verify permissions 8214 if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 8215 != PackageManager.PERMISSION_GRANTED 8216 && mContext.checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED) 8217 != PackageManager.PERMISSION_GRANTED) { 8218 throw new SecurityException( 8219 "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions"); 8220 } 8221 // verify arguments 8222 Objects.requireNonNull(device); 8223 Objects.requireNonNull(volumes); 8224 8225 int deviceOut = device.getInternalType(); 8226 if (register) { 8227 AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(this, 8228 device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior); 8229 final AbsoluteVolumeDeviceInfo oldInfo = getAbsoluteVolumeDeviceInfo(deviceOut); 8230 addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info); 8231 8232 boolean volumeBehaviorChanged = (oldInfo == null) 8233 || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior); 8234 if (volumeBehaviorChanged) { 8235 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut); 8236 removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut); 8237 8238 dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior); 8239 } 8240 // Update stream volumes to the given device, if specified in a VolumeInfo. 8241 // Mute state is not updated because it is stream-wide - the only way to mute a 8242 // stream's output to a particular device is to set the volume index to zero. 8243 for (VolumeInfo volumeInfo : volumes) { 8244 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET 8245 && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET 8246 && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) { 8247 if (volumeInfo.hasStreamType()) { 8248 setStreamVolumeInt(volumeInfo.getStreamType(), 8249 rescaleIndex(volumeInfo, volumeInfo.getStreamType()), 8250 deviceOut, false /*force*/, packageName, 8251 true /*hasModifyAudioSettings*/); 8252 } else { 8253 for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) { 8254 setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType), 8255 deviceOut, false /*force*/, packageName, 8256 true /*hasModifyAudioSettings*/); 8257 } 8258 } 8259 } 8260 } 8261 } else { 8262 AbsoluteVolumeDeviceInfo deviceInfo = removeAudioSystemDeviceOutFromAbsVolumeDevices( 8263 deviceOut); 8264 if (deviceInfo != null) { 8265 deviceInfo.unlinkToDeath(); 8266 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE); 8267 } 8268 } 8269 } 8270 8271 /** 8272 * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int) 8273 * @param device the audio device to be affected 8274 * @param deviceVolumeBehavior one of the device behaviors 8275 */ 8276 @android.annotation.EnforcePermission(anyOf = { 8277 MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED }) setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)8278 public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device, 8279 @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior, 8280 @Nullable String pkgName) { 8281 // verify permissions 8282 super.setDeviceVolumeBehavior_enforcePermission(); 8283 // verify arguments 8284 Objects.requireNonNull(device); 8285 AudioDeviceVolumeManager.enforceValidVolumeBehavior(deviceVolumeBehavior); 8286 8287 device = retrieveBluetoothAddress(device); 8288 8289 sVolumeLogger.enqueue(new EventLogger.StringEvent("setDeviceVolumeBehavior: dev:" 8290 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:" 8291 + Utils.anonymizeBluetoothAddress(device.getAddress()) + " behavior:" 8292 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior) 8293 + " pack:" + pkgName).printLog(TAG)); 8294 if (pkgName == null) { 8295 pkgName = ""; 8296 } 8297 if (device.getType() == TYPE_BLUETOOTH_A2DP) { 8298 avrcpSupportsAbsoluteVolume(device.getAddress(), 8299 deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE); 8300 return; 8301 } 8302 8303 setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName); 8304 persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior); 8305 } 8306 setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)8307 private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device, 8308 @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior, 8309 @NonNull String caller) { 8310 int audioSystemDeviceOut = device.getInternalType(); 8311 boolean volumeBehaviorChanged = false; 8312 // update device masks based on volume behavior 8313 switch (deviceVolumeBehavior) { 8314 case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE: 8315 volumeBehaviorChanged |= 8316 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 8317 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 8318 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 8319 != null); 8320 break; 8321 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED: 8322 volumeBehaviorChanged |= 8323 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut) 8324 | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut) 8325 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 8326 != null); 8327 break; 8328 case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL: 8329 volumeBehaviorChanged |= 8330 addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut) 8331 | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut) 8332 | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut) 8333 != null); 8334 break; 8335 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE: 8336 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY: 8337 case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE: 8338 throw new IllegalArgumentException("Absolute volume unsupported for now"); 8339 } 8340 8341 if (volumeBehaviorChanged) { 8342 sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE, 8343 deviceVolumeBehavior, 0, device, /*delay*/ 0); 8344 } 8345 8346 // log event and caller 8347 sDeviceLogger.enqueue(new EventLogger.StringEvent( 8348 "Volume behavior " + deviceVolumeBehavior + " for dev=0x" 8349 + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller)); 8350 // make sure we have a volume entry for this device, and that volume is updated according 8351 // to volume behavior 8352 postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut, 8353 "setDeviceVolumeBehavior:" + caller); 8354 } 8355 8356 /** 8357 * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes) 8358 * @param device the audio output device type 8359 * @return the volume behavior for the device 8360 */ 8361 @android.annotation.EnforcePermission(anyOf = { 8362 MODIFY_AUDIO_ROUTING, QUERY_AUDIO_STATE, MODIFY_AUDIO_SETTINGS_PRIVILEGED 8363 }) 8364 public @AudioDeviceVolumeManager.DeviceVolumeBehavior getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)8365 int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) { 8366 // verify permissions 8367 super.getDeviceVolumeBehavior_enforcePermission(); 8368 // verify parameters 8369 Objects.requireNonNull(device); 8370 8371 device = retrieveBluetoothAddress(device); 8372 8373 return getDeviceVolumeBehaviorInt(device); 8374 } 8375 8376 private @AudioDeviceVolumeManager.DeviceVolumeBehavior getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)8377 int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) { 8378 // Get the internal type set by the AudioDeviceAttributes constructor which is always more 8379 // exact (avoids double conversions) than a conversion from SDK type via 8380 // AudioDeviceInfo.convertDeviceTypeToInternalDevice() 8381 final int audioSystemDeviceOut = device.getInternalType(); 8382 8383 // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the 8384 // current volume behavior. 8385 if (mFullVolumeDevices.contains(audioSystemDeviceOut)) { 8386 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL; 8387 } 8388 if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) { 8389 return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED; 8390 } 8391 if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) { 8392 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE; 8393 } 8394 synchronized (mAbsoluteVolumeDeviceInfoMapLock) { 8395 if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) { 8396 final AbsoluteVolumeDeviceInfo deviceInfo = mAbsoluteVolumeDeviceInfoMap.get( 8397 audioSystemDeviceOut); 8398 if (deviceInfo != null) { 8399 return deviceInfo.mDeviceVolumeBehavior; 8400 } 8401 8402 Log.e(TAG, 8403 "Null absolute volume device info stored for key " + audioSystemDeviceOut); 8404 } 8405 } 8406 8407 if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut) 8408 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) { 8409 return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE; 8410 } 8411 return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE; 8412 } 8413 8414 /** 8415 * @see AudioManager#isVolumeFixed() 8416 * Note there are no permission checks on this operation, as this is part of API 21 8417 * @return true if the current device's volume behavior for media is 8418 * DEVICE_VOLUME_BEHAVIOR_FIXED 8419 */ isVolumeFixed()8420 public boolean isVolumeFixed() { 8421 if (mUseFixedVolume) { 8422 return true; 8423 } 8424 final AudioAttributes attributes = new AudioAttributes.Builder() 8425 .setUsage(AudioAttributes.USAGE_MEDIA) 8426 .build(); 8427 // calling getDevice*Int to bypass permission check 8428 final List<AudioDeviceAttributes> devices = 8429 getDevicesForAttributesInt(attributes, true /* forVolume */); 8430 for (AudioDeviceAttributes device : devices) { 8431 if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) { 8432 return true; 8433 } 8434 } 8435 return false; 8436 } 8437 8438 /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0; 8439 /*package*/ static final int CONNECTION_STATE_CONNECTED = 1; 8440 /** 8441 * The states that can be used with AudioService.setWiredDeviceConnectionState() 8442 * Attention: those values differ from those in BluetoothProfile, follow annotations to 8443 * distinguish between @ConnectionState and @BtProfileConnectionState 8444 */ 8445 @IntDef({ 8446 CONNECTION_STATE_DISCONNECTED, 8447 CONNECTION_STATE_CONNECTED, 8448 }) 8449 @Retention(RetentionPolicy.SOURCE) 8450 public @interface ConnectionState {} 8451 8452 /** 8453 * Default SAD for a TV using ARC, used when the Amplifier didn't report any SADs. 8454 * Represents 2-channel LPCM including all defined sample rates and bit depths. 8455 * For the format definition, see Table 34 in the CEA standard CEA-861-D. 8456 */ 8457 private static final byte[] DEFAULT_ARC_AUDIO_DESCRIPTOR = new byte[]{0x09, 0x7f, 0x07}; 8458 8459 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 8460 /** 8461 * see AudioManager.setWiredDeviceConnectionState() 8462 */ setWiredDeviceConnectionState(@onNull AudioDeviceAttributes attributes, @ConnectionState int state, String caller)8463 public void setWiredDeviceConnectionState(@NonNull AudioDeviceAttributes attributes, 8464 @ConnectionState int state, String caller) { 8465 super.setWiredDeviceConnectionState_enforcePermission(); 8466 Objects.requireNonNull(attributes); 8467 8468 attributes = retrieveBluetoothAddress(attributes); 8469 8470 // When using ARC, a TV should use default 2 channel LPCM if the Amplifier didn't 8471 // report any SADs. See section 13.15.3 of the HDMI-CEC spec version 1.4b. 8472 if (attributes.getType() == AudioDeviceInfo.TYPE_HDMI_ARC 8473 && attributes.getRole() == AudioDeviceAttributes.ROLE_OUTPUT 8474 && attributes.getAudioDescriptors().isEmpty()) { 8475 attributes = new AudioDeviceAttributes( 8476 attributes.getRole(), 8477 attributes.getType(), 8478 attributes.getAddress(), 8479 attributes.getName(), 8480 attributes.getAudioProfiles(), 8481 new ArrayList<AudioDescriptor>(Collections.singletonList( 8482 new AudioDescriptor( 8483 AudioDescriptor.STANDARD_EDID, 8484 AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE, 8485 DEFAULT_ARC_AUDIO_DESCRIPTOR 8486 ) 8487 )) 8488 ); 8489 } 8490 8491 if (state != CONNECTION_STATE_CONNECTED 8492 && state != CONNECTION_STATE_DISCONNECTED) { 8493 throw new IllegalArgumentException("Invalid state " + state); 8494 } 8495 new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState") 8496 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress()) 8497 .set(MediaMetrics.Property.CLIENT_NAME, caller) 8498 .set(MediaMetrics.Property.DEVICE, 8499 AudioSystem.getDeviceName(attributes.getInternalType())) 8500 .set(MediaMetrics.Property.NAME, attributes.getName()) 8501 .set(MediaMetrics.Property.STATE, 8502 state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected") 8503 .record(); 8504 mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller); 8505 // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System 8506 // Client. For example, the device can start with the Audio System Client unavailable. 8507 // When the feature is activated the client becomes available, therefore Audio Service 8508 // requests a new HDMI Audio System Client instance when the ARC status is changed. 8509 if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) { 8510 updateHdmiAudioSystemClient(); 8511 } 8512 } 8513 8514 /** 8515 * Replace the current HDMI Audio System Client. 8516 * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}. 8517 */ updateHdmiAudioSystemClient()8518 private void updateHdmiAudioSystemClient() { 8519 Slog.d(TAG, "Hdmi Audio System Client is updated"); 8520 synchronized (mHdmiClientLock) { 8521 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient(); 8522 } 8523 } 8524 8525 /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */ setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)8526 public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device, 8527 boolean connected) { 8528 Objects.requireNonNull(device); 8529 enforceModifyAudioRoutingPermission(); 8530 8531 device = retrieveBluetoothAddress(device); 8532 8533 mDeviceBroker.setTestDeviceConnectionState(device, 8534 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED); 8535 // simulate a routing update from native 8536 sendMsg(mAudioHandler, 8537 MSG_ROUTING_UPDATED, 8538 SENDMSG_REPLACE, 0, 0, null, 8539 /*delay*/ 0); 8540 } 8541 8542 /** 8543 * @hide 8544 * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState() 8545 * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent() 8546 */ 8547 @IntDef({ 8548 BluetoothProfile.STATE_DISCONNECTED, 8549 BluetoothProfile.STATE_CONNECTED, 8550 }) 8551 @Retention(RetentionPolicy.SOURCE) 8552 public @interface BtProfileConnectionState {} 8553 8554 /** 8555 * @hide 8556 * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged() 8557 */ 8558 @IntDef({ 8559 BluetoothProfile.HEARING_AID, 8560 BluetoothProfile.A2DP, 8561 BluetoothProfile.A2DP_SINK, 8562 BluetoothProfile.LE_AUDIO, 8563 BluetoothProfile.LE_AUDIO_BROADCAST, 8564 }) 8565 @Retention(RetentionPolicy.SOURCE) 8566 public @interface BtProfile {} 8567 8568 8569 @android.annotation.EnforcePermission(BLUETOOTH_STACK) 8570 /** 8571 * See AudioManager.handleBluetoothActiveDeviceChanged(...) 8572 */ handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)8573 public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, 8574 BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) { 8575 handleBluetoothActiveDeviceChanged_enforcePermission(); 8576 if (info == null) { 8577 throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for" 8578 + " device " + previousDevice + " -> " + newDevice); 8579 } 8580 final int profile = info.getProfile(); 8581 if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK 8582 && profile != BluetoothProfile.LE_AUDIO 8583 && profile != BluetoothProfile.LE_AUDIO_BROADCAST 8584 && profile != BluetoothProfile.HEARING_AID 8585 && !(mDeviceBroker.isScoManagedByAudio() && profile == BluetoothProfile.HEADSET)) { 8586 throw new IllegalArgumentException("Illegal BluetoothProfile profile for device " 8587 + previousDevice + " -> " + newDevice + ". Got: " + profile); 8588 } 8589 8590 sDeviceLogger.enqueue(new EventLogger.StringEvent("BluetoothActiveDeviceChanged for " 8591 + BluetoothProfile.getProfileName(profile) + ", device update " + previousDevice 8592 + " -> " + newDevice).printLog(TAG)); 8593 AudioDeviceBroker.BtDeviceChangedData data = 8594 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info, 8595 "AudioService"); 8596 sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0, 8597 /*obj*/ data, /*delay*/ 0); 8598 } 8599 8600 /** only public for mocking/spying, do not call outside of AudioService */ 8601 @VisibleForTesting setMusicMute(boolean mute)8602 public void setMusicMute(boolean mute) { 8603 getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).muteInternally(mute); 8604 } 8605 8606 private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET; 8607 static { 8608 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>(); 8609 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET); 8610 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE); 8611 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE); 8612 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HEARING_AID); 8613 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET); 8614 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET); 8615 DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET); 8616 } 8617 8618 /** only public for mocking/spying, do not call outside of AudioService */ 8619 @VisibleForTesting postAccessoryPlugMediaUnmute(int newDevice)8620 public void postAccessoryPlugMediaUnmute(int newDevice) { 8621 sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE, 8622 newDevice, 0, null, 0); 8623 } 8624 onAccessoryPlugMediaUnmute(int newDevice)8625 private void onAccessoryPlugMediaUnmute(int newDevice) { 8626 if (DEBUG_VOL) { 8627 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]", 8628 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 8629 } 8630 8631 if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS 8632 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC) 8633 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice) 8634 && getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).mIsMuted 8635 && getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).getIndex(newDevice) != 0 8636 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) { 8637 if (DEBUG_VOL) { 8638 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]", 8639 newDevice, AudioSystem.getOutputDeviceName(newDevice))); 8640 } 8641 // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute -> 8642 // vss.updateVolumeGroupIndex 8643 synchronized (mSettingsLock) { 8644 getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).mute(false, 8645 "onAccessoryPlugMediaUnmute"); 8646 } 8647 } 8648 } 8649 8650 /** 8651 * See AudioManager.hasHapticChannels(Context, Uri). 8652 */ hasHapticChannels(Uri uri)8653 public boolean hasHapticChannels(Uri uri) { 8654 return AudioManager.hasHapticChannelsImpl(mContext, uri); 8655 } 8656 8657 /////////////////////////////////////////////////////////////////////////// 8658 // Inner classes 8659 /////////////////////////////////////////////////////////////////////////// 8660 /** 8661 * Key is the AudioManager VolumeGroupId 8662 * Value is the VolumeGroupState 8663 */ 8664 private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>(); 8665 initVolumeGroupStates()8666 private void initVolumeGroupStates() { 8667 int btScoGroupId = -1; 8668 VolumeGroupState voiceCallGroup = null; 8669 for (final AudioVolumeGroup avg : getAudioVolumeGroups()) { 8670 try { 8671 if (ensureValidVolumeGroup(avg)) { 8672 final VolumeGroupState vgs = new VolumeGroupState(avg); 8673 sVolumeGroupStates.append(avg.getId(), vgs); 8674 if (vgs.isVoiceCall()) { 8675 voiceCallGroup = vgs; 8676 } 8677 } else { 8678 // invalid volume group will be reported for bt sco group with no other 8679 // legacy stream type, we try to replace it in sVolumeGroupStates with the 8680 // voice call volume group 8681 btScoGroupId = avg.getId(); 8682 } 8683 } catch (IllegalArgumentException e) { 8684 // Volume Groups without attributes are not controllable through set/get volume 8685 // using attributes. Do not append them. 8686 if (DEBUG_VOL) { 8687 Log.d(TAG, "volume group " + avg.name() + " for internal policy needs"); 8688 } 8689 } 8690 } 8691 8692 if (replaceStreamBtSco() && btScoGroupId >= 0 && voiceCallGroup != null) { 8693 // the bt sco group is deprecated, storing the voice call group instead 8694 // to keep the code backwards compatible when calling the volume group APIs 8695 sVolumeGroupStates.append(btScoGroupId, voiceCallGroup); 8696 } 8697 8698 // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after 8699 // VSS.class. Locking order needs to be preserved 8700 synchronized (mSettingsLock) { 8701 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 8702 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 8703 vgs.applyAllVolumes(/* userSwitch= */ false); 8704 } 8705 } 8706 } 8707 8708 /** 8709 * Returns false if the legacy stream types only contains the deprecated 8710 * {@link AudioSystem#STREAM_BLUETOOTH_SCO}. 8711 * 8712 * @throws IllegalArgumentException if it has more than one non-default {@link AudioAttributes} 8713 * 8714 * @param avg the volume group to check 8715 */ ensureValidVolumeGroup(AudioVolumeGroup avg)8716 private boolean ensureValidVolumeGroup(AudioVolumeGroup avg) { 8717 boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream() 8718 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes())); 8719 if (!hasAtLeastOneValidAudioAttributes) { 8720 throw new IllegalArgumentException("Volume Group " + avg.name() 8721 + " has no valid audio attributes"); 8722 } 8723 if (replaceStreamBtSco()) { 8724 // if there are multiple legacy stream types associated we can omit stream bt sco 8725 // otherwise this is not a valid volume group 8726 if (avg.getLegacyStreamTypes().length == 1 8727 && avg.getLegacyStreamTypes()[0] == AudioSystem.STREAM_BLUETOOTH_SCO) { 8728 return false; 8729 } 8730 } 8731 return true; 8732 } 8733 shouldPreserveVolume(boolean userSwitch, VolumeGroupState vgs)8734 private boolean shouldPreserveVolume(boolean userSwitch, VolumeGroupState vgs) { 8735 // as for STREAM_MUSIC, preserve volume from one user to the next except 8736 // Android Automotive platform 8737 return (userSwitch && vgs.isMusic()) && !isPlatformAutomotive(); 8738 } 8739 readVolumeGroupsSettings(boolean userSwitch)8740 private void readVolumeGroupsSettings(boolean userSwitch) { 8741 synchronized (mSettingsLock) { 8742 synchronized (mVolumeStateLock) { 8743 if (DEBUG_VOL) { 8744 Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch); 8745 } 8746 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 8747 VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 8748 if (!shouldPreserveVolume(userSwitch, vgs)) { 8749 vgs.clearIndexCache(); 8750 vgs.readSettings(); 8751 } 8752 vgs.applyAllVolumes(userSwitch); 8753 } 8754 } 8755 } 8756 } 8757 8758 // Called upon crash of AudioServer restoreVolumeGroups()8759 private void restoreVolumeGroups() { 8760 if (DEBUG_VOL) { 8761 Log.v(TAG, "restoreVolumeGroups"); 8762 } 8763 8764 // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after 8765 // VSS.class. Locking order needs to be preserved 8766 synchronized (mSettingsLock) { 8767 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 8768 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 8769 vgs.applyAllVolumes(false/*userSwitch*/); 8770 } 8771 } 8772 } 8773 dumpVolumeGroups(PrintWriter pw)8774 private void dumpVolumeGroups(PrintWriter pw) { 8775 pw.println("\nVolume Groups (device: index)"); 8776 for (int i = 0; i < sVolumeGroupStates.size(); i++) { 8777 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i); 8778 vgs.dump(pw); 8779 pw.println(""); 8780 } 8781 } 8782 isCallStream(int stream)8783 private static boolean isCallStream(int stream) { 8784 return stream == AudioSystem.STREAM_VOICE_CALL 8785 || stream == AudioSystem.STREAM_BLUETOOTH_SCO; 8786 } 8787 getVolumeGroupForStreamType(int stream)8788 private static int getVolumeGroupForStreamType(int stream) { 8789 AudioAttributes attributes = 8790 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream); 8791 if (attributes.equals(new AudioAttributes.Builder().build())) { 8792 return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; 8793 } 8794 return AudioProductStrategy.getVolumeGroupIdForAudioAttributes( 8795 attributes, /* fallbackOnDefault= */ false); 8796 } 8797 8798 // NOTE: Locking order for synchronized objects related to volume management: 8799 // 1 mSettingsLock 8800 // 2 mVolumeStateLock 8801 private class VolumeGroupState { 8802 private final AudioVolumeGroup mAudioVolumeGroup; 8803 private final SparseIntArray mIndexMap = new SparseIntArray(8); 8804 private int mIndexMin; 8805 private int mIndexMax; 8806 private boolean mHasValidStreamType = false; 8807 private int mPublicStreamType = AudioSystem.STREAM_MUSIC; 8808 private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes(); 8809 private boolean mIsMuted = false; 8810 private String mSettingName; 8811 8812 // No API in AudioSystem to get a device from strategy or from attributes. 8813 // Need a valid public stream type to use current API getDeviceForStream getDeviceForVolume()8814 private int getDeviceForVolume() { 8815 return getDeviceForStream(mPublicStreamType); 8816 } 8817 VolumeGroupState(AudioVolumeGroup avg)8818 private VolumeGroupState(AudioVolumeGroup avg) { 8819 mAudioVolumeGroup = avg; 8820 if (DEBUG_VOL) { 8821 Log.v(TAG, "VolumeGroupState for " + avg.toString()); 8822 } 8823 // mAudioAttributes is the default at this point 8824 for (AudioAttributes aa : avg.getAudioAttributes()) { 8825 if (!aa.equals(mAudioAttributes)) { 8826 mAudioAttributes = aa; 8827 break; 8828 } 8829 } 8830 int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes(); 8831 String streamSettingName = ""; 8832 if (streamTypes.length != 0) { 8833 // Uses already initialized MIN / MAX if a stream type is attached to group 8834 for (int streamType : streamTypes) { 8835 if (streamType != AudioSystem.STREAM_DEFAULT 8836 && streamType < AudioSystem.getNumStreamTypes()) { 8837 mPublicStreamType = streamType; 8838 mHasValidStreamType = true; 8839 streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType]; 8840 break; 8841 } 8842 } 8843 8844 if (replaceStreamBtSco()) { 8845 mIndexMin = getVssForStreamOrDefault(mPublicStreamType).getMinIndex() / 10; 8846 mIndexMax = getVssForStreamOrDefault(mPublicStreamType).getMaxIndex() / 10; 8847 } else { 8848 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType]; 8849 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType]; 8850 } 8851 } else if (!avg.getAudioAttributes().isEmpty()) { 8852 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes); 8853 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes); 8854 } else { 8855 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name() 8856 + " has neither valid attributes nor valid stream types assigned"); 8857 } 8858 mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name()); 8859 // Load volume indexes from data base 8860 readSettings(); 8861 } 8862 getLegacyStreamTypes()8863 public @NonNull int[] getLegacyStreamTypes() { 8864 return mAudioVolumeGroup.getLegacyStreamTypes(); 8865 } 8866 name()8867 public String name() { 8868 return mAudioVolumeGroup.name(); 8869 } 8870 getId()8871 public int getId() { 8872 return mAudioVolumeGroup.getId(); 8873 } 8874 8875 /** 8876 * Volume group with non null minimum index are considered as non mutable, thus 8877 * bijectivity is broken with potential associated stream type. 8878 * VOICE_CALL stream has minVolumeIndex > 0 but can be muted directly by an 8879 * app that has MODIFY_PHONE_STATE permission. 8880 */ isVssMuteBijective(int stream)8881 private boolean isVssMuteBijective(int stream) { 8882 return isStreamAffectedByMute(stream) 8883 && (getMinIndex() == (getVssForStreamOrDefault(stream).getMinIndex() + 5) / 10) 8884 && (getMinIndex() == 0 || isCallStream(stream)); 8885 } 8886 isMutable()8887 private boolean isMutable() { 8888 return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)); 8889 } 8890 /** 8891 * Mute/unmute the volume group 8892 * @param muted the new mute state 8893 */ 8894 @GuardedBy("AudioService.this.mVolumeStateLock") mute(boolean muted)8895 public boolean mute(boolean muted) { 8896 if (!isMutable()) { 8897 // Non mutable volume group 8898 if (DEBUG_VOL) { 8899 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 8900 } 8901 return false; 8902 } 8903 boolean changed = (mIsMuted != muted); 8904 // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default. 8905 if (changed) { 8906 mIsMuted = muted; 8907 applyAllVolumes(false /*userSwitch*/); 8908 } 8909 return changed; 8910 } 8911 isMuted()8912 public boolean isMuted() { 8913 return mIsMuted; 8914 } 8915 adjustVolume(int direction, int flags)8916 public void adjustVolume(int direction, int flags) { 8917 synchronized (mSettingsLock) { 8918 synchronized (mVolumeStateLock) { 8919 int device = getDeviceForVolume(); 8920 int previousIndex = getIndex(device); 8921 if (isMuteAdjust(direction) && !isMutable()) { 8922 // Non mutable volume group 8923 if (DEBUG_VOL) { 8924 Log.d(TAG, "invalid mute on unmutable volume group " + name()); 8925 } 8926 return; 8927 } 8928 8929 float stepFactor = getVssForStreamOrDefault( 8930 mPublicStreamType).getIndexStepFactor(); 8931 switch (direction) { 8932 case AudioManager.ADJUST_TOGGLE_MUTE: { 8933 // Note: If muted by volume 0, unmute will restore volume 0. 8934 mute(!mIsMuted); 8935 break; 8936 } 8937 case AudioManager.ADJUST_UNMUTE: 8938 // Note: If muted by volume 0, unmute will restore volume 0. 8939 mute(false); 8940 break; 8941 case AudioManager.ADJUST_MUTE: 8942 // May be already muted by setvolume 0, prevent from setting same value 8943 if (previousIndex != 0) { 8944 // bypass persist 8945 mute(true); 8946 } 8947 mIsMuted = true; 8948 break; 8949 case AudioManager.ADJUST_RAISE: 8950 // As for stream, RAISE during mute will increment the index 8951 setVolumeIndex(Math.min((int) ((previousIndex + 1) * stepFactor), 8952 mIndexMax), device, flags); 8953 break; 8954 case AudioManager.ADJUST_LOWER: 8955 // For stream, ADJUST_LOWER on a muted VSS is a no-op 8956 // If we decide to unmute on ADJUST_LOWER, cannot fallback on 8957 // adjustStreamVolume for group associated to legacy stream type 8958 if (isMuted() && previousIndex != 0) { 8959 mute(false); 8960 } else { 8961 int newIndex = Math.max((int) ((previousIndex - 1) * stepFactor), 8962 mIndexMin); 8963 setVolumeIndex(newIndex, device, flags); 8964 } 8965 break; 8966 } 8967 } 8968 } 8969 } 8970 getVolumeIndex()8971 public int getVolumeIndex() { 8972 synchronized (mVolumeStateLock) { 8973 return getIndex(getDeviceForVolume()); 8974 } 8975 } 8976 setVolumeIndex(int index, int flags)8977 public void setVolumeIndex(int index, int flags) { 8978 synchronized (mSettingsLock) { 8979 synchronized (mVolumeStateLock) { 8980 if (mUseFixedVolume) { 8981 return; 8982 } 8983 setVolumeIndex(index, getDeviceForVolume(), flags); 8984 } 8985 } 8986 } 8987 8988 @GuardedBy("AudioService.this.mVolumeStateLock") setVolumeIndex(int index, int device, int flags)8989 private void setVolumeIndex(int index, int device, int flags) { 8990 // Update cache & persist (muted by volume 0 shall be persisted) 8991 updateVolumeIndex(index, device); 8992 // setting non-zero volume for a muted stream unmutes the stream and vice versa, 8993 boolean changed = mute(index == 0); 8994 if (!changed) { 8995 // Set the volume index only if mute operation is a no-op 8996 index = getValidIndex(index); 8997 setVolumeIndexInt(index, device, flags); 8998 } 8999 } 9000 9001 @GuardedBy("AudioService.this.mVolumeStateLock") updateVolumeIndex(int index, int device)9002 public void updateVolumeIndex(int index, int device) { 9003 // Filter persistency if already exist and the index has not changed 9004 if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) { 9005 // Update local cache 9006 mIndexMap.put(device, getValidIndex(index)); 9007 9008 // update data base - post a persist volume group msg 9009 sendMsg(mAudioHandler, 9010 MSG_PERSIST_VOLUME_GROUP, 9011 SENDMSG_QUEUE, 9012 device, 9013 0, 9014 this, 9015 PERSIST_DELAY); 9016 } 9017 } 9018 9019 @GuardedBy("AudioService.this.mVolumeStateLock") setVolumeIndexInt(int index, int device, int flags)9020 private void setVolumeIndexInt(int index, int device, int flags) { 9021 // Reflect mute state of corresponding stream by forcing index to 0 if muted 9022 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 9023 // This allows RX path muting by the audio HAL only when explicitly muted but not when 9024 // index is just set to 0 to repect BT requirements 9025 boolean muted = false; 9026 if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType) 9027 && getVssForStreamOrDefault(mPublicStreamType).isFullyMuted()) { 9028 if (ringMyCar()) { 9029 muted = true; 9030 } else { 9031 index = 0; 9032 } 9033 } else if (isStreamBluetoothSco(mPublicStreamType) && index == 0) { 9034 index = 1; 9035 } 9036 9037 if (replaceStreamBtSco()) { 9038 index = (int) (mIndexMin + (index - mIndexMin) 9039 / getVssForStreamOrDefault(mPublicStreamType).getIndexStepFactor()); 9040 } 9041 9042 9043 if (DEBUG_VOL) { 9044 Log.d(TAG, "setVolumeIndexInt(" + mAudioVolumeGroup.getId() + ", " + index + ", " 9045 + muted + ", " + device + ")"); 9046 } 9047 9048 // Set the volume index 9049 mAudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, muted, device); 9050 } 9051 9052 @GuardedBy("AudioService.this.mVolumeStateLock") getIndex(int device)9053 private int getIndex(int device) { 9054 int index = mIndexMap.get(device, -1); 9055 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 9056 return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 9057 } 9058 9059 @GuardedBy("AudioService.this.mVolumeStateLock") hasIndexForDevice(int device)9060 private boolean hasIndexForDevice(int device) { 9061 return (mIndexMap.get(device, -1) != -1); 9062 } 9063 getMaxIndex()9064 public int getMaxIndex() { 9065 return mIndexMax; 9066 } 9067 getMinIndex()9068 public int getMinIndex() { 9069 return mIndexMin; 9070 } 9071 isValidStream(int stream)9072 private boolean isValidStream(int stream) { 9073 return (stream != AudioSystem.STREAM_DEFAULT) && getVssForStream(stream) != null; 9074 } 9075 isMusic()9076 public boolean isMusic() { 9077 return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC; 9078 } 9079 isVoiceCall()9080 public boolean isVoiceCall() { 9081 return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_VOICE_CALL; 9082 } 9083 applyAllVolumes(boolean userSwitch)9084 public void applyAllVolumes(boolean userSwitch) { 9085 String caller = "from vgs"; 9086 synchronized (mVolumeStateLock) { 9087 // apply device specific volumes first 9088 for (int i = 0; i < mIndexMap.size(); i++) { 9089 int device = mIndexMap.keyAt(i); 9090 int index = mIndexMap.valueAt(i); 9091 boolean synced = false; 9092 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 9093 for (int stream : getLegacyStreamTypes()) { 9094 if (isValidStream(stream)) { 9095 final VolumeStreamState vss = getVssForStreamOrDefault(stream); 9096 boolean streamMuted = vss.mIsMuted; 9097 int deviceForStream = getDeviceForStream(stream); 9098 int indexForStream = (vss.getIndex(deviceForStream) + 5) / 10; 9099 if (device == deviceForStream) { 9100 if (indexForStream == index && (isMuted() == streamMuted) 9101 && isVssMuteBijective(stream)) { 9102 synced = true; 9103 continue; 9104 } 9105 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 9106 vss.mute(isMuted(), "VGS.applyAllVolumes#1"); 9107 } 9108 if (indexForStream != index) { 9109 vss.setIndex(index * 10, device, 9110 caller, true /*hasModifyAudioSettings*/); 9111 } 9112 } 9113 } 9114 } 9115 if (!synced) { 9116 if (DEBUG_VOL) { 9117 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group " 9118 + mAudioVolumeGroup.name() + " and device " 9119 + AudioSystem.getOutputDeviceName(device)); 9120 } 9121 setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/); 9122 } 9123 } 9124 } 9125 // apply default volume last: by convention , default device volume will be used 9126 // by audio policy manager if no explicit volume is present for a given device type 9127 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 9128 boolean synced = false; 9129 int deviceForVolume = getDeviceForVolume(); 9130 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0); 9131 for (int stream : getLegacyStreamTypes()) { 9132 if (isValidStream(stream)) { 9133 final VolumeStreamState vss = getVssForStreamOrDefault(stream); 9134 boolean streamMuted = vss.mIsMuted; 9135 int defaultStreamIndex = (vss.getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5) 9136 / 10; 9137 if (forceDeviceSync) { 9138 vss.setIndex(index * 10, deviceForVolume, caller, 9139 true /*hasModifyAudioSettings*/); 9140 } 9141 if (defaultStreamIndex == index && (isMuted() == streamMuted) 9142 && isVssMuteBijective(stream)) { 9143 synced = true; 9144 continue; 9145 } 9146 if (defaultStreamIndex != index) { 9147 vss.setIndex(index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller, 9148 true /*hasModifyAudioSettings*/); 9149 } 9150 if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) { 9151 vss.mute(isMuted(), "VGS.applyAllVolumes#2"); 9152 } 9153 } 9154 } 9155 if (!synced) { 9156 if (DEBUG_VOL) { 9157 Log.d(TAG, "applyAllVolumes: apply default device index " + index 9158 + ", group " + mAudioVolumeGroup.name()); 9159 } 9160 setVolumeIndexInt( 9161 isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/); 9162 } 9163 if (forceDeviceSync) { 9164 if (DEBUG_VOL) { 9165 Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index 9166 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume) 9167 + ", group " + mAudioVolumeGroup.name()); 9168 } 9169 setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0); 9170 } 9171 } 9172 } 9173 clearIndexCache()9174 public void clearIndexCache() { 9175 mIndexMap.clear(); 9176 } 9177 getVolumePersistenceUserId()9178 private @UserIdInt int getVolumePersistenceUserId() { 9179 return isMusic() && !isPlatformAutomotive() 9180 ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT; 9181 } 9182 persistVolumeGroup(int device)9183 private void persistVolumeGroup(int device) { 9184 // No need to persist the index if the volume group is backed up 9185 // by a public stream type as this is redundant 9186 if (mUseFixedVolume || mHasValidStreamType) { 9187 return; 9188 } 9189 synchronized (mVolumeStateLock) { 9190 if (DEBUG_VOL) { 9191 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) 9192 + " for group " + mAudioVolumeGroup.name() 9193 + ", device " + AudioSystem.getOutputDeviceName(device) 9194 + " and User=" + getCurrentUserId() 9195 + " mSettingName: " + mSettingName); 9196 } 9197 9198 boolean success = mSettings.putSystemIntForUser(mContentResolver, 9199 getSettingNameForDevice(device), 9200 getIndex(device), 9201 getVolumePersistenceUserId()); 9202 if (!success) { 9203 Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name()); 9204 } 9205 } 9206 } 9207 readSettings()9208 public void readSettings() { 9209 synchronized (mVolumeStateLock) { 9210 // force maximum volume on all streams if fixed volume property is set 9211 if (mUseFixedVolume) { 9212 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 9213 return; 9214 } 9215 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 9216 // retrieve current volume for device 9217 // if no volume stored for current volume group and device, use default volume 9218 // if default device, continue otherwise 9219 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) 9220 ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1; 9221 int index; 9222 String name = getSettingNameForDevice(device); 9223 index = mSettings.getSystemIntForUser( 9224 mContentResolver, name, defaultIndex, 9225 getVolumePersistenceUserId()); 9226 if (index == -1) { 9227 continue; 9228 } 9229 if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED 9230 && mCameraSoundForced.get()) { 9231 index = mIndexMax; 9232 } 9233 if (DEBUG_VOL) { 9234 Log.v(TAG, "readSettings: found stored index " + getValidIndex(index) 9235 + " for group " + mAudioVolumeGroup.name() + ", device: " + name 9236 + ", User=" + getCurrentUserId()); 9237 } 9238 mIndexMap.put(device, getValidIndex(index)); 9239 } 9240 } 9241 } 9242 9243 @GuardedBy("AudioService.this.mVolumeStateLock") getValidIndex(int index)9244 private int getValidIndex(int index) { 9245 if (index < mIndexMin) { 9246 return mIndexMin; 9247 } else if (mUseFixedVolume || index > mIndexMax) { 9248 return mIndexMax; 9249 } 9250 return index; 9251 } 9252 getSettingNameForDevice(int device)9253 public @NonNull String getSettingNameForDevice(int device) { 9254 String suffix = AudioSystem.getOutputDeviceName(device); 9255 if (suffix.isEmpty()) { 9256 return mSettingName; 9257 } 9258 return mSettingName + "_" + AudioSystem.getOutputDeviceName(device); 9259 } 9260 setSettingName(String settingName)9261 void setSettingName(String settingName) { 9262 mSettingName = settingName; 9263 } 9264 getSettingName()9265 String getSettingName() { 9266 return mSettingName; 9267 } 9268 dump(PrintWriter pw)9269 private void dump(PrintWriter pw) { 9270 pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":"); 9271 pw.print(" Muted: "); 9272 pw.println(mIsMuted); 9273 pw.print(" Min: "); 9274 pw.println(mIndexMin); 9275 pw.print(" Max: "); 9276 pw.println(mIndexMax); 9277 pw.print(" Current: "); 9278 for (int i = 0; i < mIndexMap.size(); i++) { 9279 if (i > 0) { 9280 pw.print(", "); 9281 } 9282 int device = mIndexMap.keyAt(i); 9283 pw.print(Integer.toHexString(device)); 9284 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 9285 : AudioSystem.getOutputDeviceName(device); 9286 if (!deviceName.isEmpty()) { 9287 pw.print(" ("); 9288 pw.print(deviceName); 9289 pw.print(")"); 9290 } 9291 pw.print(": "); 9292 pw.print(mIndexMap.valueAt(i)); 9293 } 9294 pw.println(); 9295 pw.print(" Devices: "); 9296 int n = 0; 9297 int devices = getDeviceForVolume(); 9298 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 9299 if ((devices & device) == device) { 9300 if (n++ > 0) { 9301 pw.print(", "); 9302 } 9303 pw.print(AudioSystem.getOutputDeviceName(device)); 9304 } 9305 } 9306 pw.println(); 9307 pw.print(" Streams: "); 9308 Arrays.stream(getLegacyStreamTypes()) 9309 .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " ")); 9310 } 9311 } 9312 9313 // NOTE: Locking order for synchronized objects related to volume or ringer mode management: 9314 // 1 mScoclient OR mSafeMediaVolumeState 9315 // 2 mSetModeLock 9316 // 3 mSettingsLock 9317 // 4 mVolumeStateLock 9318 /*package*/ class VolumeStreamState { 9319 private final int mStreamType; 9320 private VolumeGroupState mVolumeGroupState = null; 9321 private int mIndexMin; 9322 // min index when user doesn't have permission to change audio settings 9323 private int mIndexMinNoPerm; 9324 private int mIndexMax; 9325 9326 /** 9327 * Variable used to determine the size of an incremental step when calling the 9328 * adjustStreamVolume methods with raise/lower adjustments. This can change dynamically 9329 * for some streams. 9330 * 9331 * <p>STREAM_VOICE_CALL has a different step value when is streaming on a SCO device. 9332 * Internally we are using the same volume range but through the step factor we force the 9333 * number of UI volume steps. 9334 */ 9335 private float mIndexStepFactor = 1.f; 9336 9337 private boolean mIsMuted = false; 9338 private boolean mIsMutedInternally = false; 9339 private String mVolumeIndexSettingName; 9340 @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>(); 9341 9342 private final SparseIntArray mIndexMap = new SparseIntArray(8) { 9343 @Override 9344 public void put(int key, int value) { 9345 super.put(key, value); 9346 record("put", key, value); 9347 if (cacheGetStreamVolume()) { 9348 if (DEBUG_VOL) { 9349 Log.d(TAG, "Clear volume cache after update index map"); 9350 } 9351 AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API); 9352 } 9353 } 9354 @Override 9355 public void setValueAt(int index, int value) { 9356 super.setValueAt(index, value); 9357 record("setValueAt", keyAt(index), value); 9358 if (cacheGetStreamVolume()) { 9359 if (DEBUG_VOL) { 9360 Log.d(TAG, "Clear volume cache after update index map"); 9361 } 9362 AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API); 9363 } 9364 } 9365 9366 // Record all changes in the VolumeStreamState 9367 private void record(String event, int key, int value) { 9368 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 9369 : AudioSystem.getOutputDeviceName(key); 9370 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR 9371 + AudioSystem.streamToString(mStreamType) 9372 + "." + device) 9373 .set(MediaMetrics.Property.EVENT, event) 9374 .set(MediaMetrics.Property.INDEX, value) 9375 .set(MediaMetrics.Property.MIN_INDEX, mIndexMin) 9376 .set(MediaMetrics.Property.MAX_INDEX, mIndexMax) 9377 .record(); 9378 } 9379 }; 9380 private final Intent mVolumeChanged; 9381 private final Bundle mVolumeChangedOptions; 9382 private final Intent mStreamDevicesChanged; 9383 private final Bundle mStreamDevicesChangedOptions; 9384 VolumeStreamState(String settingName, int streamType)9385 private VolumeStreamState(String settingName, int streamType) { 9386 mVolumeIndexSettingName = settingName; 9387 9388 mStreamType = streamType; 9389 mIndexMin = MIN_STREAM_VOLUME[streamType] * 10; 9390 mIndexMax = MAX_STREAM_VOLUME[streamType] * 10; 9391 9392 updateIndexFactors(); 9393 mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex() 9394 9395 readSettings(); 9396 mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); 9397 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 9398 final BroadcastOptions volumeChangedOptions = BroadcastOptions.makeBasic(); 9399 // This allows us to discard older broadcasts still waiting to be delivered 9400 // which have the same namespace (VOLUME_CHANGED_ACTION) and key (mStreamType). 9401 volumeChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT); 9402 volumeChangedOptions.setDeliveryGroupMatchingKey( 9403 AudioManager.VOLUME_CHANGED_ACTION, String.valueOf(mStreamType)); 9404 volumeChangedOptions.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 9405 mVolumeChangedOptions = volumeChangedOptions.toBundle(); 9406 9407 mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION); 9408 mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 9409 final BroadcastOptions streamDevicesChangedOptions = BroadcastOptions.makeBasic(); 9410 streamDevicesChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT); 9411 streamDevicesChangedOptions.setDeliveryGroupMatchingKey( 9412 AudioManager.STREAM_DEVICES_CHANGED_ACTION, String.valueOf(mStreamType)); 9413 streamDevicesChangedOptions.setDeferralPolicy( 9414 BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 9415 mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle(); 9416 } 9417 updateIndexFactors()9418 public void updateIndexFactors() { 9419 if (!replaceStreamBtSco() && !equalScoLeaVcIndexRange()) { 9420 return; 9421 } 9422 9423 // index values sent to APM are in the stream type SDK range, not *10 9424 int indexMinVolCurve = MIN_STREAM_VOLUME[mStreamType]; 9425 int indexMaxVolCurve = MAX_STREAM_VOLUME[mStreamType]; 9426 synchronized (this) { 9427 if (mStreamType == AudioSystem.STREAM_VOICE_CALL) { 9428 if (MAX_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO] 9429 > MAX_STREAM_VOLUME[mStreamType]) { 9430 mIndexMax = MAX_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO] * 10; 9431 } 9432 9433 if (!equalScoLeaVcIndexRange() && isStreamBluetoothSco(mStreamType)) { 9434 // SCO devices have a different min index 9435 mIndexMin = MIN_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO] * 10; 9436 indexMinVolCurve = MIN_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO]; 9437 indexMaxVolCurve = MAX_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO]; 9438 mIndexStepFactor = 1.f; 9439 } else if (equalScoLeaVcIndexRange() && isStreamBluetoothComm(mStreamType)) { 9440 // For non SCO devices the stream state does not change the min index 9441 if (mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) { 9442 mIndexMin = MIN_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO] * 10; 9443 indexMinVolCurve = MIN_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO]; 9444 indexMaxVolCurve = MAX_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO]; 9445 } else { 9446 mIndexMin = MIN_STREAM_VOLUME[mStreamType] * 10; 9447 } 9448 mIndexStepFactor = 1.f; 9449 } else { 9450 mIndexMin = MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 10; 9451 mIndexStepFactor = (float) (mIndexMax - mIndexMin) / (float) ( 9452 MAX_STREAM_VOLUME[mStreamType] * 10 9453 - MIN_STREAM_VOLUME[mStreamType] * 10); 9454 } 9455 9456 if (mVolumeGroupState != null) { 9457 mVolumeGroupState.mIndexMin = mIndexMin; 9458 } 9459 9460 mIndexMinNoPerm = mIndexMin; 9461 } 9462 } 9463 if (cacheGetStreamMinMaxVolume() && mStreamType == AudioSystem.STREAM_VOICE_CALL) { 9464 if (DEBUG_VOL) { 9465 Log.d(TAG, "Clear min volume cache from updateIndexFactors"); 9466 } 9467 AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API); 9468 } 9469 9470 final int status = AudioSystem.initStreamVolume( 9471 mStreamType, indexMinVolCurve, indexMaxVolCurve); 9472 sVolumeLogger.enqueue(new EventLogger.StringEvent( 9473 "updateIndexFactors() stream:" + mStreamType + " index min/max:" 9474 + mIndexMin / 10 + "/" + mIndexMax / 10 + " indexStepFactor:" 9475 + mIndexStepFactor).printSlog(ALOGI, TAG)); 9476 if (status != AudioSystem.AUDIO_STATUS_OK) { 9477 sVolumeLogger.enqueue(new EventLogger.StringEvent( 9478 "Failed initStreamVolume with status=" + status).printSlog(ALOGE, TAG)); 9479 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0, 9480 "updateIndexFactors()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 9481 } 9482 } 9483 9484 /** 9485 * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}. 9486 * <p> It helps to synchronize the index, mute attributes on the maching 9487 * {@link volumeGroupState} 9488 * @param volumeGroupState matching the {@link VolumeStreamState} 9489 */ setVolumeGroupState(VolumeGroupState volumeGroupState)9490 public void setVolumeGroupState(VolumeGroupState volumeGroupState) { 9491 mVolumeGroupState = volumeGroupState; 9492 if (mVolumeGroupState != null) { 9493 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 9494 } 9495 } 9496 getIndexStepFactor()9497 public float getIndexStepFactor() { 9498 return mIndexStepFactor; 9499 } 9500 9501 /** 9502 * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission 9503 * @param index minimum index expressed in "UI units", i.e. no 10x factor 9504 */ updateNoPermMinIndex(int index)9505 public void updateNoPermMinIndex(int index) { 9506 boolean changedNoPermMinIndex = 9507 cacheGetStreamMinMaxVolume() && (index * 10) != mIndexMinNoPerm; 9508 mIndexMinNoPerm = index * 10; 9509 if (mIndexMinNoPerm < mIndexMin) { 9510 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType); 9511 mIndexMinNoPerm = mIndexMin; 9512 } 9513 if (changedNoPermMinIndex) { 9514 if (DEBUG_VOL) { 9515 Log.d(TAG, "Clear min volume cache from updateNoPermMinIndex"); 9516 } 9517 AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API); 9518 } 9519 } 9520 9521 /** 9522 * Returns a list of devices associated with the stream type. 9523 * 9524 * This is a reference to the local list, do not modify. 9525 */ 9526 @GuardedBy("mVolumeStateLock") 9527 @NonNull observeDevicesForStream_syncVSS( boolean checkOthers)9528 public Set<Integer> observeDevicesForStream_syncVSS( 9529 boolean checkOthers) { 9530 if (!mSystemServer.isPrivileged()) { 9531 return new TreeSet<Integer>(); 9532 } 9533 final Set<Integer> deviceSet = 9534 getDeviceSetForStreamDirect(mStreamType); 9535 if (deviceSet.equals(mObservedDeviceSet)) { 9536 return mObservedDeviceSet; 9537 } 9538 9539 // Use legacy bit masks for message signalling. 9540 // TODO(b/185386781): message needs update since it uses devices bit-mask. 9541 final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet); 9542 final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet); 9543 9544 mObservedDeviceSet = deviceSet; 9545 if (checkOthers) { 9546 // one stream's devices have changed, check the others 9547 postObserveDevicesForAllStreams(mStreamType); 9548 } 9549 // log base stream changes to the event log 9550 if (sStreamVolumeAlias.get(mStreamType, /*valueIfKeyNotFound=*/-1) == mStreamType) { 9551 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices); 9552 } 9553 // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after 9554 // the postObserveDevicesForStreams is handled 9555 final SomeArgs args = SomeArgs.obtain(); 9556 args.arg1 = mStreamDevicesChanged; 9557 args.arg2 = mStreamDevicesChangedOptions; 9558 sendMsg(mAudioHandler, 9559 MSG_STREAM_DEVICES_CHANGED, 9560 SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/, 9561 // ok to send reference to this object, it is final 9562 args /*obj*/, 0 /*delay*/); 9563 return mObservedDeviceSet; 9564 } 9565 getSettingNameForDevice(int device)9566 public @Nullable String getSettingNameForDevice(int device) { 9567 if (!hasValidSettingsName()) { 9568 return null; 9569 } 9570 final String suffix = AudioSystem.getOutputDeviceName(device); 9571 if (suffix.isEmpty()) { 9572 return mVolumeIndexSettingName; 9573 } 9574 return mVolumeIndexSettingName + "_" + suffix; 9575 } 9576 hasValidSettingsName()9577 private boolean hasValidSettingsName() { 9578 return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty()); 9579 } 9580 setSettingName(String settingName)9581 void setSettingName(String settingName) { 9582 mVolumeIndexSettingName = settingName; 9583 if (mVolumeGroupState != null) { 9584 mVolumeGroupState.setSettingName(mVolumeIndexSettingName); 9585 } 9586 } 9587 getSettingName()9588 String getSettingName() { 9589 return mVolumeIndexSettingName; 9590 } 9591 readSettings()9592 public void readSettings() { 9593 synchronized (mVolumeStateLock) { 9594 // force maximum volume on all streams if fixed volume property is set 9595 if (mUseFixedVolume) { 9596 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 9597 return; 9598 } 9599 // do not read system stream volume from settings: this stream is always aliased 9600 // to another stream type and its volume is never persisted. Values in settings can 9601 // only be stale values 9602 if ((mStreamType == AudioSystem.STREAM_SYSTEM) 9603 || (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) { 9604 int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType]; 9605 if (mCameraSoundForced.get()) { 9606 index = mIndexMax; 9607 } 9608 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index); 9609 return; 9610 } 9611 9612 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) { 9613 9614 // retrieve current volume for device 9615 // if no volume stored for current stream and device, use default volume if default 9616 // device, continue otherwise 9617 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? 9618 AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1; 9619 int index; 9620 if (!hasValidSettingsName()) { 9621 index = defaultIndex; 9622 } else { 9623 String name = getSettingNameForDevice(device); 9624 index = mSettings.getSystemIntForUser( 9625 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); 9626 } 9627 if (index == -1) { 9628 continue; 9629 } 9630 9631 mIndexMap.put(device, getValidIndex(10 * index, 9632 true /*hasModifyAudioSettings*/)); 9633 } 9634 } 9635 } 9636 9637 /** 9638 * Sends the new volume index on the given device to native. 9639 * 9640 * <p>Make sure the index is consistent with the muting state. When ringMyCar is enabled 9641 * will send the non-zero index together with muted state. Otherwise, index 0 will be sent 9642 * to native for signalising a muted stream. 9643 **/ 9644 @GuardedBy("mVolumeStateLock") setStreamVolumeIndex(int index, int device)9645 private void setStreamVolumeIndex(int index, int device) { 9646 // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted. 9647 // This allows RX path muting by the audio HAL only when explicitly muted but not when 9648 // index is just set to 0 to respect BT requirements 9649 if (isStreamBluetoothSco(mStreamType) && index == 0 && !isFullyMuted()) { 9650 index = 1; 9651 } 9652 9653 if (replaceStreamBtSco() && index != 0) { 9654 index = (int) (mIndexMin + (index * 10 - mIndexMin) / getIndexStepFactor() + 5) 9655 / 10; 9656 } 9657 9658 boolean muted = ringMyCar() ? isFullyMuted() : false; 9659 if (DEBUG_VOL) { 9660 Log.d(TAG, "setStreamVolumeIndexAS(streamType=" + mStreamType + ", index=" + index 9661 + ", muted=" + muted + ", device=" + device + ")"); 9662 } 9663 mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, muted, device); 9664 } 9665 9666 // must be called while synchronized mVolumeStateLock 9667 @GuardedBy("mVolumeStateLock") applyDeviceVolume_syncVSS(int device)9668 /*package*/ void applyDeviceVolume_syncVSS(int device) { 9669 int index; 9670 if (isFullyMuted() && !ringMyCar()) { 9671 index = 0; 9672 } else if (isAbsoluteVolumeDevice(device) 9673 || isA2dpAbsoluteVolumeDevice(device) 9674 || AudioSystem.isLeAudioDeviceType(device)) { 9675 // do not change the volume logic for dynamic abs behavior devices like HDMI 9676 if (isAbsoluteVolumeDevice(device)) { 9677 index = (mIndexMax + 5) / 10; 9678 } else { 9679 index = (getIndex(device) + 5) / 10; 9680 } 9681 } else if (isFullVolumeDevice(device)) { 9682 index = (mIndexMax + 5)/10; 9683 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 9684 index = (getIndex(device) + 5) / 10; 9685 } else { 9686 index = (getIndex(device) + 5)/10; 9687 } 9688 9689 setStreamVolumeIndex(index, device); 9690 } 9691 applyAllVolumes()9692 public void applyAllVolumes() { 9693 synchronized (mVolumeStateLock) { 9694 // apply device specific volumes first 9695 int index; 9696 boolean isAbsoluteVolume = false; 9697 for (int i = 0; i < mIndexMap.size(); i++) { 9698 final int device = mIndexMap.keyAt(i); 9699 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 9700 if (isFullyMuted() && !ringMyCar()) { 9701 index = 0; 9702 } else if (isAbsoluteVolumeDevice(device) 9703 || isA2dpAbsoluteVolumeDevice(device) 9704 || AudioSystem.isLeAudioDeviceType(device)) { 9705 isAbsoluteVolume = true; 9706 // do not change the volume logic for dynamic abs behavior devices 9707 // like HDMI 9708 if (isAbsoluteVolumeDevice(device)) { 9709 index = (mIndexMax + 5) / 10; 9710 } else { 9711 index = (getIndex(device) + 5) / 10; 9712 } 9713 } else if (isFullVolumeDevice(device)) { 9714 index = (mIndexMax + 5)/10; 9715 } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) { 9716 isAbsoluteVolume = true; 9717 index = (getIndex(device) + 5) / 10; 9718 } else { 9719 index = (mIndexMap.valueAt(i) + 5)/10; 9720 } 9721 9722 if (mStreamType == AudioSystem.STREAM_MUSIC) { 9723 sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, 9724 SENDMSG_QUEUE, device, isAbsoluteVolume ? 1 : 0, this, 9725 /*delay=*/0); 9726 } 9727 9728 setStreamVolumeIndex(index, device); 9729 } 9730 } 9731 // apply default volume last: by convention , default device volume will be used 9732 // by audio policy manager if no explicit volume is present for a given device type 9733 if (isFullyMuted() && !ringMyCar()) { 9734 index = 0; 9735 } else { 9736 index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10; 9737 } 9738 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT); 9739 } 9740 } 9741 adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)9742 public boolean adjustIndex(int deltaIndex, int device, String caller, 9743 boolean hasModifyAudioSettings) { 9744 return setIndex(getIndex(device) + deltaIndex, device, caller, 9745 hasModifyAudioSettings); 9746 } 9747 setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)9748 public boolean setIndex(int index, int device, String caller, 9749 boolean hasModifyAudioSettings) { 9750 boolean changed; 9751 int oldIndex; 9752 final boolean isCurrentDevice; 9753 final StringBuilder aliasStreamIndexes = new StringBuilder(); 9754 synchronized (mSettingsLock) { 9755 synchronized (mVolumeStateLock) { 9756 oldIndex = getIndex(device); 9757 index = getValidIndex(index, hasModifyAudioSettings); 9758 // for STREAM_SYSTEM_ENFORCED, do not sync aliased streams on the enforced index 9759 int aliasIndex = index; 9760 if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) 9761 && mCameraSoundForced.get()) { 9762 index = mIndexMax; 9763 } 9764 mIndexMap.put(device, index); 9765 9766 changed = oldIndex != index; 9767 // Apply change to all streams using this one as alias if: 9768 // - the index actually changed OR 9769 // - there is no volume index stored for this device on alias stream. 9770 // If changing volume of current device, also change volume of current 9771 // device on aliased stream 9772 isCurrentDevice = (device == getDeviceForStream(mStreamType)); 9773 final int numStreamTypes = AudioSystem.getNumStreamTypes(); 9774 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 9775 final VolumeStreamState aliasStreamState = getVssForStream(streamType); 9776 if (aliasStreamState != null && streamType != mStreamType 9777 && sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound*/-1) 9778 == mStreamType && (changed || !aliasStreamState.hasIndexForDevice( 9779 device))) { 9780 final int scaledIndex = 9781 rescaleIndex(aliasIndex, mStreamType, streamType); 9782 boolean changedAlias = aliasStreamState.setIndex(scaledIndex, device, 9783 caller, hasModifyAudioSettings); 9784 if (isCurrentDevice) { 9785 changedAlias |= aliasStreamState.setIndex(scaledIndex, 9786 getDeviceForStream(streamType), caller, 9787 hasModifyAudioSettings); 9788 } 9789 if (changedAlias) { 9790 aliasStreamIndexes.append(AudioSystem.streamToString(streamType)) 9791 .append(":").append((scaledIndex + 5) / 10).append(" "); 9792 } 9793 } 9794 } 9795 // Mirror changes in SPEAKER ringtone volume on SCO when 9796 if (changed && mStreamType == AudioSystem.STREAM_RING 9797 && device == AudioSystem.DEVICE_OUT_SPEAKER) { 9798 for (int i = 0; i < mIndexMap.size(); i++) { 9799 int otherDevice = mIndexMap.keyAt(i); 9800 if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) { 9801 mIndexMap.put(otherDevice, index); 9802 } 9803 } 9804 } 9805 if (changed) { 9806 // If associated to volume group, update group cache 9807 updateVolumeGroupIndex(device, /* forceMuteState= */ false); 9808 9809 oldIndex = (oldIndex + 5) / 10; 9810 index = (index + 5) / 10; 9811 // log base stream changes to the event log 9812 if (sStreamVolumeAlias.get(mStreamType, /*valueIfKeyNotFound=*/-1) 9813 == mStreamType) { 9814 if (caller == null) { 9815 Log.w(TAG, "No caller for volume_changed event", new Throwable()); 9816 } 9817 EventLogTags.writeVolumeChanged( 9818 mStreamType, oldIndex, index, mIndexMax / 10, caller); 9819 } 9820 // fire changed intents for all streams, but only when the device it changed 9821 // on 9822 // is the current device 9823 if ((index != oldIndex) && isCurrentDevice) { 9824 // for single volume devices, only send the volume change broadcast 9825 // on the alias stream 9826 final int streamAlias = 9827 sStreamVolumeAlias.get(mStreamType, /*valueIfKeyNotFound=*/-1); 9828 if (!mIsSingleVolume || streamAlias == mStreamType) { 9829 mVolumeChanged.putExtra( 9830 AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); 9831 mVolumeChanged.putExtra( 9832 AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); 9833 int extraStreamType = mStreamType; 9834 // TODO: remove this when deprecating STREAM_BLUETOOTH_SCO 9835 if (isStreamBluetoothSco(mStreamType)) { 9836 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, 9837 AudioSystem.STREAM_BLUETOOTH_SCO); 9838 extraStreamType = AudioSystem.STREAM_BLUETOOTH_SCO; 9839 } else { 9840 mVolumeChanged.putExtra( 9841 AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 9842 } 9843 mVolumeChanged.putExtra( 9844 AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, streamAlias); 9845 9846 if (mStreamType == streamAlias) { 9847 String aliasStreamIndexesString = ""; 9848 if (!aliasStreamIndexes.isEmpty()) { 9849 aliasStreamIndexesString = 9850 " aliased streams: " + aliasStreamIndexes; 9851 } 9852 AudioService.sVolumeLogger.enqueue( 9853 new VolChangedBroadcastEvent(extraStreamType, 9854 aliasStreamIndexesString, index, oldIndex)); 9855 if (extraStreamType != mStreamType) { 9856 AudioService.sVolumeLogger.enqueue( 9857 new VolChangedBroadcastEvent(mStreamType, 9858 aliasStreamIndexesString, index, oldIndex)); 9859 } 9860 } 9861 sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions); 9862 if (extraStreamType != mStreamType) { 9863 // send multiple intents in case we merged voice call and bt sco 9864 // streams 9865 mVolumeChanged.putExtra( 9866 AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 9867 // do not use the options in thid case which could discard 9868 // the previous intent 9869 sendBroadcastToAll(mVolumeChanged, null); 9870 } 9871 } 9872 } 9873 } 9874 return changed; 9875 } 9876 } 9877 } 9878 getIndex(int device)9879 public int getIndex(int device) { 9880 synchronized (mVolumeStateLock) { 9881 int index = mIndexMap.get(device, -1); 9882 if (index == -1) { 9883 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 9884 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 9885 } 9886 return index; 9887 } 9888 } 9889 getVolumeInfo(int device)9890 public @NonNull VolumeInfo getVolumeInfo(int device) { 9891 synchronized (mVolumeStateLock) { 9892 int index = mIndexMap.get(device, -1); 9893 if (index == -1) { 9894 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 9895 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 9896 } 9897 final VolumeInfo vi = new VolumeInfo.Builder(mStreamType) 9898 .setMinVolumeIndex(getMinIndex()) 9899 .setMaxVolumeIndex(getMaxIndex()) 9900 .setVolumeIndex(index) 9901 .setMuted(isFullyMuted()) 9902 .build(); 9903 return vi; 9904 } 9905 } 9906 hasIndexForDevice(int device)9907 public boolean hasIndexForDevice(int device) { 9908 synchronized (mVolumeStateLock) { 9909 return (mIndexMap.get(device, -1) != -1); 9910 } 9911 } 9912 getMaxIndex()9913 public int getMaxIndex() { 9914 return mIndexMax; 9915 } 9916 9917 /** 9918 * @return the lowest index regardless of permissions 9919 */ getMinIndex()9920 public int getMinIndex() { 9921 return mIndexMin; 9922 } 9923 9924 /** 9925 * @param isPrivileged true if the caller is privileged and not subject to minimum 9926 * volume index thresholds 9927 * @return the lowest index that this caller can set or adjust to 9928 */ getMinIndex(boolean isPrivileged)9929 public int getMinIndex(boolean isPrivileged) { 9930 return isPrivileged ? mIndexMin : mIndexMinNoPerm; 9931 } 9932 9933 /** 9934 * Copies all device/index pairs from the given VolumeStreamState after initializing 9935 * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState 9936 * has the same stream type as this instance. 9937 * @param srcStream 9938 * @param caller 9939 */ 9940 // must be sync'd on mSettingsLock before mVolumeStateLock 9941 @GuardedBy("mVolumeStateLock") setAllIndexes(VolumeStreamState srcStream, String caller)9942 public void setAllIndexes(VolumeStreamState srcStream, String caller) { 9943 if (srcStream == null || mStreamType == srcStream.mStreamType) { 9944 return; 9945 } 9946 int srcStreamType = srcStream.getStreamType(); 9947 // apply default device volume from source stream to all devices first in case 9948 // some devices are present in this stream state but not in source stream state 9949 int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 9950 index = rescaleIndex(index, srcStreamType, mStreamType); 9951 for (int i = 0; i < mIndexMap.size(); i++) { 9952 mIndexMap.put(mIndexMap.keyAt(i), index); 9953 } 9954 // Now apply actual volume for devices in source stream state 9955 SparseIntArray srcMap = srcStream.mIndexMap; 9956 for (int i = 0; i < srcMap.size(); i++) { 9957 int device = srcMap.keyAt(i); 9958 index = srcMap.valueAt(i); 9959 index = rescaleIndex(index, srcStreamType, mStreamType); 9960 9961 setIndex(index, device, caller, true /*hasModifyAudioSettings*/); 9962 } 9963 } 9964 9965 // must be sync'd on mSettingsLock before mVolumeStateLock 9966 @GuardedBy("mVolumeStateLock") setAllIndexesToMax()9967 public void setAllIndexesToMax() { 9968 for (int i = 0; i < mIndexMap.size(); i++) { 9969 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax); 9970 } 9971 } 9972 9973 // If associated to volume group, update group cache updateVolumeGroupIndex(int device, boolean forceMuteState)9974 private void updateVolumeGroupIndex(int device, boolean forceMuteState) { 9975 // need mSettingsLock when called from setIndex for vgs.mute -> vgs.applyAllVolumes -> 9976 // vss.setIndex which grabs this lock after VSS.class. Locking order needs to be 9977 // preserved 9978 synchronized (mSettingsLock) { 9979 synchronized (mVolumeStateLock) { 9980 if (mVolumeGroupState != null) { 9981 int groupIndex = (getIndex(device) + 5) / 10; 9982 if (DEBUG_VOL) { 9983 Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType 9984 + ", muted=" + mIsMuted + ", device=" + device + ", index=" 9985 + getIndex(device) + ", group " + mVolumeGroupState.name() 9986 + " Muted=" + mVolumeGroupState.isMuted() + ", Index=" 9987 + groupIndex + ", forceMuteState=" + forceMuteState); 9988 } 9989 mVolumeGroupState.updateVolumeIndex(groupIndex, device); 9990 // Only propage mute of stream when applicable 9991 if (isMutable()) { 9992 // For call stream, align mute only when muted, not when index is set to 9993 // 0 9994 mVolumeGroupState.mute( 9995 forceMuteState ? mIsMuted : 9996 (groupIndex == 0 && !isCallStream(mStreamType)) 9997 || mIsMuted); 9998 } 9999 } 10000 } 10001 } 10002 } 10003 10004 /** 10005 * Mute/unmute the stream 10006 * @param state the new mute state 10007 * @return true if the mute state was changed 10008 */ mute(boolean state, String source)10009 public boolean mute(boolean state, String source) { 10010 boolean changed = false; 10011 synchronized (mVolumeStateLock) { 10012 changed = mute(state, true, source); 10013 } 10014 if (changed) { 10015 broadcastMuteSetting(mStreamType, state); 10016 } 10017 return changed; 10018 } 10019 10020 /** 10021 * Mute/unmute the stream by AudioService 10022 * @param state the new mute state 10023 * @return true if the mute state was changed 10024 */ muteInternally(boolean state)10025 public boolean muteInternally(boolean state) { 10026 boolean changed = false; 10027 synchronized (mVolumeStateLock) { 10028 if (state != mIsMutedInternally) { 10029 changed = true; 10030 mIsMutedInternally = state; 10031 // mute immediately to avoid delay and preemption when using a message. 10032 applyAllVolumes(); 10033 } 10034 } 10035 if (changed) { 10036 sVolumeLogger.enqueue(new VolumeEvent( 10037 VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state)); 10038 } 10039 return changed; 10040 } 10041 10042 @GuardedBy("mVolumeStateLock") isFullyMuted()10043 public boolean isFullyMuted() { 10044 return mIsMuted || mIsMutedInternally; 10045 } 10046 10047 isMutable()10048 private boolean isMutable() { 10049 return isStreamAffectedByMute(mStreamType) 10050 && (mIndexMin == 0 || isCallStream(mStreamType)); 10051 } 10052 10053 /** 10054 * Mute/unmute the stream 10055 * @param state the new mute state 10056 * @param apply true to propagate to HW, or false just to update the cache. May be needed 10057 * to mute a stream and its aliases as applyAllVolume will force settings to aliases. 10058 * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume} 10059 * @return true if the mute state was changed 10060 */ mute(boolean state, boolean apply, String src)10061 public boolean mute(boolean state, boolean apply, String src) { 10062 boolean changed; 10063 synchronized (mVolumeStateLock) { 10064 changed = state != mIsMuted; 10065 if (changed) { 10066 sMuteLogger.enqueue( 10067 new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src)); 10068 // check to see if unmuting should not have happened due to ringer muted streams 10069 if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) { 10070 Slog.e(TAG, "Attempt to unmute stream " + mStreamType 10071 + " despite ringer-zen muted stream 0x" 10072 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams), 10073 new Exception()); // this will put a stack trace in the logs 10074 sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent( 10075 mStreamType, AudioService.sRingerAndZenModeMutedStreams)); 10076 // do not change mute state 10077 return false; 10078 } 10079 mIsMuted = state; 10080 if (apply) { 10081 doMute(); 10082 } 10083 } 10084 } 10085 10086 if (cacheGetStreamVolume() && changed) { 10087 if (DEBUG_VOL) { 10088 Log.d(TAG, "Clear volume cache after changing mute state"); 10089 } 10090 AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API); 10091 } 10092 10093 return changed; 10094 } 10095 doMute()10096 public void doMute() { 10097 synchronized (mVolumeStateLock) { 10098 // If associated to volume group, update group cache 10099 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */true); 10100 10101 // Set the new mute volume. This propagates the values to 10102 // the audio system, otherwise the volume won't be changed 10103 // at the lower level. 10104 sendMsg(mAudioHandler, 10105 MSG_SET_ALL_VOLUMES, 10106 SENDMSG_QUEUE, 10107 0, 10108 0, 10109 this, 0); 10110 } 10111 } 10112 getStreamType()10113 public int getStreamType() { 10114 return mStreamType; 10115 } 10116 checkFixedVolumeDevices()10117 public void checkFixedVolumeDevices() { 10118 synchronized (mVolumeStateLock) { 10119 // ignore settings for fixed volume devices: volume should always be at max or 0 10120 if (sStreamVolumeAlias.get(mStreamType) == AudioSystem.STREAM_MUSIC) { 10121 for (int i = 0; i < mIndexMap.size(); i++) { 10122 int device = mIndexMap.keyAt(i); 10123 int index = mIndexMap.valueAt(i); 10124 if (isFullVolumeDevice(device) 10125 || (isFixedVolumeDevice(device) && index != 0)) { 10126 mIndexMap.put(device, mIndexMax); 10127 } 10128 applyDeviceVolume_syncVSS(device); 10129 } 10130 } 10131 } 10132 } 10133 getValidIndex(int index, boolean hasModifyAudioSettings)10134 private int getValidIndex(int index, boolean hasModifyAudioSettings) { 10135 final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm; 10136 if (index < indexMin) { 10137 return indexMin; 10138 } else if (mUseFixedVolume || index > mIndexMax) { 10139 return mIndexMax; 10140 } 10141 10142 return index; 10143 } 10144 dump(PrintWriter pw)10145 private void dump(PrintWriter pw) { 10146 pw.print(" Muted: "); 10147 pw.println(mIsMuted); 10148 pw.print(" Muted Internally: "); 10149 pw.println(mIsMutedInternally); 10150 pw.print(" Min: "); 10151 pw.print((mIndexMin + 5) / 10); 10152 if (mIndexMin != mIndexMinNoPerm) { 10153 pw.print(" w/o perm:"); 10154 pw.println((mIndexMinNoPerm + 5) / 10); 10155 } else { 10156 pw.println(); 10157 } 10158 pw.print(" Max: "); 10159 pw.println((mIndexMax + 5) / 10); 10160 pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType)); 10161 pw.print(" Current: "); 10162 for (int i = 0; i < mIndexMap.size(); i++) { 10163 if (i > 0) { 10164 pw.print(", "); 10165 } 10166 final int device = mIndexMap.keyAt(i); 10167 pw.print(Integer.toHexString(device)); 10168 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 10169 : AudioSystem.getOutputDeviceName(device); 10170 if (!deviceName.isEmpty()) { 10171 pw.print(" ("); 10172 pw.print(deviceName); 10173 pw.print(")"); 10174 } 10175 pw.print(": "); 10176 final int index = (mIndexMap.valueAt(i) + 5) / 10; 10177 pw.print(index); 10178 } 10179 pw.println(); 10180 pw.print(" Devices: "); 10181 pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType))); 10182 pw.println(); 10183 pw.print(" Volume Group: "); 10184 pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a"); 10185 } 10186 } 10187 10188 /** Thread that handles native AudioSystem control. */ 10189 private class AudioSystemThread extends Thread { AudioSystemThread()10190 AudioSystemThread() { 10191 super("AudioService"); 10192 } 10193 10194 @Override run()10195 public void run() { 10196 // Set this thread up so the handler will work on it 10197 Looper.prepare(); 10198 10199 synchronized(AudioService.this) { 10200 mAudioHandler = new AudioHandler(); 10201 10202 // Notify that the handler has been created 10203 AudioService.this.notify(); 10204 } 10205 10206 // Listen for volume change requests that are set by VolumePanel 10207 Looper.loop(); 10208 } 10209 } 10210 10211 private static final class DeviceVolumeUpdate { 10212 final int mStreamType; 10213 final int mDevice; 10214 final @NonNull String mCaller; 10215 private static final int NO_NEW_INDEX = -2049; 10216 private final int mVssVolIndex; 10217 10218 // Constructor with volume index, meant to cause this volume to be set and applied for the 10219 // given stream type on the given device DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)10220 DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) { 10221 mStreamType = streamType; 10222 mVssVolIndex = vssVolIndex; 10223 mDevice = device; 10224 mCaller = caller; 10225 } 10226 10227 // Constructor with no volume index, meant to cause re-apply of volume for the given 10228 // stream type on the given device DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)10229 DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) { 10230 mStreamType = streamType; 10231 mVssVolIndex = NO_NEW_INDEX; 10232 mDevice = device; 10233 mCaller = caller; 10234 } 10235 hasVolumeIndex()10236 boolean hasVolumeIndex() { 10237 return mVssVolIndex != NO_NEW_INDEX; 10238 } 10239 getVolumeIndex()10240 int getVolumeIndex() throws IllegalStateException { 10241 Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX); 10242 return mVssVolIndex; 10243 } 10244 } 10245 10246 /** only public for mocking/spying, do not call outside of AudioService */ 10247 @VisibleForTesting postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)10248 public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, 10249 String caller) { 10250 sendMsg(mAudioHandler, 10251 MSG_SET_DEVICE_STREAM_VOLUME, 10252 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 10253 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller), 10254 0 /*delay*/); 10255 } 10256 postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)10257 /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) { 10258 sendMsg(mAudioHandler, 10259 MSG_SET_DEVICE_STREAM_VOLUME, 10260 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, 10261 new DeviceVolumeUpdate(streamType, device, caller), 10262 0 /*delay*/); 10263 } 10264 onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)10265 private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) { 10266 final VolumeStreamState streamState = getVssForStream(update.mStreamType); 10267 if (streamState == null) { 10268 Log.w(TAG, "Invalid onSetVolumeIndexOnDevice for stream type " + update.mStreamType); 10269 return; 10270 } 10271 if (update.hasVolumeIndex()) { 10272 int index = update.getVolumeIndex(); 10273 if (mSoundDoseHelper.checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) { 10274 index = mSoundDoseHelper.safeMediaVolumeIndex(update.mDevice); 10275 } 10276 streamState.setIndex(index, update.mDevice, update.mCaller, 10277 // trusted as index is always validated before message is posted 10278 true /*hasModifyAudioSettings*/); 10279 sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller + " dev:0x" 10280 + Integer.toHexString(update.mDevice) + " volIdx:" + index)); 10281 } else { 10282 sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller 10283 + " update vol on dev:0x" + Integer.toHexString(update.mDevice))); 10284 } 10285 setDeviceVolume(streamState, update.mDevice); 10286 } 10287 setDeviceVolume(VolumeStreamState streamState, int device)10288 /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) { 10289 synchronized (mVolumeStateLock) { 10290 sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_QUEUE, 10291 device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device) 10292 || AudioSystem.isLeAudioDeviceType(device) ? 1 : 0), 10293 streamState, /*delay=*/0); 10294 // Apply volume 10295 streamState.applyDeviceVolume_syncVSS(device); 10296 10297 // Apply change to all streams using this one as alias 10298 int numStreamTypes = AudioSystem.getNumStreamTypes(); 10299 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 10300 final VolumeStreamState vss = getVssForStream(streamType); 10301 if (vss != null && streamType != streamState.mStreamType 10302 && sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1) 10303 == streamState.mStreamType) { 10304 // Make sure volume is also maxed out on A2DP device for aliased stream 10305 // that may have a different device selected 10306 int streamDevice = getDeviceForStream(streamType); 10307 if ((device != streamDevice) 10308 && (isAbsoluteVolumeDevice(device) 10309 || isA2dpAbsoluteVolumeDevice(device) 10310 || AudioSystem.isLeAudioDeviceType(device))) { 10311 vss.applyDeviceVolume_syncVSS(device); 10312 } 10313 vss.applyDeviceVolume_syncVSS(streamDevice); 10314 } 10315 } 10316 } 10317 // Post a persist volume msg 10318 sendMsg(mAudioHandler, 10319 MSG_PERSIST_VOLUME, 10320 SENDMSG_QUEUE, 10321 device, 10322 0, 10323 streamState, 10324 PERSIST_DELAY); 10325 10326 } 10327 10328 /** Handles internal volume messages in separate volume thread. */ 10329 /*package*/ class AudioHandler extends Handler { 10330 AudioHandler()10331 AudioHandler() { 10332 super(); 10333 } 10334 AudioHandler(Looper looper)10335 AudioHandler(Looper looper) { 10336 super(looper); 10337 } 10338 setAllVolumes(VolumeStreamState streamState)10339 private void setAllVolumes(VolumeStreamState streamState) { 10340 10341 // Apply volume 10342 streamState.applyAllVolumes(); 10343 10344 // Apply change to all streams using this one as alias 10345 int numStreamTypes = AudioSystem.getNumStreamTypes(); 10346 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 10347 final VolumeStreamState vss = getVssForStream(streamType); 10348 if (vss != null && streamType != streamState.mStreamType 10349 && sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1) 10350 == streamState.mStreamType) { 10351 vss.applyAllVolumes(); 10352 } 10353 } 10354 } 10355 persistVolume(VolumeStreamState streamState, int device)10356 private void persistVolume(VolumeStreamState streamState, int device) { 10357 if (mUseFixedVolume) { 10358 return; 10359 } 10360 if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) { 10361 return; 10362 } 10363 10364 // Persisting STREAM_SYSTEM_ENFORCED index is not needed as its alias (STREAM_RING) 10365 // is persisted. This can also be problematic when the enforcement is active as it will 10366 // override current SYSTEM_RING persisted value given they share the same settings name 10367 // (due to aliasing). 10368 if (streamState.mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) { 10369 return; 10370 } 10371 if (streamState.hasValidSettingsName()) { 10372 mSettings.putSystemIntForUser(mContentResolver, 10373 streamState.getSettingNameForDevice(device), 10374 (streamState.getIndex(device) + 5) / 10, 10375 UserHandle.USER_CURRENT); 10376 } 10377 } 10378 persistRingerMode(int ringerMode)10379 private void persistRingerMode(int ringerMode) { 10380 if (mUseFixedVolume) { 10381 return; 10382 } 10383 mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode); 10384 } 10385 onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)10386 private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc, 10387 @AudioManager.VolumeAdjustment int direction) { 10388 try { 10389 apc.notifyVolumeAdjust(direction); 10390 } catch(Exception e) { 10391 // nothing we can do about this. Do not log error, too much potential for spam 10392 } 10393 } 10394 10395 @Override handleMessage(Message msg)10396 public void handleMessage(Message msg) { 10397 switch (msg.what) { 10398 10399 case MSG_SET_DEVICE_VOLUME: 10400 setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1); 10401 break; 10402 10403 case MSG_SET_ALL_VOLUMES: 10404 setAllVolumes((VolumeStreamState) msg.obj); 10405 break; 10406 10407 case MSG_PERSIST_VOLUME: 10408 persistVolume((VolumeStreamState) msg.obj, msg.arg1); 10409 break; 10410 10411 case MSG_PERSIST_VOLUME_GROUP: 10412 final VolumeGroupState vgs = (VolumeGroupState) msg.obj; 10413 vgs.persistVolumeGroup(msg.arg1); 10414 break; 10415 10416 case MSG_APPLY_INPUT_GAIN_INDEX: 10417 onApplyInputGainIndex((AudioDeviceAttributes) msg.obj, msg.arg1); 10418 break; 10419 10420 case MSG_PERSIST_INPUT_GAIN_INDEX: 10421 onPersistInputGainIndex((AudioDeviceAttributes) msg.obj); 10422 break; 10423 10424 case MSG_PERSIST_RINGER_MODE: 10425 // note that the value persisted is the current ringer mode, not the 10426 // value of ringer mode as of the time the request was made to persist 10427 persistRingerMode(getRingerModeInternal()); 10428 break; 10429 10430 case MSG_AUDIO_SERVER_DIED: 10431 onAudioServerDied(); 10432 break; 10433 10434 case MSG_DISPATCH_AUDIO_SERVER_STATE: 10435 onDispatchAudioServerStateChange(msg.arg1 == 1); 10436 break; 10437 10438 case MSG_UNLOAD_SOUND_EFFECTS: 10439 mSfxHelper.unloadSoundEffects(); 10440 break; 10441 10442 case MSG_LOAD_SOUND_EFFECTS: 10443 { 10444 LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj; 10445 if (mSystemReady) { 10446 mSfxHelper.loadSoundEffects(reply); 10447 } else { 10448 Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete"); 10449 if (reply != null) { 10450 reply.run(false); 10451 } 10452 } 10453 } 10454 break; 10455 10456 case MSG_PLAY_SOUND_EFFECT: 10457 mSfxHelper.playSoundEffect(msg.arg1, msg.arg2); 10458 break; 10459 10460 case MSG_SET_FORCE_USE: 10461 { 10462 final String eventSource = (String) msg.obj; 10463 final int useCase = msg.arg1; 10464 final int config = msg.arg2; 10465 if (useCase == AudioSystem.FOR_MEDIA) { 10466 Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from " 10467 + eventSource); 10468 break; 10469 } 10470 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE 10471 + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase)) 10472 .set(MediaMetrics.Property.EVENT, "setForceUse") 10473 .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource) 10474 .set(MediaMetrics.Property.FORCE_USE_MODE, 10475 AudioSystem.forceUseConfigToString(config)) 10476 .record(); 10477 sForceUseLogger.enqueue( 10478 new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource)); 10479 mAudioSystem.setForceUse(useCase, config); 10480 } 10481 break; 10482 10483 case MSG_DISABLE_AUDIO_FOR_UID: 10484 mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */, 10485 msg.arg2 /* uid */); 10486 mAudioEventWakeLock.release(); 10487 break; 10488 10489 case MSG_INIT_STREAMS_VOLUMES: 10490 onInitStreamsAndVolumes(); 10491 mAudioEventWakeLock.release(); 10492 break; 10493 10494 case MSG_INIT_INPUT_GAINS: 10495 onInitInputGains(); 10496 mAudioEventWakeLock.release(); 10497 break; 10498 10499 case MSG_INIT_ADI_DEVICE_STATES: 10500 onInitAdiDeviceStates(); 10501 mAudioEventWakeLock.release(); 10502 break; 10503 10504 case MSG_INIT_SPATIALIZER: 10505 onInitSpatializer(); 10506 mAudioEventWakeLock.release(); 10507 break; 10508 10509 case MSG_INIT_HEADTRACKING_SENSORS: 10510 mSpatializerHelper.onInitSensors(); 10511 break; 10512 10513 case MSG_RESET_SPATIALIZER: 10514 mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); 10515 break; 10516 10517 case MSG_SYSTEM_READY: 10518 onSystemReady(); 10519 break; 10520 10521 case MSG_INDICATE_SYSTEM_READY: 10522 onIndicateSystemReady(); 10523 break; 10524 10525 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE: 10526 onAccessoryPlugMediaUnmute(msg.arg1); 10527 break; 10528 10529 case MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE: 10530 onUnmuteStreamOnSingleVolDevice(msg.arg1, msg.arg2); 10531 break; 10532 10533 case MSG_DYN_POLICY_MIX_STATE_UPDATE: 10534 onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1); 10535 break; 10536 10537 case MSG_NOTIFY_VOL_EVENT: 10538 onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1); 10539 break; 10540 10541 case MSG_ENABLE_SURROUND_FORMATS: 10542 onEnableSurroundFormats((ArrayList<Integer>) msg.obj); 10543 break; 10544 10545 case MSG_UPDATE_RINGER_MODE: 10546 onUpdateRingerModeServiceInt(); 10547 break; 10548 10549 case MSG_SET_DEVICE_STREAM_VOLUME: 10550 onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj); 10551 break; 10552 10553 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS: 10554 onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1); 10555 break; 10556 10557 case MSG_HDMI_VOLUME_CHECK: 10558 onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj); 10559 break; 10560 10561 case MSG_PLAYBACK_CONFIG_CHANGE: 10562 onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj); 10563 break; 10564 case MSG_RECORDING_CONFIG_CHANGE: 10565 onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj); 10566 break; 10567 10568 case MSG_BROADCAST_MICROPHONE_MUTE: 10569 mSystemServer.sendMicrophoneMuteChangedIntent(); 10570 break; 10571 10572 case MSG_BROADCAST_MASTER_MUTE: 10573 mSystemServer.broadcastMasterMuteStatus(msg.arg1 == 1); 10574 break; 10575 10576 case MSG_CHECK_MODE_FOR_UID: 10577 synchronized (mDeviceBroker.mSetModeLock) { 10578 if (msg.obj == null) { 10579 break; 10580 } 10581 // Update active playback/recording for apps requesting IN_COMMUNICATION 10582 // mode after a grace period following the mode change 10583 SetModeDeathHandler h = (SetModeDeathHandler) msg.obj; 10584 if (mSetModeDeathHandlers.indexOf(h) < 0) { 10585 break; 10586 } 10587 boolean wasActive = h.isActive(); 10588 h.setPlaybackActive(isPlaybackActiveForUid(h.getUid())); 10589 h.setRecordingActive(isRecordingActiveForUid(h.getUid())); 10590 if (wasActive != h.isActive()) { 10591 onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(), 10592 mContext.getPackageName(), false /*force*/, false /*signal*/); 10593 } 10594 } 10595 break; 10596 10597 case MSG_STREAM_DEVICES_CHANGED: 10598 final SomeArgs args = (SomeArgs) msg.obj; 10599 final Intent intent = (Intent) args.arg1; 10600 final Bundle options = (Bundle) args.arg2; 10601 args.recycle(); 10602 sendBroadcastToAll(intent 10603 .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1) 10604 .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2), 10605 options); 10606 break; 10607 10608 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE: 10609 onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj); 10610 break; 10611 10612 case MSG_REINIT_VOLUMES: 10613 onReinitVolumes((String) msg.obj); 10614 break; 10615 10616 case MSG_UPDATE_A11Y_SERVICE_UIDS: 10617 onUpdateAccessibilityServiceUids(); 10618 break; 10619 10620 case MSG_UPDATE_AUDIO_MODE: 10621 case MSG_UPDATE_AUDIO_MODE_SIGNAL: 10622 synchronized (mDeviceBroker.mSetModeLock) { 10623 UpdateAudioModeInfo info = (UpdateAudioModeInfo) msg.obj; 10624 onUpdateAudioMode(info.getMode(), info.getPid(), info.getPackageName(), 10625 false /*force*/, msg.what == MSG_UPDATE_AUDIO_MODE_SIGNAL); 10626 } 10627 break; 10628 10629 case MSG_BT_DEV_CHANGED: 10630 mDeviceBroker.queueOnBluetoothActiveDeviceChanged( 10631 (AudioDeviceBroker.BtDeviceChangedData) msg.obj); 10632 break; 10633 10634 case MSG_DISPATCH_AUDIO_MODE: 10635 dispatchMode(msg.arg1); 10636 break; 10637 10638 case MSG_ROUTING_UPDATED: 10639 onRoutingUpdatedFromAudioThread(); 10640 break; 10641 10642 case MSG_ADD_ASSISTANT_SERVICE_UID: 10643 onAddAssistantServiceUids(new int[]{msg.arg1}); 10644 break; 10645 10646 case MSG_REMOVE_ASSISTANT_SERVICE_UID: 10647 onRemoveAssistantServiceUids(new int[]{msg.arg1}); 10648 break; 10649 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID: 10650 updateActiveAssistantServiceUids(); 10651 break; 10652 10653 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR: 10654 dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1); 10655 break; 10656 10657 case MSG_ROTATION_UPDATE: 10658 // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270 10659 mAudioSystem.setParameters((String) msg.obj); 10660 break; 10661 10662 case MSG_FOLD_UPDATE: 10663 // fold parameter format: "device_folded=x" where x is one of on, off 10664 mAudioSystem.setParameters((String) msg.obj); 10665 break; 10666 10667 case MSG_NO_LOG_FOR_PLAYER_I: 10668 mPlaybackMonitor.ignorePlayerIId(msg.arg1); 10669 break; 10670 10671 case MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES: 10672 onDispatchPreferredMixerAttributesChanged(msg.getData(), msg.arg1); 10673 break; 10674 10675 case MSG_CONFIGURATION_CHANGED: 10676 onConfigurationChanged(); 10677 break; 10678 10679 case MSG_UPDATE_CONTEXTUAL_VOLUMES: 10680 onUpdateContextualVolumes(); 10681 break; 10682 10683 case MSG_BT_COMM_DEVICE_ACTIVE_UPDATE: 10684 onUpdateBtCommDeviceActive(msg.arg1); 10685 break; 10686 10687 case MusicFxHelper.MSG_EFFECT_CLIENT_GONE: 10688 mMusicFxHelper.handleMessage(msg); 10689 break; 10690 10691 case SoundDoseHelper.MSG_CONFIGURE_SAFE_MEDIA: 10692 case SoundDoseHelper.MSG_CONFIGURE_SAFE_MEDIA_FORCED: 10693 case SoundDoseHelper.MSG_PERSIST_SAFE_VOLUME_STATE: 10694 case SoundDoseHelper.MSG_PERSIST_MUSIC_ACTIVE_MS: 10695 case SoundDoseHelper.MSG_PERSIST_CSD_VALUES: 10696 case SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION: 10697 case SoundDoseHelper.MSG_LOWER_VOLUME_TO_RS1: 10698 mSoundDoseHelper.handleMessage(msg); 10699 break; 10700 10701 default: 10702 Log.e(TAG, "Unsupported msgId " + msg.what); 10703 } 10704 } 10705 } 10706 10707 private class SettingsObserver extends ContentObserver { 10708 SettingsObserver()10709 SettingsObserver() { 10710 super(new Handler()); 10711 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 10712 Settings.Global.ZEN_MODE), false, this); 10713 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 10714 Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this); 10715 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 10716 Settings.Global.MUTE_ALARM_STREAM_WITH_RINGER_MODE), false, this); 10717 mContentResolver.registerContentObserver(Settings.System.getUriFor( 10718 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); 10719 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 10720 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); 10721 mContentResolver.registerContentObserver(Settings.System.getUriFor( 10722 Settings.System.MASTER_MONO), false, this, UserHandle.USER_ALL); 10723 mContentResolver.registerContentObserver(Settings.System.getUriFor( 10724 Settings.System.MASTER_BALANCE), false, this, UserHandle.USER_ALL); 10725 10726 mEncodedSurroundMode = mSettings.getGlobalInt( 10727 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 10728 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 10729 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 10730 Settings.Global.ENCODED_SURROUND_OUTPUT), false, this); 10731 mEnabledSurroundFormats = mSettings.getGlobalString( 10732 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); 10733 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 10734 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this); 10735 10736 mContentResolver.registerContentObserver(Settings.Secure.getUriFor( 10737 Settings.Secure.VOICE_INTERACTION_SERVICE), false, this); 10738 } 10739 10740 @Override onChange(boolean selfChange)10741 public void onChange(boolean selfChange) { 10742 super.onChange(selfChange); 10743 // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode. 10744 // However there appear to be some missing locks around sRingerAndZenModeMutedStreams 10745 // and mRingerModeAffectedStreams, so will leave this synchronized for now. 10746 // sRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). 10747 synchronized (mSettingsLock) { 10748 if (updateRingerAndZenModeAffectedStreams()) { 10749 /* 10750 * Ensure all stream types that should be affected by ringer mode 10751 * are in the proper state. 10752 */ 10753 setRingerModeInt(getRingerModeInternal(), false); 10754 } 10755 readDockAudioSettings(mContentResolver); 10756 updateMasterMono(mContentResolver); 10757 updateMasterBalance(mContentResolver); 10758 updateEncodedSurroundOutput(); 10759 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged); 10760 updateAssistantUIdLocked(/* forceUpdate= */ false); 10761 } 10762 } 10763 updateEncodedSurroundOutput()10764 private void updateEncodedSurroundOutput() { 10765 int newSurroundMode = mSettings.getGlobalInt( 10766 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 10767 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 10768 // Did it change? 10769 if (mEncodedSurroundMode != newSurroundMode) { 10770 // Send to AudioPolicyManager 10771 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver"); 10772 mDeviceBroker.toggleHdmiIfConnected_Async(); 10773 mEncodedSurroundMode = newSurroundMode; 10774 mSurroundModeChanged = true; 10775 } else { 10776 mSurroundModeChanged = false; 10777 } 10778 } 10779 } 10780 avrcpSupportsAbsoluteVolume(String address, boolean support)10781 private void avrcpSupportsAbsoluteVolume(String address, boolean support) { 10782 // address is not used for now, but may be used when multiple a2dp devices are supported 10783 sVolumeLogger.enqueue(new EventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr=" 10784 + Utils.anonymizeBluetoothAddress(address) + " support=" + support).printLog(TAG)); 10785 mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support); 10786 setAvrcpAbsoluteVolumeSupported(support); 10787 } 10788 setAvrcpAbsoluteVolumeSupported(boolean support)10789 /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) { 10790 Log.i(TAG, "setAvrcpAbsoluteVolumeSupported support " + support); 10791 synchronized (mCachedAbsVolDrivingStreamsLock) { 10792 mAvrcpAbsVolSupported = support; 10793 int a2dpDev = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; 10794 mCachedAbsVolDrivingStreams.compute(a2dpDev, (dev, stream) -> { 10795 if (!mAvrcpAbsVolSupported) { 10796 final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled( 10797 a2dpDev, /*address=*/"", /*enabled*/false, 10798 AudioSystem.STREAM_DEFAULT); 10799 if (result != AudioSystem.AUDIO_STATUS_OK) { 10800 sVolumeLogger.enqueueAndSlog( 10801 new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR, 10802 result, a2dpDev, /*enabled=*/false, 10803 AudioSystem.STREAM_DEFAULT).eventToString(), ALOGE, 10804 TAG); 10805 } 10806 return null; 10807 } 10808 // For A2DP and AVRCP we need to set the driving stream based on the 10809 // BT contextual stream. Hence, we need to make sure in adjustStreamVolume 10810 // and setStreamVolume that the driving abs volume stream is consistent. 10811 int streamToDriveAbs = getBluetoothContextualVolumeStream(); 10812 if (stream == null || stream != streamToDriveAbs) { 10813 final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev, 10814 /*address=*/"", /*enabled*/true, streamToDriveAbs); 10815 if (result != AudioSystem.AUDIO_STATUS_OK) { 10816 sVolumeLogger.enqueueAndSlog( 10817 new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR, 10818 result, a2dpDev, /*enabled=*/true, 10819 streamToDriveAbs).eventToString(), ALOGE, TAG); 10820 } 10821 } 10822 return streamToDriveAbs; 10823 }); 10824 } 10825 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 10826 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, 10827 getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC), 0); 10828 } 10829 10830 /** 10831 * @return true if there is currently a registered dynamic mixing policy that affects media 10832 * and is not a render + loopback policy 10833 */ 10834 // only public for mocking/spying 10835 @VisibleForTesting hasMediaDynamicPolicy()10836 public boolean hasMediaDynamicPolicy() { 10837 synchronized (mAudioPolicies) { 10838 if (mAudioPolicies.isEmpty()) { 10839 return false; 10840 } 10841 final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values(); 10842 for (AudioPolicyProxy app : appColl) { 10843 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA, 10844 AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 10845 return true; 10846 } 10847 } 10848 return false; 10849 } 10850 } 10851 10852 /** only public for mocking/spying, do not call outside of AudioService */ 10853 @VisibleForTesting checkMusicActive(int deviceType, String caller)10854 public void checkMusicActive(int deviceType, String caller) { 10855 if (mSoundDoseHelper.safeDevicesContains(deviceType)) { 10856 mSoundDoseHelper.scheduleMusicActiveCheck(); 10857 } 10858 } 10859 10860 /** 10861 * Receiver for misc intent broadcasts the Phone app cares about. 10862 */ 10863 private class AudioServiceBroadcastReceiver extends BroadcastReceiver { 10864 @Override onReceive(Context context, Intent intent)10865 public void onReceive(Context context, Intent intent) { 10866 final String action = intent.getAction(); 10867 int outDevice; 10868 int inDevice; 10869 int state; 10870 10871 if (action.equals(Intent.ACTION_DOCK_EVENT)) { 10872 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 10873 Intent.EXTRA_DOCK_STATE_UNDOCKED); 10874 int config; 10875 switch (dockState) { 10876 case Intent.EXTRA_DOCK_STATE_DESK: 10877 config = AudioSystem.FORCE_BT_DESK_DOCK; 10878 break; 10879 case Intent.EXTRA_DOCK_STATE_CAR: 10880 config = AudioSystem.FORCE_BT_CAR_DOCK; 10881 break; 10882 case Intent.EXTRA_DOCK_STATE_LE_DESK: 10883 config = AudioSystem.FORCE_ANALOG_DOCK; 10884 break; 10885 case Intent.EXTRA_DOCK_STATE_HE_DESK: 10886 config = AudioSystem.FORCE_DIGITAL_DOCK; 10887 break; 10888 case Intent.EXTRA_DOCK_STATE_UNDOCKED: 10889 default: 10890 config = AudioSystem.FORCE_NONE; 10891 } 10892 // Low end docks have a menu to enable or disable audio 10893 // (see mDockAudioMediaEnabled) 10894 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) 10895 || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) 10896 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) { 10897 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config, 10898 "ACTION_DOCK_EVENT intent"); 10899 } 10900 mDockState = dockState; 10901 } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED) 10902 || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { 10903 mDeviceBroker.postReceiveBtEvent(intent); 10904 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 10905 if (mMonitorRotation) { 10906 RotationHelper.enable(); 10907 } 10908 AudioSystem.setParameters("screen_state=on"); 10909 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 10910 if (mMonitorRotation) { 10911 //reduce wakeups (save current) by only listening when display is on 10912 RotationHelper.disable(); 10913 } 10914 AudioSystem.setParameters("screen_state=off"); 10915 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 10916 sendMsg(mAudioHandler, 10917 MSG_CONFIGURATION_CHANGED, 10918 SENDMSG_REPLACE, 10919 0, 10920 0, 10921 null, 0); 10922 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 10923 // the current audio focus owner is likely no longer valid 10924 final boolean audioDiscarded = mMediaFocusControl.maybeDiscardAudioFocusOwner(); 10925 if (audioDiscarded && mUserSwitchedReceived) { 10926 // attempt to stop music playback for background user except on first user 10927 // switch (i.e. first boot) 10928 mDeviceBroker.postBroadcastBecomingNoisy(); 10929 } 10930 mUserSwitchedReceived = true; 10931 10932 if (mSupportsMicPrivacyToggle) { 10933 mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal 10934 .isSensorPrivacyEnabled(getCurrentUserId(), 10935 SensorPrivacyManager.Sensors.MICROPHONE); 10936 setMicrophoneMuteNoCallerCheck(getCurrentUserId()); 10937 } 10938 10939 // load volume settings for new user 10940 readAudioSettings(true /*userSwitch*/); 10941 // preserve STREAM_MUSIC volume from one user to the next. 10942 sendMsg(mAudioHandler, 10943 MSG_SET_ALL_VOLUMES, 10944 SENDMSG_QUEUE, 10945 0, 10946 0, 10947 getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC), 0); 10948 } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) { 10949 // Disable audio recording for the background user/profile 10950 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 10951 if (userId >= 0) { 10952 // TODO Kill recording streams instead of killing processes holding permission 10953 UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId); 10954 killBackgroundUserProcessesWithRecordAudioPermission(userInfo); 10955 } 10956 try { 10957 UserManagerService.getInstance().setUserRestriction( 10958 UserManager.DISALLOW_RECORD_AUDIO, true, userId); 10959 } catch (IllegalArgumentException e) { 10960 Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); 10961 } 10962 } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) { 10963 // Enable audio recording for foreground user/profile 10964 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 10965 try { 10966 UserManagerService.getInstance().setUserRestriction( 10967 UserManager.DISALLOW_RECORD_AUDIO, false, userId); 10968 } catch (IllegalArgumentException e) { 10969 Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e); 10970 } 10971 } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) || 10972 action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) { 10973 mMusicFxHelper.handleAudioEffectBroadcast(context, intent); 10974 } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) { 10975 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); 10976 final String[] suspendedPackages = 10977 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 10978 if (suspendedPackages == null || suspendedUids == null 10979 || suspendedPackages.length != suspendedUids.length) { 10980 return; 10981 } 10982 for (int i = 0; i < suspendedUids.length; i++) { 10983 if (!TextUtils.isEmpty(suspendedPackages[i])) { 10984 mMediaFocusControl.noFocusForSuspendedApp( 10985 suspendedPackages[i], suspendedUids[i]); 10986 } 10987 } 10988 } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) { 10989 mSoundDoseHelper.onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE, 10990 mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)); 10991 } 10992 } 10993 } // end class AudioServiceBroadcastReceiver 10994 10995 private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener { 10996 10997 @Override onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)10998 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, 10999 Bundle prevRestrictions) { 11000 // Update mic mute state. 11001 { 11002 final boolean wasRestricted = 11003 prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 11004 final boolean isRestricted = 11005 newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 11006 if (wasRestricted != isRestricted) { 11007 mMicMuteFromRestrictions = isRestricted; 11008 setMicrophoneMuteNoCallerCheck(userId); 11009 } 11010 } 11011 11012 // Update speaker mute state. 11013 { 11014 final boolean wasRestricted = 11015 prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 11016 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 11017 final boolean isRestricted = 11018 newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME) 11019 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE); 11020 if (wasRestricted != isRestricted) { 11021 setMasterMuteInternalNoCallerCheck( 11022 isRestricted, /* flags =*/ 0, userId, "onUserRestrictionsChanged"); 11023 } 11024 } 11025 } 11026 } // end class AudioServiceUserRestrictionsListener 11027 killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)11028 private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) { 11029 PackageManager pm = mContext.getPackageManager(); 11030 // Find the home activity of the user. It should not be killed to avoid expensive restart, 11031 // when the user switches back. For managed profiles, we should kill all recording apps 11032 ComponentName homeActivityName = null; 11033 if (!oldUser.isManagedProfile()) { 11034 homeActivityName = LocalServices.getService( 11035 ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id); 11036 } 11037 final String[] permissions = { Manifest.permission.RECORD_AUDIO }; 11038 List<PackageInfo> packages; 11039 try { 11040 packages = AppGlobals.getPackageManager() 11041 .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList(); 11042 } catch (RemoteException e) { 11043 throw new AndroidRuntimeException(e); 11044 } 11045 for (int j = packages.size() - 1; j >= 0; j--) { 11046 PackageInfo pkg = packages.get(j); 11047 // Skip system processes 11048 if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { 11049 continue; 11050 } 11051 // Skip packages that have permission to interact across users 11052 if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName) 11053 == PackageManager.PERMISSION_GRANTED) { 11054 continue; 11055 } 11056 if (homeActivityName != null 11057 && pkg.packageName.equals(homeActivityName.getPackageName()) 11058 && pkg.applicationInfo.isSystemApp()) { 11059 continue; 11060 } 11061 try { 11062 final int uid = pkg.applicationInfo.uid; 11063 ActivityManager.getService().killUid(UserHandle.getAppId(uid), 11064 UserHandle.getUserId(uid), 11065 "killBackgroundUserProcessesWithAudioRecordPermission"); 11066 } catch (RemoteException e) { 11067 Log.w(TAG, "Error calling killUid", e); 11068 } 11069 } 11070 } 11071 11072 /* Listen to permission invalidations for the PermissionProvider */ setupPermissionListener()11073 private void setupPermissionListener() { 11074 // instanceof to simplify the construction requirements of AudioService for testing: no 11075 // delayed execution during unit tests. 11076 if (mAudioServerLifecycleExecutor instanceof ScheduledExecutorService exec) { 11077 // The order on the task list is an embedding on the scheduling order of the executor, 11078 // since we synchronously add the scheduled task to our local queue. This list should 11079 // almost always have only two elements, except in cases of serious system contention. 11080 Runnable task = () -> { 11081 synchronized (mScheduledPermissionTasks) { 11082 mScheduledPermissionTasks.add(exec.schedule(() -> { 11083 try { 11084 // Our goal is to remove all tasks which don't correspond to ourselves 11085 // on this queue. Either they are already done (ahead of us), or we 11086 // should cancel them (behind us), since their work is redundant after 11087 // we fire. 11088 // We must be the first non-completed task in the queue, since the 11089 // execution order matches the queue order. Note, this task is the only 11090 // writer on elements in the queue, and the task is serialized, so 11091 // => no in-flight cancellation 11092 // => exists at least one non-completed task (ourselves) 11093 // => the queue is non-empty (only completed tasks removed) 11094 synchronized (mScheduledPermissionTasks) { 11095 final var iter = mScheduledPermissionTasks.iterator(); 11096 while (iter.next().isDone()) { 11097 iter.remove(); 11098 } 11099 // iter is on the first element which is not completed (us) 11100 while (iter.hasNext()) { 11101 if (!iter.next().cancel(false)) { 11102 throw new AssertionError( 11103 "Cancel should be infallible since we" + 11104 "cancel from the executor"); 11105 } 11106 iter.remove(); 11107 } 11108 } 11109 mPermissionProvider.onPermissionStateChanged(); 11110 } catch (Exception e) { 11111 // Handle executor routing exceptions to nowhere 11112 Thread.getDefaultUncaughtExceptionHandler() 11113 .uncaughtException(Thread.currentThread(), e); 11114 } 11115 }, getAudioPermissionsDelay(), TimeUnit.MILLISECONDS)); 11116 } 11117 }; 11118 if (PropertyInvalidatedCache.separatePermissionNotificationsEnabled()) { 11119 mCacheWatcher = new CacheWatcher(task); 11120 mCacheWatcher.start(); 11121 } else { 11122 mSysPropListenerNativeHandle = mAudioSystem.listenForSystemPropertyChange( 11123 PermissionManager.CACHE_KEY_PACKAGE_INFO_NOTIFY, 11124 task); 11125 } 11126 } else { 11127 mAudioSystem.listenForSystemPropertyChange( 11128 PermissionManager.CACHE_KEY_PACKAGE_INFO_NOTIFY, 11129 () -> mAudioServerLifecycleExecutor.execute( 11130 mPermissionProvider::onPermissionStateChanged)); 11131 } 11132 } 11133 11134 /** 11135 * Listens for CACHE_KEY_PACKAGE_INFO_CACHE invalidations to trigger permission syncing 11136 */ 11137 private static class CacheWatcher extends Thread { 11138 11139 // The run/stop signal. 11140 private final AtomicBoolean mRunning = new AtomicBoolean(false); 11141 11142 // The source of change information. 11143 private final PropertyInvalidatedCache.NonceWatcher mWatcher; 11144 11145 // Task to trigger when cache changes 11146 private final Runnable mTask; 11147 CacheWatcher(Runnable r)11148 public CacheWatcher(Runnable r) { 11149 mWatcher = PropertyInvalidatedCache.getNonceWatcher( 11150 PermissionManager.CACHE_KEY_PACKAGE_INFO_CACHE); 11151 mTask = r; 11152 } 11153 run()11154 public void run() { 11155 mRunning.set(true); 11156 while (mRunning.get()) { 11157 doCheck(); 11158 try { 11159 mWatcher.waitForChange(); 11160 } catch (InterruptedException e) { 11161 Log.wtf(TAG, "Unexpected Interrupt", e); 11162 // We don't know why the exception occurred but keep running until told to 11163 // stop. 11164 continue; 11165 } 11166 } 11167 } 11168 doCheck()11169 public synchronized void doCheck() { 11170 if (mWatcher.isChanged()) { 11171 mTask.run(); 11172 } 11173 } 11174 11175 /** 11176 * Cause the thread to exit. Running is set to false and the watcher is awakened. 11177 */ done()11178 public void done() { 11179 mRunning.set(false); 11180 mWatcher.wakeUp(); 11181 } 11182 } 11183 11184 //========================================================================================== 11185 // Audio Focus 11186 //========================================================================================== 11187 /** 11188 * Returns whether a focus request is eligible to force ducking. 11189 * Will return true if: 11190 * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY, 11191 * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 11192 * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true, 11193 * - the uid of the requester is a known accessibility service or root. 11194 * @param aa AudioAttributes of the focus request 11195 * @param uid uid of the focus requester 11196 * @return true if ducking is to be forced 11197 */ forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)11198 private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa, 11199 int request, int uid) { 11200 if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY 11201 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) { 11202 return false; 11203 } 11204 final Bundle extraInfo = aa.getBundle(); 11205 if (extraInfo == null || 11206 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) { 11207 return false; 11208 } 11209 if (uid == 0) { 11210 return true; 11211 } 11212 synchronized (mAccessibilityServiceUidsLock) { 11213 if (mAccessibilityServiceUids != null) { 11214 int callingUid = Binder.getCallingUid(); 11215 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 11216 if (mAccessibilityServiceUids[i] == callingUid) { 11217 return true; 11218 } 11219 } 11220 } 11221 } 11222 return false; 11223 } 11224 isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)11225 private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) { 11226 synchronized (mSupportedSystemUsagesLock) { 11227 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 11228 if (mSupportedSystemUsages[i] == usage) { 11229 return true; 11230 } 11231 } 11232 return false; 11233 } 11234 } 11235 validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)11236 private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 11237 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 11238 if (AudioAttributes.isSystemUsage(usage)) { 11239 if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 11240 && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 11241 && callerHasPermission(CALL_AUDIO_INTERCEPTION)) 11242 || callerHasPermission(MODIFY_AUDIO_ROUTING)) { 11243 if (!isSupportedSystemUsage(usage)) { 11244 throw new IllegalArgumentException( 11245 "Unsupported usage " + AudioAttributes.usageToString(usage)); 11246 } 11247 } else { 11248 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission"); 11249 } 11250 } 11251 } 11252 isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)11253 private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) { 11254 @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage(); 11255 if (AudioAttributes.isSystemUsage(usage)) { 11256 return isSupportedSystemUsage(usage) 11257 && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT 11258 && (audioAttributes.getAllFlags() 11259 & AudioAttributes.FLAG_CALL_REDIRECTION) != 0 11260 && callerHasPermission(CALL_AUDIO_INTERCEPTION)) 11261 || callerHasPermission(MODIFY_AUDIO_ROUTING)); 11262 } 11263 return true; 11264 } 11265 requestAudioFocus(AudioAttributes aa, int focusReqType, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)11266 public int requestAudioFocus(AudioAttributes aa, int focusReqType, IBinder cb, 11267 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 11268 String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) { 11269 if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) { 11270 throw new IllegalArgumentException("Invalid test flag"); 11271 } 11272 final int uid = Binder.getCallingUid(); 11273 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 11274 .setUid(uid) 11275 //.putInt("focusReqType", focusReqType) 11276 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 11277 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 11278 .set(MediaMetrics.Property.EVENT, "requestAudioFocus") 11279 .set(MediaMetrics.Property.FLAGS, flags); 11280 11281 // permission checks 11282 if (aa != null && !isValidAudioAttributesUsage(aa)) { 11283 final String reason = "Request using unsupported usage"; 11284 Log.w(TAG, reason); 11285 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 11286 .record(); 11287 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11288 } 11289 if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) { 11290 if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) { 11291 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 11292 MODIFY_PHONE_STATE)) { 11293 final String reason = "Invalid permission to (un)lock audio focus"; 11294 Log.e(TAG, reason, new Exception()); 11295 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 11296 .record(); 11297 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11298 } 11299 } else { 11300 // only a registered audio policy can be used to lock focus 11301 synchronized (mAudioPolicies) { 11302 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 11303 final String reason = 11304 "Invalid unregistered AudioPolicy to (un)lock audio focus"; 11305 Log.e(TAG, reason); 11306 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 11307 .record(); 11308 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11309 } 11310 } 11311 } 11312 } 11313 11314 if (callingPackageName == null || clientId == null || aa == null) { 11315 final String reason = "Invalid null parameter to request audio focus"; 11316 Log.e(TAG, reason); 11317 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason) 11318 .record(); 11319 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11320 } 11321 11322 // does caller have system privileges to bypass HardeningEnforcer 11323 boolean permissionOverridesCheck = false; 11324 if ((mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 11325 == PackageManager.PERMISSION_GRANTED) 11326 || (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 11327 == PackageManager.PERMISSION_GRANTED)) { 11328 permissionOverridesCheck = true; 11329 } else if (uid < UserHandle.AID_APP_START) { 11330 permissionOverridesCheck = true; 11331 } 11332 11333 final long token = Binder.clearCallingIdentity(); 11334 try { 11335 //TODO move inside HardeningEnforcer after refactor that moves permission checks 11336 // in the blockFocusMethod 11337 if (permissionOverridesCheck) { 11338 mHardeningEnforcer.metricsLogFocusReq(/*blocked*/ false, focusReqType, uid, 11339 /*unblockedBySdk*/ false); 11340 } 11341 if (!permissionOverridesCheck && mHardeningEnforcer.blockFocusMethod(uid, 11342 HardeningEnforcer.METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS, 11343 clientId, focusReqType, callingPackageName, attributionTag, sdk)) { 11344 final String reason = "Audio focus request blocked by hardening"; 11345 Log.w(TAG, reason); 11346 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason).record(); 11347 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11348 } 11349 } finally { 11350 Binder.restoreCallingIdentity(token); 11351 } 11352 11353 mmi.record(); 11354 return mMediaFocusControl.requestAudioFocus(aa, focusReqType, cb, fd, 11355 clientId, callingPackageName, flags, sdk, 11356 forceFocusDuckingForAccessibility(aa, focusReqType, uid), -1 /*testUid, ignored*/, 11357 permissionOverridesCheck); 11358 } 11359 11360 /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */ requestAudioFocusForTest(AudioAttributes aa, int focusReqType, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, int fakeUid, int sdk)11361 public int requestAudioFocusForTest(AudioAttributes aa, int focusReqType, IBinder cb, 11362 IAudioFocusDispatcher fd, String clientId, String callingPackageName, 11363 int flags, int fakeUid, int sdk) { 11364 if (!enforceQueryAudioStateForTest("focus request")) { 11365 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11366 } 11367 if (callingPackageName == null || clientId == null || aa == null) { 11368 final String reason = "Invalid null parameter to request audio focus"; 11369 Log.e(TAG, reason); 11370 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11371 } 11372 return mMediaFocusControl.requestAudioFocus(aa, focusReqType, cb, fd, 11373 clientId, callingPackageName, flags, 11374 sdk, false /*forceDuck*/, fakeUid, true /*permissionOverridesCheck*/); 11375 } 11376 abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)11377 public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, 11378 String callingPackageName) { 11379 MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus") 11380 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName) 11381 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 11382 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus"); 11383 11384 if (aa != null && !isValidAudioAttributesUsage(aa)) { 11385 Log.w(TAG, "Request using unsupported usage."); 11386 mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record(); 11387 11388 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11389 } 11390 mmi.record(); 11391 //delay abandon focus requests from Telecom if an audio mode reset from Telecom 11392 // is still being processed 11393 final boolean abandonFromTelecom = (mContext.checkCallingOrSelfPermission( 11394 MODIFY_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) 11395 && ((aa != null && aa.getUsage() == AudioAttributes.USAGE_VOICE_COMMUNICATION) 11396 || AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)); 11397 if (abandonFromTelecom) { 11398 synchronized (mAudioModeResetLock) { 11399 final long start = java.lang.System.currentTimeMillis(); 11400 long elapsed = 0; 11401 while (mAudioModeResetCount > 0) { 11402 if (DEBUG_MODE) { 11403 Log.i(TAG, "Abandon focus from Telecom, waiting for mode change"); 11404 } 11405 try { 11406 mAudioModeResetLock.wait( 11407 AUDIO_MODE_RESET_TIMEOUT_MS - elapsed); 11408 } catch (InterruptedException e) { 11409 Log.w(TAG, "Interrupted while waiting for audio mode reset"); 11410 } 11411 elapsed = java.lang.System.currentTimeMillis() - start; 11412 if (elapsed >= AUDIO_MODE_RESET_TIMEOUT_MS) { 11413 Log.e(TAG, "Timeout waiting for audio mode reset"); 11414 // reset count to avoid sticky out of sync state. 11415 resetAudioModeResetCount(); 11416 break; 11417 } 11418 } 11419 if (DEBUG_MODE && elapsed != 0) { 11420 Log.i(TAG, "Abandon focus from Telecom done waiting"); 11421 } 11422 } 11423 } 11424 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 11425 } 11426 11427 /** synchronization between setMode(NORMAL) and abandonAudioFocus() from Telecom */ 11428 private static final long AUDIO_MODE_RESET_TIMEOUT_MS = 3000; 11429 11430 private final Object mAudioModeResetLock = new Object(); 11431 11432 @GuardedBy("mAudioModeResetLock") 11433 private int mAudioModeResetCount = 0; 11434 decrementAudioModeResetCount()11435 void decrementAudioModeResetCount() { 11436 synchronized (mAudioModeResetLock) { 11437 if (mAudioModeResetCount > 0) { 11438 mAudioModeResetCount--; 11439 } else { 11440 Log.w(TAG, "mAudioModeResetCount already 0"); 11441 } 11442 mAudioModeResetLock.notify(); 11443 } 11444 } 11445 resetAudioModeResetCount()11446 private void resetAudioModeResetCount() { 11447 synchronized (mAudioModeResetLock) { 11448 mAudioModeResetCount = 0; 11449 mAudioModeResetLock.notify(); 11450 } 11451 } 11452 11453 /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */ abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)11454 public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, 11455 AudioAttributes aa, String callingPackageName) { 11456 if (!enforceQueryAudioStateForTest("focus abandon")) { 11457 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 11458 } 11459 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName); 11460 } 11461 11462 /** see {@link AudioManager#getFocusDuckedUidsForTest()} */ 11463 @Override 11464 @EnforcePermission(QUERY_AUDIO_STATE) getFocusDuckedUidsForTest()11465 public @NonNull List<Integer> getFocusDuckedUidsForTest() { 11466 super.getFocusDuckedUidsForTest_enforcePermission(); 11467 return mPlaybackMonitor.getFocusDuckedUids(); 11468 } 11469 unregisterAudioFocusClient(String clientId)11470 public void unregisterAudioFocusClient(String clientId) { 11471 new MediaMetrics.Item(mMetricsId + "focus") 11472 .set(MediaMetrics.Property.CLIENT_NAME, clientId) 11473 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient") 11474 .record(); 11475 mMediaFocusControl.unregisterAudioFocusClient(clientId); 11476 } 11477 getCurrentAudioFocus()11478 public int getCurrentAudioFocus() { 11479 return mMediaFocusControl.getCurrentAudioFocus(); 11480 } 11481 getFocusRampTimeMs(int focusGain, AudioAttributes attr)11482 public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) { 11483 return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr); 11484 } 11485 11486 /** 11487 * Test method to return the duration of the fade out applied on the players of a focus loser 11488 * @see AudioManager#getFocusFadeOutDurationForTest() 11489 * @return the fade out duration, in ms 11490 */ 11491 @EnforcePermission(QUERY_AUDIO_STATE) getFocusFadeOutDurationForTest()11492 public long getFocusFadeOutDurationForTest() { 11493 super.getFocusFadeOutDurationForTest_enforcePermission(); 11494 return mMediaFocusControl.getFocusFadeOutDurationForTest(); 11495 } 11496 11497 /** 11498 * Test method to return the length of time after a fade out before the focus loser is unmuted 11499 * (and is faded back in). 11500 * @see AudioManager#getFocusUnmuteDelayAfterFadeOutForTest() 11501 * @return the time gap after a fade out completion on focus loss, and fade in start, in ms 11502 */ 11503 @Override 11504 @EnforcePermission(QUERY_AUDIO_STATE) getFocusUnmuteDelayAfterFadeOutForTest()11505 public long getFocusUnmuteDelayAfterFadeOutForTest() { 11506 super.getFocusUnmuteDelayAfterFadeOutForTest_enforcePermission(); 11507 return mMediaFocusControl.getFocusUnmuteDelayAfterFadeOutForTest(); 11508 } 11509 11510 /** 11511 * Test method to start preventing applications from requesting audio focus during a test, 11512 * which could interfere with the testing of the functionality/behavior under test. 11513 * Calling this method needs to be paired with a call to {@link #exitAudioFocusFreezeForTest} 11514 * when the testing is done. If this is not the case (e.g. in case of a test crash), 11515 * a death observer mechanism will ensure the system is not left in a bad state, but this should 11516 * not be relied on when implementing tests. 11517 * @see AudioManager#enterAudioFocusFreezeForTest(List) 11518 * @param cb IBinder to track the death of the client of this method 11519 * @param exemptedUids a list of UIDs that are exempt from the freeze. This would for instance 11520 * be those of the test runner and other players used in the test 11521 * @return true if the focus freeze mode is successfully entered, false if there was an issue, 11522 * such as another freeze currently used. 11523 */ 11524 @Override 11525 @EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) enterAudioFocusFreezeForTest(IBinder cb, int[] exemptedUids)11526 public boolean enterAudioFocusFreezeForTest(IBinder cb, int[] exemptedUids) { 11527 super.enterAudioFocusFreezeForTest_enforcePermission(); 11528 Objects.requireNonNull(exemptedUids); 11529 Objects.requireNonNull(cb); 11530 return mMediaFocusControl.enterAudioFocusFreezeForTest(cb, exemptedUids); 11531 } 11532 11533 /** 11534 * Test method to end preventing applications from requesting audio focus during a test. 11535 * @see AudioManager#exitAudioFocusFreezeForTest() 11536 * @param cb IBinder identifying the client of this method 11537 * @return true if the focus freeze mode is successfully exited, false if there was an issue, 11538 * such as the freeze already having ended, or not started. 11539 */ 11540 @Override 11541 @EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) exitAudioFocusFreezeForTest(IBinder cb)11542 public boolean exitAudioFocusFreezeForTest(IBinder cb) { 11543 super.exitAudioFocusFreezeForTest_enforcePermission(); 11544 Objects.requireNonNull(cb); 11545 return mMediaFocusControl.exitAudioFocusFreezeForTest(cb); 11546 } 11547 11548 /** only public for mocking/spying, do not call outside of AudioService */ 11549 @VisibleForTesting hasAudioFocusUsers()11550 public boolean hasAudioFocusUsers() { 11551 return mMediaFocusControl.hasAudioFocusUsers(); 11552 } 11553 11554 /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */ 11555 @Override getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)11556 public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) { 11557 if (!enforceQueryAudioStateForTest("fade out duration")) { 11558 return 0; 11559 } 11560 return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa); 11561 } 11562 enforceQueryAudioStateForTest(String mssg)11563 private boolean enforceQueryAudioStateForTest(String mssg) { 11564 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 11565 Manifest.permission.QUERY_AUDIO_STATE)) { 11566 final String reason = "Doesn't have QUERY_AUDIO_STATE permission for " 11567 + mssg + " test API"; 11568 Log.e(TAG, reason, new Exception()); 11569 return false; 11570 } 11571 return true; 11572 } 11573 11574 //========================================================================================== 11575 private final @NonNull SpatializerHelper mSpatializerHelper; 11576 /** 11577 * Initialized from property ro.audio.spatializer_enabled 11578 * Should only be 1 when the device ships with a Spatializer effect 11579 */ 11580 private final boolean mHasSpatializerEffect; 11581 /** 11582 * Default value for the spatial audio feature 11583 */ 11584 private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true; 11585 enforceModifyDefaultAudioEffectsPermission()11586 private void enforceModifyDefaultAudioEffectsPermission() { 11587 if (mContext.checkCallingOrSelfPermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11588 != PackageManager.PERMISSION_GRANTED) { 11589 throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission"); 11590 } 11591 } 11592 11593 /** 11594 * Returns the immersive audio level that the platform is capable of 11595 * @see Spatializer#getImmersiveAudioLevel() 11596 */ getSpatializerImmersiveAudioLevel()11597 public int getSpatializerImmersiveAudioLevel() { 11598 return mSpatializerHelper.getCapableImmersiveAudioLevel(); 11599 } 11600 11601 /** @see Spatializer#isEnabled() */ isSpatializerEnabled()11602 public boolean isSpatializerEnabled() { 11603 return mSpatializerHelper.isEnabled(); 11604 } 11605 11606 /** @see Spatializer#isAvailable() */ isSpatializerAvailable()11607 public boolean isSpatializerAvailable() { 11608 return mSpatializerHelper.isAvailable(); 11609 } 11610 11611 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11612 /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */ isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)11613 public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device) { 11614 super.isSpatializerAvailableForDevice_enforcePermission(); 11615 11616 return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device)); 11617 } 11618 11619 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11620 /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */ hasHeadTracker(@onNull AudioDeviceAttributes device)11621 public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) { 11622 super.hasHeadTracker_enforcePermission(); 11623 11624 return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device)); 11625 } 11626 11627 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11628 /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */ setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)11629 public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) { 11630 super.setHeadTrackerEnabled_enforcePermission(); 11631 11632 mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device)); 11633 } 11634 11635 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11636 /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */ isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)11637 public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) { 11638 super.isHeadTrackerEnabled_enforcePermission(); 11639 11640 return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device)); 11641 } 11642 11643 /** @see Spatializer#isHeadTrackerAvailable() */ isHeadTrackerAvailable()11644 public boolean isHeadTrackerAvailable() { 11645 return mSpatializerHelper.isHeadTrackerAvailable(); 11646 } 11647 11648 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11649 /** @see Spatializer#setSpatializerEnabled(boolean) */ setSpatializerEnabled(boolean enabled)11650 public void setSpatializerEnabled(boolean enabled) { 11651 super.setSpatializerEnabled_enforcePermission(); 11652 11653 mSpatializerHelper.setFeatureEnabled(enabled); 11654 } 11655 11656 /** @see Spatializer#canBeSpatialized() */ canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)11657 public boolean canBeSpatialized( 11658 @NonNull AudioAttributes attributes, @NonNull AudioFormat format) { 11659 Objects.requireNonNull(attributes); 11660 Objects.requireNonNull(format); 11661 return mSpatializerHelper.canBeSpatialized(attributes, format); 11662 } 11663 getSpatializedChannelMasks()11664 public @NonNull List<Integer> getSpatializedChannelMasks() { 11665 return mSpatializerHelper.getSpatializedChannelMasks(); 11666 } 11667 11668 /** @see Spatializer.SpatializerInfoDispatcherStub */ registerSpatializerCallback( @onNull ISpatializerCallback cb)11669 public void registerSpatializerCallback( 11670 @NonNull ISpatializerCallback cb) { 11671 Objects.requireNonNull(cb); 11672 mSpatializerHelper.registerStateCallback(cb); 11673 } 11674 11675 /** @see Spatializer.SpatializerInfoDispatcherStub */ unregisterSpatializerCallback( @onNull ISpatializerCallback cb)11676 public void unregisterSpatializerCallback( 11677 @NonNull ISpatializerCallback cb) { 11678 Objects.requireNonNull(cb); 11679 mSpatializerHelper.unregisterStateCallback(cb); 11680 } 11681 11682 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11683 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)11684 public void registerSpatializerHeadTrackingCallback( 11685 @NonNull ISpatializerHeadTrackingModeCallback cb) { 11686 super.registerSpatializerHeadTrackingCallback_enforcePermission(); 11687 11688 Objects.requireNonNull(cb); 11689 mSpatializerHelper.registerHeadTrackingModeCallback(cb); 11690 } 11691 11692 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11693 /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */ unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)11694 public void unregisterSpatializerHeadTrackingCallback( 11695 @NonNull ISpatializerHeadTrackingModeCallback cb) { 11696 super.unregisterSpatializerHeadTrackingCallback_enforcePermission(); 11697 11698 Objects.requireNonNull(cb); 11699 mSpatializerHelper.unregisterHeadTrackingModeCallback(cb); 11700 } 11701 11702 /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */ registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)11703 public void registerSpatializerHeadTrackerAvailableCallback( 11704 @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) { 11705 Objects.requireNonNull(cb); 11706 mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register); 11707 } 11708 11709 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11710 /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */ registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)11711 public void registerHeadToSoundstagePoseCallback( 11712 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 11713 super.registerHeadToSoundstagePoseCallback_enforcePermission(); 11714 11715 Objects.requireNonNull(cb); 11716 mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb); 11717 } 11718 11719 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11720 /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */ unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)11721 public void unregisterHeadToSoundstagePoseCallback( 11722 @NonNull ISpatializerHeadToSoundStagePoseCallback cb) { 11723 super.unregisterHeadToSoundstagePoseCallback_enforcePermission(); 11724 11725 Objects.requireNonNull(cb); 11726 mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb); 11727 } 11728 11729 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11730 /** @see Spatializer#getSpatializerCompatibleAudioDevices() */ getSpatializerCompatibleAudioDevices()11731 public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() { 11732 super.getSpatializerCompatibleAudioDevices_enforcePermission(); 11733 11734 return mSpatializerHelper.getCompatibleAudioDevices(); 11735 } 11736 11737 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11738 /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)11739 public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 11740 super.addSpatializerCompatibleAudioDevice_enforcePermission(); 11741 11742 Objects.requireNonNull(ada); 11743 mSpatializerHelper.addCompatibleAudioDevice(ada); 11744 } 11745 11746 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11747 /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */ removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)11748 public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { 11749 super.removeSpatializerCompatibleAudioDevice_enforcePermission(); 11750 11751 Objects.requireNonNull(ada); 11752 mSpatializerHelper.removeCompatibleAudioDevice(ada); 11753 } 11754 11755 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11756 /** @see Spatializer#getSupportedHeadTrackingModes() */ getSupportedHeadTrackingModes()11757 public int[] getSupportedHeadTrackingModes() { 11758 super.getSupportedHeadTrackingModes_enforcePermission(); 11759 11760 return mSpatializerHelper.getSupportedHeadTrackingModes(); 11761 } 11762 11763 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11764 /** @see Spatializer#getHeadTrackingMode() */ getActualHeadTrackingMode()11765 public int getActualHeadTrackingMode() { 11766 super.getActualHeadTrackingMode_enforcePermission(); 11767 11768 return mSpatializerHelper.getActualHeadTrackingMode(); 11769 } 11770 11771 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11772 /** @see Spatializer#getDesiredHeadTrackingMode() */ getDesiredHeadTrackingMode()11773 public int getDesiredHeadTrackingMode() { 11774 super.getDesiredHeadTrackingMode_enforcePermission(); 11775 11776 return mSpatializerHelper.getDesiredHeadTrackingMode(); 11777 } 11778 11779 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11780 /** @see Spatializer#setGlobalTransform */ setSpatializerGlobalTransform(@onNull float[] transform)11781 public void setSpatializerGlobalTransform(@NonNull float[] transform) { 11782 super.setSpatializerGlobalTransform_enforcePermission(); 11783 11784 Objects.requireNonNull(transform); 11785 mSpatializerHelper.setGlobalTransform(transform); 11786 } 11787 11788 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11789 /** @see Spatializer#recenterHeadTracker() */ recenterHeadTracker()11790 public void recenterHeadTracker() { 11791 super.recenterHeadTracker_enforcePermission(); 11792 11793 mSpatializerHelper.recenterHeadTracker(); 11794 } 11795 11796 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11797 /** @see Spatializer#setDesiredHeadTrackingMode */ setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)11798 public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) { 11799 super.setDesiredHeadTrackingMode_enforcePermission(); 11800 11801 switch(mode) { 11802 case Spatializer.HEAD_TRACKING_MODE_DISABLED: 11803 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD: 11804 case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE: 11805 break; 11806 default: 11807 return; 11808 } 11809 mSpatializerHelper.setDesiredHeadTrackingMode(mode); 11810 } 11811 11812 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11813 /** @see Spatializer#setEffectParameter */ setSpatializerParameter(int key, @NonNull byte[] value)11814 public void setSpatializerParameter(int key, @NonNull byte[] value) { 11815 super.setSpatializerParameter_enforcePermission(); 11816 11817 Objects.requireNonNull(value); 11818 mSpatializerHelper.setEffectParameter(key, value); 11819 } 11820 11821 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11822 /** @see Spatializer#getEffectParameter */ getSpatializerParameter(int key, @NonNull byte[] value)11823 public void getSpatializerParameter(int key, @NonNull byte[] value) { 11824 super.getSpatializerParameter_enforcePermission(); 11825 11826 Objects.requireNonNull(value); 11827 mSpatializerHelper.getEffectParameter(key, value); 11828 } 11829 11830 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11831 /** @see Spatializer#getOutput */ getSpatializerOutput()11832 public int getSpatializerOutput() { 11833 super.getSpatializerOutput_enforcePermission(); 11834 11835 return mSpatializerHelper.getOutput(); 11836 } 11837 11838 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11839 /** @see Spatializer#setOnSpatializerOutputChangedListener */ registerSpatializerOutputCallback(ISpatializerOutputCallback cb)11840 public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) { 11841 super.registerSpatializerOutputCallback_enforcePermission(); 11842 11843 Objects.requireNonNull(cb); 11844 mSpatializerHelper.registerSpatializerOutputCallback(cb); 11845 } 11846 11847 @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS) 11848 /** @see Spatializer#clearOnSpatializerOutputChangedListener */ unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)11849 public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) { 11850 super.unregisterSpatializerOutputCallback_enforcePermission(); 11851 11852 Objects.requireNonNull(cb); 11853 mSpatializerHelper.unregisterSpatializerOutputCallback(cb); 11854 } 11855 11856 /** 11857 * post a message to schedule init/release of head tracking sensors 11858 * whether to initialize or release sensors is based on the state of spatializer 11859 */ postInitSpatializerHeadTrackingSensors()11860 void postInitSpatializerHeadTrackingSensors() { 11861 sendMsg(mAudioHandler, 11862 MSG_INIT_HEADTRACKING_SENSORS, 11863 SENDMSG_REPLACE, 11864 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 11865 } 11866 11867 /** 11868 * post a message to schedule a reset of the spatializer state 11869 */ postResetSpatializer()11870 void postResetSpatializer() { 11871 sendMsg(mAudioHandler, 11872 MSG_RESET_SPATIALIZER, 11873 SENDMSG_REPLACE, 11874 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0); 11875 } 11876 onInitAdiDeviceStates()11877 void onInitAdiDeviceStates() { 11878 mDeviceBroker.onReadAudioDeviceSettings(); 11879 mSoundDoseHelper.initCachedAudioDeviceCategories( 11880 mDeviceBroker.getImmutableDeviceInventory()); 11881 } 11882 onInitSpatializer()11883 void onInitSpatializer() { 11884 mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect); 11885 mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect); 11886 } 11887 isSADevice(AdiDeviceState deviceState)11888 /*package*/ boolean isSADevice(AdiDeviceState deviceState) { 11889 return mSpatializerHelper.isSADevice(deviceState); 11890 } 11891 isBluetoothPrividged()11892 private boolean isBluetoothPrividged() { 11893 return PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 11894 Manifest.permission.BLUETOOTH_CONNECT) 11895 || Binder.getCallingUid() == Process.SYSTEM_UID; 11896 } 11897 retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices)11898 List<AudioDeviceAttributes> retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices) { 11899 if (isBluetoothPrividged()) { 11900 return devices; 11901 } 11902 11903 List<AudioDeviceAttributes> checkedDevices = new ArrayList<AudioDeviceAttributes>(); 11904 for (AudioDeviceAttributes ada : devices) { 11905 if (ada == null) { 11906 continue; 11907 } 11908 checkedDevices.add(retrieveBluetoothAddressUncheked(ada)); 11909 } 11910 return checkedDevices; 11911 } 11912 retrieveBluetoothAddress(@onNull AudioDeviceAttributes ada)11913 AudioDeviceAttributes retrieveBluetoothAddress(@NonNull AudioDeviceAttributes ada) { 11914 if (isBluetoothPrividged()) { 11915 return ada; 11916 } 11917 return retrieveBluetoothAddressUncheked(ada); 11918 } 11919 retrieveBluetoothAddressUncheked(@onNull AudioDeviceAttributes ada)11920 AudioDeviceAttributes retrieveBluetoothAddressUncheked(@NonNull AudioDeviceAttributes ada) { 11921 Objects.requireNonNull(ada); 11922 if (AudioSystem.isBluetoothDevice(ada.getInternalType())) { 11923 String anonymizedAddress = Utils.anonymizeBluetoothAddress(ada.getAddress()); 11924 for (AdiDeviceState ads : mDeviceBroker.getImmutableDeviceInventory()) { 11925 if (!(AudioSystem.isBluetoothDevice(ads.getInternalDeviceType()) 11926 && (ada.getInternalType() == ads.getInternalDeviceType()) 11927 && anonymizedAddress.equals(Utils.anonymizeBluetoothAddress( 11928 ads.getDeviceAddress())))) { 11929 continue; 11930 } 11931 ada.setAddress(ads.getDeviceAddress()); 11932 break; 11933 } 11934 } 11935 return ada; 11936 } 11937 anonymizeAudioDeviceAttributesList( List<AudioDeviceAttributes> devices)11938 private List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesList( 11939 List<AudioDeviceAttributes> devices) { 11940 if (isBluetoothPrividged()) { 11941 return devices; 11942 } 11943 return anonymizeAudioDeviceAttributesListUnchecked(devices); 11944 } 11945 anonymizeAudioDeviceAttributesListUnchecked( List<AudioDeviceAttributes> devices)11946 /* package */ List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesListUnchecked( 11947 List<AudioDeviceAttributes> devices) { 11948 List<AudioDeviceAttributes> anonymizedDevices = new ArrayList<AudioDeviceAttributes>(); 11949 for (AudioDeviceAttributes ada : devices) { 11950 anonymizedDevices.add(anonymizeAudioDeviceAttributesUnchecked(ada)); 11951 } 11952 return anonymizedDevices; 11953 } 11954 anonymizeAudioDeviceAttributesUnchecked( AudioDeviceAttributes ada)11955 private AudioDeviceAttributes anonymizeAudioDeviceAttributesUnchecked( 11956 AudioDeviceAttributes ada) { 11957 if (ada == null || !AudioSystem.isBluetoothDevice(ada.getInternalType())) { 11958 return ada; 11959 } 11960 AudioDeviceAttributes res = new AudioDeviceAttributes(ada); 11961 res.setAddress(Utils.anonymizeBluetoothAddress(ada.getAddress())); 11962 return res; 11963 } 11964 anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada)11965 private AudioDeviceAttributes anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada) { 11966 if (isBluetoothPrividged()) { 11967 return ada; 11968 } 11969 11970 return anonymizeAudioDeviceAttributesUnchecked(ada); 11971 } 11972 11973 // ======================================================================================== 11974 // LoudnessCodecConfigurator 11975 11976 @Override registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher)11977 public void registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher) { 11978 mLoudnessCodecHelper.registerLoudnessCodecUpdatesDispatcher(dispatcher); 11979 } 11980 11981 @Override unregisterLoudnessCodecUpdatesDispatcher( ILoudnessCodecUpdatesDispatcher dispatcher)11982 public void unregisterLoudnessCodecUpdatesDispatcher( 11983 ILoudnessCodecUpdatesDispatcher dispatcher) { 11984 mLoudnessCodecHelper.unregisterLoudnessCodecUpdatesDispatcher(dispatcher); 11985 } 11986 11987 /** @see LoudnessCodecController#create(int) */ 11988 @Override startLoudnessCodecUpdates(int sessionId)11989 public void startLoudnessCodecUpdates(int sessionId) { 11990 mLoudnessCodecHelper.startLoudnessCodecUpdates(sessionId); 11991 } 11992 11993 /** @see LoudnessCodecController#close() */ 11994 @Override stopLoudnessCodecUpdates(int sessionId)11995 public void stopLoudnessCodecUpdates(int sessionId) { 11996 mLoudnessCodecHelper.stopLoudnessCodecUpdates(sessionId); 11997 } 11998 11999 /** @see LoudnessCodecController#addMediaCodec(MediaCodec) */ 12000 @Override addLoudnessCodecInfo(int sessionId, int mediaCodecHash, LoudnessCodecInfo codecInfo)12001 public void addLoudnessCodecInfo(int sessionId, int mediaCodecHash, 12002 LoudnessCodecInfo codecInfo) { 12003 mLoudnessCodecHelper.addLoudnessCodecInfo(sessionId, mediaCodecHash, codecInfo); 12004 } 12005 12006 /** @see LoudnessCodecController#removeMediaCodec(MediaCodec) */ 12007 @Override removeLoudnessCodecInfo(int sessionId, LoudnessCodecInfo codecInfo)12008 public void removeLoudnessCodecInfo(int sessionId, LoudnessCodecInfo codecInfo) { 12009 mLoudnessCodecHelper.removeLoudnessCodecInfo(sessionId, codecInfo); 12010 } 12011 12012 /** @see LoudnessCodecController#getLoudnessCodecParams(MediaCodec) */ 12013 @Override getLoudnessParams(LoudnessCodecInfo codecInfo)12014 public PersistableBundle getLoudnessParams(LoudnessCodecInfo codecInfo) { 12015 return mLoudnessCodecHelper.getLoudnessParams(codecInfo); 12016 } 12017 12018 //========================================================================================== 12019 12020 // camera sound is forced if any of the resources corresponding to one active SIM 12021 // demands it. readCameraSoundForced()12022 private boolean readCameraSoundForced() { 12023 if (SystemProperties.getBoolean("audio.camerasound.force", false) 12024 || mContext.getResources().getBoolean( 12025 com.android.internal.R.bool.config_camera_sound_forced)) { 12026 return true; 12027 } 12028 12029 SubscriptionManager subscriptionManager = mContext.getSystemService( 12030 SubscriptionManager.class); 12031 if (subscriptionManager == null) { 12032 Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!"); 12033 return false; 12034 } 12035 int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false); 12036 for (int subId : subscriptionIds) { 12037 if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean( 12038 com.android.internal.R.bool.config_camera_sound_forced)) { 12039 return true; 12040 } 12041 } 12042 return false; 12043 } 12044 12045 //========================================================================================== 12046 private final Object mMuteAwaitConnectionLock = new Object(); 12047 12048 /** 12049 * The device that is expected to be connected soon, and causes players to be muted until 12050 * its connection, or it times out. 12051 * Null when no active muting command, or it has timed out. 12052 */ 12053 @GuardedBy("mMuteAwaitConnectionLock") 12054 private AudioDeviceAttributes mMutingExpectedDevice; 12055 @GuardedBy("mMuteAwaitConnectionLock") 12056 private @Nullable int[] mMutedUsagesAwaitingConnection; 12057 12058 /** @see AudioManager#muteAwaitConnection */ 12059 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)12060 public void muteAwaitConnection(@NonNull int[] usages, 12061 @NonNull AudioDeviceAttributes device, long timeOutMs) { 12062 Objects.requireNonNull(usages); 12063 Objects.requireNonNull(device); 12064 enforceModifyAudioRoutingPermission(); 12065 12066 final AudioDeviceAttributes ada = retrieveBluetoothAddress(device); 12067 12068 if (timeOutMs <= 0 || usages.length == 0) { 12069 throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute"); 12070 } 12071 Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs 12072 + " usages:" + Arrays.toString(usages)); 12073 12074 if (mDeviceBroker.isDeviceConnected(ada)) { 12075 // not throwing an exception as there could be a race between a connection (server-side, 12076 // notification of connection in flight) and a mute operation (client-side) 12077 Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected"); 12078 return; 12079 } 12080 synchronized (mMuteAwaitConnectionLock) { 12081 if (mMutingExpectedDevice != null) { 12082 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:" 12083 + mMutingExpectedDevice); 12084 throw new IllegalStateException("muteAwaitConnection already in progress"); 12085 } 12086 mMutingExpectedDevice = ada; 12087 mMutedUsagesAwaitingConnection = usages; 12088 mPlaybackMonitor.muteAwaitConnection(usages, ada, timeOutMs); 12089 } 12090 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 12091 try { 12092 AudioDeviceAttributes dev = ada; 12093 if (!isPrivileged) { 12094 dev = anonymizeAudioDeviceAttributesUnchecked(ada); 12095 } 12096 cb.dispatchOnMutedUntilConnection(dev, usages); 12097 } catch (RemoteException e) { } 12098 }); 12099 } 12100 12101 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 12102 /** @see AudioManager#getMutingExpectedDevice */ getMutingExpectedDevice()12103 public @Nullable AudioDeviceAttributes getMutingExpectedDevice() { 12104 super.getMutingExpectedDevice_enforcePermission(); 12105 12106 synchronized (mMuteAwaitConnectionLock) { 12107 return anonymizeAudioDeviceAttributes(mMutingExpectedDevice); 12108 } 12109 } 12110 12111 /** @see AudioManager#cancelMuteAwaitConnection */ 12112 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)12113 public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) { 12114 Objects.requireNonNull(device); 12115 enforceModifyAudioRoutingPermission(); 12116 12117 final AudioDeviceAttributes ada = retrieveBluetoothAddress(device); 12118 12119 Log.i(TAG, "cancelMuteAwaitConnection for device:" + device); 12120 final int[] mutedUsages; 12121 synchronized (mMuteAwaitConnectionLock) { 12122 if (mMutingExpectedDevice == null) { 12123 // not throwing an exception as there could be a race between a timeout 12124 // (server-side) and a cancel operation (client-side) 12125 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device"); 12126 return; 12127 } 12128 if (!ada.equalTypeAddress(mMutingExpectedDevice)) { 12129 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device 12130 + "] but expected device is" + mMutingExpectedDevice); 12131 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device"); 12132 } 12133 mutedUsages = mMutedUsagesAwaitingConnection; 12134 mMutingExpectedDevice = null; 12135 mMutedUsagesAwaitingConnection = null; 12136 mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device); 12137 } 12138 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 12139 try { 12140 AudioDeviceAttributes dev = ada; 12141 if (!isPrivileged) { 12142 dev = anonymizeAudioDeviceAttributesUnchecked(ada); 12143 } 12144 cb.dispatchOnUnmutedEvent( 12145 AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, dev, mutedUsages); 12146 } catch (RemoteException e) { } }); 12147 } 12148 12149 final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers = 12150 new RemoteCallbackList<IMuteAwaitConnectionCallback>(); 12151 12152 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 12153 /** @see AudioManager#registerMuteAwaitConnectionCallback */ registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)12154 public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb, 12155 boolean register) { 12156 super.registerMuteAwaitConnectionDispatcher_enforcePermission(); 12157 12158 if (register) { 12159 mMuteAwaitConnectionDispatchers.register(cb, isBluetoothPrividged()); 12160 } else { 12161 mMuteAwaitConnectionDispatchers.unregister(cb); 12162 } 12163 } 12164 12165 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection checkMuteAwaitConnection()12166 void checkMuteAwaitConnection() { 12167 final AudioDeviceAttributes device; 12168 final int[] mutedUsages; 12169 synchronized (mMuteAwaitConnectionLock) { 12170 if (mMutingExpectedDevice == null) { 12171 return; 12172 } 12173 device = mMutingExpectedDevice; 12174 mutedUsages = mMutedUsagesAwaitingConnection; 12175 if (!mDeviceBroker.isDeviceConnected(device)) { 12176 return; 12177 } 12178 mMutingExpectedDevice = null; 12179 mMutedUsagesAwaitingConnection = null; 12180 mPlaybackMonitor.cancelMuteAwaitConnection( 12181 "checkMuteAwaitConnection device " + device + " connected, unmuting"); 12182 } 12183 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 12184 try { 12185 AudioDeviceAttributes ada = device; 12186 if (!isPrivileged) { 12187 ada = anonymizeAudioDeviceAttributesUnchecked(device); 12188 } 12189 cb.dispatchOnUnmutedEvent(AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION, 12190 ada, mutedUsages); 12191 } catch (RemoteException e) { } }); 12192 } 12193 12194 /** 12195 * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection 12196 */ 12197 @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)12198 void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) { 12199 final int[] mutedUsages; 12200 synchronized (mMuteAwaitConnectionLock) { 12201 if (!timedOutDevice.equals(mMutingExpectedDevice)) { 12202 return; 12203 } 12204 Log.i(TAG, "muteAwaitConnection timeout, clearing expected device " 12205 + mMutingExpectedDevice); 12206 mutedUsages = mMutedUsagesAwaitingConnection; 12207 mMutingExpectedDevice = null; 12208 mMutedUsagesAwaitingConnection = null; 12209 } 12210 dispatchMuteAwaitConnection((cb, isPrivileged) -> { 12211 try { 12212 cb.dispatchOnUnmutedEvent( 12213 AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT, 12214 timedOutDevice, mutedUsages); 12215 } catch (RemoteException e) { } }); 12216 } 12217 dispatchMuteAwaitConnection( java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback)12218 private void dispatchMuteAwaitConnection( 12219 java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback) { 12220 final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast(); 12221 // lazy initialization as errors unlikely 12222 ArrayList<IMuteAwaitConnectionCallback> errorList = null; 12223 for (int i = 0; i < nbDispatchers; i++) { 12224 try { 12225 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i), 12226 (Boolean) mMuteAwaitConnectionDispatchers.getBroadcastCookie(i)); 12227 } catch (Exception e) { 12228 if (errorList == null) { 12229 errorList = new ArrayList<>(1); 12230 } 12231 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i)); 12232 } 12233 } 12234 if (errorList != null) { 12235 for (IMuteAwaitConnectionCallback errorItem : errorList) { 12236 mMuteAwaitConnectionDispatchers.unregister(errorItem); 12237 } 12238 } 12239 mMuteAwaitConnectionDispatchers.finishBroadcast(); 12240 } 12241 12242 final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers = 12243 new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>(); 12244 12245 /** 12246 * @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and 12247 * AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener 12248 */ registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)12249 public void registerDeviceVolumeBehaviorDispatcher(boolean register, 12250 @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) { 12251 enforceQueryStateOrModifyRoutingPermission(); 12252 Objects.requireNonNull(dispatcher); 12253 if (register) { 12254 mDeviceVolumeBehaviorDispatchers.register(dispatcher); 12255 } else { 12256 mDeviceVolumeBehaviorDispatchers.unregister(dispatcher); 12257 } 12258 } 12259 dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)12260 private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) { 12261 final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast(); 12262 for (int i = 0; i < dispatchers; i++) { 12263 try { 12264 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i) 12265 .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior); 12266 } catch (RemoteException e) { 12267 } 12268 } 12269 mDeviceVolumeBehaviorDispatchers.finishBroadcast(); 12270 } 12271 12272 //========================================================================================== 12273 // Device orientation 12274 //========================================================================================== 12275 /** 12276 * Handles device configuration changes that may map to a change in rotation. 12277 * Monitoring rotation is optional, and is defined by the definition and value 12278 * of the "ro.audio.monitorRotation" system property. 12279 */ onConfigurationChanged()12280 private void onConfigurationChanged() { 12281 try { 12282 // reading new configuration "safely" (i.e. under try catch) in case anything 12283 // goes wrong. 12284 Configuration config = mContext.getResources().getConfiguration(); 12285 mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG); 12286 12287 final boolean cameraSoundForced = readCameraSoundForced(); 12288 final boolean cameraSoundForcedChanged = 12289 (mCameraSoundForced.getAndSet(cameraSoundForced) != cameraSoundForced); 12290 synchronized (mSettingsLock) { 12291 if (cameraSoundForcedChanged) { 12292 if (!mIsSingleVolume) { 12293 synchronized (mVolumeStateLock) { 12294 final VolumeStreamState s = getVssForStreamOrDefault( 12295 AudioSystem.STREAM_SYSTEM_ENFORCED); 12296 if (cameraSoundForced) { 12297 s.setAllIndexesToMax(); 12298 mRingerModeAffectedStreams &= 12299 ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 12300 } else { 12301 s.setAllIndexes(getVssForStreamOrDefault(AudioSystem.STREAM_SYSTEM), 12302 TAG); 12303 mRingerModeAffectedStreams |= 12304 (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 12305 } 12306 } 12307 // take new state into account for streams muted by ringer mode 12308 setRingerModeInt(getRingerModeInternal(), false); 12309 } 12310 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, 12311 cameraSoundForced ? 12312 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 12313 "onConfigurationChanged"); 12314 sendMsg(mAudioHandler, 12315 MSG_SET_ALL_VOLUMES, 12316 SENDMSG_QUEUE, 12317 0, 12318 0, 12319 getVssForStreamOrDefault(AudioSystem.STREAM_SYSTEM_ENFORCED), 0); 12320 } 12321 } 12322 mVolumeController.setLayoutDirection(config.getLayoutDirection()); 12323 } catch (Exception e) { 12324 Log.e(TAG, "Error handling configuration change: ", e); 12325 } 12326 } 12327 12328 @android.annotation.EnforcePermission(Manifest.permission.REMOTE_AUDIO_PLAYBACK) 12329 @Override setRingtonePlayer(IRingtonePlayer player)12330 public void setRingtonePlayer(IRingtonePlayer player) { 12331 setRingtonePlayer_enforcePermission(); 12332 mRingtonePlayer = player; 12333 } 12334 12335 @Override getRingtonePlayer()12336 public IRingtonePlayer getRingtonePlayer() { 12337 return mRingtonePlayer; 12338 } 12339 12340 @Override startWatchingRoutes(IAudioRoutesObserver observer)12341 public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { 12342 return mDeviceBroker.startWatchingRoutes(observer); 12343 } 12344 12345 @Override disableSafeMediaVolume(String callingPackage)12346 public void disableSafeMediaVolume(String callingPackage) { 12347 enforceVolumeController("disable the safe media volume"); 12348 mSoundDoseHelper.disableSafeMediaVolume(callingPackage); 12349 } 12350 12351 @Override lowerVolumeToRs1(String callingPackage)12352 public void lowerVolumeToRs1(String callingPackage) { 12353 enforceVolumeController("lowerVolumeToRs1"); 12354 postLowerVolumeToRs1(); 12355 } 12356 postLowerVolumeToRs1()12357 /*package*/ void postLowerVolumeToRs1() { 12358 sendMsg(mAudioHandler, SoundDoseHelper.MSG_LOWER_VOLUME_TO_RS1, SENDMSG_QUEUE, 12359 // no params, no delay 12360 0, 0, null, 0); 12361 } 12362 12363 @Override 12364 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getOutputRs2UpperBound()12365 public float getOutputRs2UpperBound() { 12366 super.getOutputRs2UpperBound_enforcePermission(); 12367 return mSoundDoseHelper.getOutputRs2UpperBound(); 12368 } 12369 12370 @Override 12371 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setOutputRs2UpperBound(float rs2Value)12372 public void setOutputRs2UpperBound(float rs2Value) { 12373 super.setOutputRs2UpperBound_enforcePermission(); 12374 mSoundDoseHelper.setOutputRs2UpperBound(rs2Value); 12375 } 12376 12377 @Override 12378 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getCsd()12379 public float getCsd() { 12380 super.getCsd_enforcePermission(); 12381 return mSoundDoseHelper.getCsd(); 12382 } 12383 12384 @Override 12385 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setCsd(float csd)12386 public void setCsd(float csd) { 12387 super.setCsd_enforcePermission(); 12388 if (csd < 0.0f) { 12389 mSoundDoseHelper.resetCsdTimeouts(); 12390 } else { 12391 mSoundDoseHelper.setCsd(csd); 12392 } 12393 } 12394 12395 @Override 12396 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) forceUseFrameworkMel(boolean useFrameworkMel)12397 public void forceUseFrameworkMel(boolean useFrameworkMel) { 12398 super.forceUseFrameworkMel_enforcePermission(); 12399 mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel); 12400 } 12401 12402 @Override 12403 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices)12404 public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) { 12405 super.forceComputeCsdOnAllDevices_enforcePermission(); 12406 mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices); 12407 } 12408 12409 @Override 12410 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdEnabled()12411 public boolean isCsdEnabled() { 12412 super.isCsdEnabled_enforcePermission(); 12413 return mSoundDoseHelper.isCsdEnabled(); 12414 } 12415 12416 @Override 12417 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdAsAFeatureAvailable()12418 public boolean isCsdAsAFeatureAvailable() { 12419 super.isCsdAsAFeatureAvailable_enforcePermission(); 12420 return mSoundDoseHelper.isCsdAsAFeatureAvailable(); 12421 } 12422 12423 @Override 12424 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isCsdAsAFeatureEnabled()12425 public boolean isCsdAsAFeatureEnabled() { 12426 super.isCsdAsAFeatureEnabled_enforcePermission(); 12427 return mSoundDoseHelper.isCsdAsAFeatureEnabled(); 12428 } 12429 12430 @Override 12431 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setCsdAsAFeatureEnabled(boolean csdToggleValue)12432 public void setCsdAsAFeatureEnabled(boolean csdToggleValue) { 12433 super.setCsdAsAFeatureEnabled_enforcePermission(); 12434 mSoundDoseHelper.setCsdAsAFeatureEnabled(csdToggleValue); 12435 } 12436 12437 @Override 12438 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setBluetoothAudioDeviceCategory(@onNull String address, @AudioDeviceCategory int btAudioDeviceCategory)12439 public boolean setBluetoothAudioDeviceCategory(@NonNull String address, 12440 @AudioDeviceCategory int btAudioDeviceCategory) { 12441 super.setBluetoothAudioDeviceCategory_enforcePermission(); 12442 12443 final String addr = Objects.requireNonNull(address); 12444 if (isBluetoothAudioDeviceCategoryFixed(addr)) { 12445 Log.w(TAG, "Cannot set fixed audio device type for address " 12446 + Utils.anonymizeBluetoothAddress(address)); 12447 return false; 12448 } 12449 12450 mDeviceBroker.addAudioDeviceWithCategoryInInventoryIfNeeded(address, btAudioDeviceCategory); 12451 12452 return true; 12453 } 12454 12455 @Override 12456 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) 12457 @AudioDeviceCategory getBluetoothAudioDeviceCategory(@onNull String address)12458 public int getBluetoothAudioDeviceCategory(@NonNull String address) { 12459 super.getBluetoothAudioDeviceCategory_enforcePermission(); 12460 12461 return mDeviceBroker.getAndUpdateBtAdiDeviceStateCategoryForAddress(address); 12462 } 12463 12464 @Override 12465 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) isBluetoothAudioDeviceCategoryFixed(@onNull String address)12466 public boolean isBluetoothAudioDeviceCategoryFixed(@NonNull String address) { 12467 super.isBluetoothAudioDeviceCategoryFixed_enforcePermission(); 12468 12469 return mDeviceBroker.isBluetoothAudioDeviceCategoryFixed(address); 12470 } 12471 12472 /** Update the sound dose and spatializer state based on the new AdiDeviceState. */ 12473 @VisibleForTesting(visibility = PACKAGE) onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA)12474 public void onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA) { 12475 if (deviceState == null) { 12476 return; 12477 } 12478 mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(), initSA); 12479 mSoundDoseHelper.setAudioDeviceCategory(deviceState.getDeviceAddress(), 12480 deviceState.getInternalDeviceType(), 12481 deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES); 12482 } 12483 12484 //========================================================================================== 12485 // Hdmi CEC: 12486 // - System audio mode: 12487 // If Hdmi Cec's system audio mode is on, audio service should send the volume change 12488 // to HdmiControlService so that the audio receiver can handle it. 12489 // - CEC sink: 12490 // OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level 12491 // and volume changes won't be taken into account on this device. Volume adjustments 12492 // are transformed into key events for the HDMI playback client. 12493 //========================================================================================== 12494 12495 @GuardedBy("mHdmiClientLock") updateHdmiCecSinkLocked(boolean hdmiCecSink)12496 private void updateHdmiCecSinkLocked(boolean hdmiCecSink) { 12497 if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) { 12498 if (hdmiCecSink) { 12499 if (DEBUG_VOL) { 12500 Log.d(TAG, "CEC sink: setting HDMI as full vol device"); 12501 } 12502 setDeviceVolumeBehaviorInternal( 12503 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 12504 AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, 12505 "AudioService.updateHdmiCecSinkLocked()"); 12506 } else { 12507 if (DEBUG_VOL) { 12508 Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device"); 12509 } 12510 // Android TV devices without CEC service apply software volume on 12511 // HDMI output 12512 setDeviceVolumeBehaviorInternal( 12513 new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""), 12514 AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE, 12515 "AudioService.updateHdmiCecSinkLocked()"); 12516 } 12517 postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI, 12518 "HdmiPlaybackClient.DisplayStatusCallback"); 12519 } 12520 } 12521 12522 private class MyHdmiControlStatusChangeListenerCallback 12523 implements HdmiControlManager.HdmiControlStatusChangeListener { onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)12524 public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled, 12525 boolean isCecAvailable) { 12526 synchronized (mHdmiClientLock) { 12527 if (mHdmiManager == null) return; 12528 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED; 12529 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false); 12530 } 12531 } 12532 }; 12533 12534 private class MyHdmiCecVolumeControlFeatureListener 12535 implements HdmiControlManager.HdmiCecVolumeControlFeatureListener { onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)12536 public void onHdmiCecVolumeControlFeature( 12537 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) { 12538 synchronized (mHdmiClientLock) { 12539 if (mHdmiManager == null) return; 12540 mHdmiCecVolumeControlEnabled = 12541 hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED; 12542 } 12543 } 12544 }; 12545 12546 private final Object mHdmiClientLock = new Object(); 12547 12548 // If HDMI-CEC system audio is supported 12549 // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume 12550 // commands 12551 private boolean mHdmiSystemAudioSupported = false; 12552 // Set only when device is tv. 12553 @GuardedBy("mHdmiClientLock") 12554 private HdmiTvClient mHdmiTvClient; 12555 // true if the device has system feature PackageManager.FEATURE_LEANBACK. 12556 // cached HdmiControlManager interface 12557 @GuardedBy("mHdmiClientLock") 12558 private HdmiControlManager mHdmiManager; 12559 // Set only when device is a set-top box. 12560 @GuardedBy("mHdmiClientLock") 12561 private HdmiPlaybackClient mHdmiPlaybackClient; 12562 // Set only when device is an audio system. 12563 @GuardedBy("mHdmiClientLock") 12564 private HdmiAudioSystemClient mHdmiAudioSystemClient; 12565 // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise) 12566 @GuardedBy("mHdmiClientLock") 12567 private boolean mHdmiCecVolumeControlEnabled; 12568 12569 private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback = 12570 new MyHdmiControlStatusChangeListenerCallback(); 12571 12572 private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener = 12573 new MyHdmiCecVolumeControlFeatureListener(); 12574 12575 @Override setHdmiSystemAudioSupported(boolean on)12576 public int setHdmiSystemAudioSupported(boolean on) { 12577 int device = AudioSystem.DEVICE_NONE; 12578 synchronized (mHdmiClientLock) { 12579 if (mHdmiManager != null) { 12580 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) { 12581 Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports" 12582 + "system audio mode."); 12583 return device; 12584 } 12585 if (mHdmiSystemAudioSupported != on) { 12586 mHdmiSystemAudioSupported = on; 12587 final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : 12588 AudioSystem.FORCE_NONE; 12589 mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config, 12590 "setHdmiSystemAudioSupported"); 12591 } 12592 // TODO(b/185386781): Update AudioManager API to use device list. 12593 // So far, this value appears to be advisory for debug log. 12594 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC); 12595 } 12596 } 12597 return device; 12598 } 12599 12600 @Override isHdmiSystemAudioSupported()12601 public boolean isHdmiSystemAudioSupported() { 12602 return mHdmiSystemAudioSupported; 12603 } 12604 12605 //========================================================================================== 12606 // Accessibility 12607 initA11yMonitoring()12608 private void initA11yMonitoring() { 12609 final AccessibilityManager accessibilityManager = 12610 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 12611 updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled()); 12612 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 12613 accessibilityManager.addTouchExplorationStateChangeListener(this, null); 12614 accessibilityManager.addAccessibilityServicesStateChangeListener(this); 12615 } 12616 12617 //--------------------------------------------------------------------------------- 12618 // A11y: taking touch exploration into account for selecting the default 12619 // stream override timeout when adjusting volume 12620 //--------------------------------------------------------------------------------- 12621 12622 // - STREAM_NOTIFICATION on tablets during this period after a notification stopped 12623 // - STREAM_RING on phones during this period after a notification stopped 12624 // - STREAM_MUSIC otherwise 12625 12626 private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0; 12627 private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000; 12628 12629 private static int sStreamOverrideDelayMs; 12630 12631 @Override onTouchExplorationStateChanged(boolean enabled)12632 public void onTouchExplorationStateChanged(boolean enabled) { 12633 updateDefaultStreamOverrideDelay(enabled); 12634 } 12635 updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)12636 private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) { 12637 if (touchExploreEnabled) { 12638 sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS; 12639 } else { 12640 sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS; 12641 } 12642 if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled 12643 + " stream override delay is now " + sStreamOverrideDelayMs + " ms"); 12644 } 12645 12646 //--------------------------------------------------------------------------------- 12647 // A11y: taking a11y state into account for the handling of a11y prompts volume 12648 //--------------------------------------------------------------------------------- 12649 12650 private static boolean sIndependentA11yVolume = false; 12651 12652 // implementation of AccessibilityServicesStateChangeListener 12653 @Override onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)12654 public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) { 12655 updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive()); 12656 } 12657 updateA11yVolumeAlias(boolean a11VolEnabled)12658 private void updateA11yVolumeAlias(boolean a11VolEnabled) { 12659 if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled); 12660 if (mIsSingleVolume) { 12661 if (DEBUG_VOL) Log.d(TAG, "Accessibility volume is not set on single volume device"); 12662 return; 12663 } 12664 if (sIndependentA11yVolume != a11VolEnabled) { 12665 sIndependentA11yVolume = a11VolEnabled; 12666 // update the volume mapping scheme 12667 updateStreamVolumeAlias(true /*updateVolumes*/, TAG); 12668 // update the volume controller behavior 12669 mVolumeController.setA11yMode(sIndependentA11yVolume ? 12670 VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME : 12671 VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME); 12672 mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0); 12673 } 12674 } 12675 12676 //========================================================================================== 12677 // Camera shutter sound policy. 12678 // config_camera_sound_forced configuration option in config.xml defines if the camera shutter 12679 // sound is forced (sound even if the device is in silent mode) or not. This option is false by 12680 // default and can be overridden by country specific overlay in values-mccXXX/config.xml. 12681 //========================================================================================== 12682 12683 // cached value of com.android.internal.R.bool.config_camera_sound_forced 12684 private AtomicBoolean mCameraSoundForced = new AtomicBoolean(false); 12685 12686 // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound isCameraSoundForced()12687 public boolean isCameraSoundForced() { 12688 return mCameraSoundForced.get(); 12689 } 12690 12691 //========================================================================================== 12692 // AudioService logging and dumpsys 12693 //========================================================================================== 12694 static final int LOG_NB_EVENTS_LIFECYCLE = 20; 12695 static final int LOG_NB_EVENTS_PHONE_STATE = 20; 12696 static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 200; 12697 static final int LOG_NB_EVENTS_FORCE_USE = 20; 12698 static final int LOG_NB_EVENTS_VOLUME = 100; 12699 static final int LOG_NB_EVENTS_DYN_POLICY = 10; 12700 static final int LOG_NB_EVENTS_SPATIAL = 30; 12701 static final int LOG_NB_EVENTS_SOUND_DOSE = 50; 12702 static final int LOG_NB_EVENTS_HARDENING = 50; 12703 12704 static final int LOG_NB_EVENTS_LOUDNESS_CODEC = 30; 12705 12706 static final EventLogger 12707 sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE, 12708 "audio services lifecycle"); 12709 12710 static final EventLogger sMuteLogger = new EventLogger(30, 12711 "mute commands"); 12712 12713 final private EventLogger 12714 mModeLogger = new EventLogger(LOG_NB_EVENTS_PHONE_STATE, 12715 "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))"); 12716 12717 // logs for wired + A2DP device connections: 12718 // - wired: logged before onSetWiredDeviceConnectionState() is executed 12719 // - A2DP: logged at reception of method call 12720 /*package*/ static final EventLogger 12721 sDeviceLogger = new EventLogger( 12722 LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection"); 12723 12724 static final EventLogger 12725 sForceUseLogger = new EventLogger( 12726 LOG_NB_EVENTS_FORCE_USE, 12727 "force use (logged before setForceUse() is executed)"); 12728 12729 static final EventLogger 12730 sVolumeLogger = new EventLogger(LOG_NB_EVENTS_VOLUME, 12731 "volume changes (logged when command received by AudioService)"); 12732 12733 static final EventLogger 12734 sSpatialLogger = new EventLogger(LOG_NB_EVENTS_SPATIAL, 12735 "spatial audio"); 12736 12737 final private EventLogger 12738 mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY, 12739 "dynamic policy events (logged when command received by AudioService)"); 12740 12741 private final EventLogger mHardeningLogger = new EventLogger( 12742 LOG_NB_EVENTS_HARDENING, "Hardening enforcement"); 12743 12744 private static final String[] RINGER_MODE_NAMES = new String[] { 12745 "SILENT", 12746 "VIBRATE", 12747 "NORMAL" 12748 }; 12749 dumpRingerMode(PrintWriter pw)12750 private void dumpRingerMode(PrintWriter pw) { 12751 pw.println("\nRinger mode: "); 12752 pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]); 12753 pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]); 12754 pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode())); 12755 dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams); 12756 dumpRingerModeStreams(pw, "muted", sRingerAndZenModeMutedStreams); 12757 pw.print("- delegate = "); pw.println(mRingerModeDelegate); 12758 } 12759 dumpRingerModeStreams(PrintWriter pw, String type, int streams)12760 private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) { 12761 pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x"); 12762 pw.print(Integer.toHexString(streams)); 12763 if (streams != 0) { 12764 pw.print(" ("); 12765 boolean first = true; 12766 for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) { 12767 final int stream = (1 << i); 12768 if ((streams & stream) != 0) { 12769 if (!first) pw.print(','); 12770 pw.print(AudioSystem.STREAM_NAMES[i]); 12771 streams &= ~stream; 12772 first = false; 12773 } 12774 } 12775 if (streams != 0) { 12776 if (!first) pw.print(','); 12777 pw.print(streams); 12778 } 12779 pw.print(')'); 12780 } 12781 pw.println(); 12782 } 12783 getAbsoluteVolumeDevicesWithBehavior(int behavior)12784 private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) { 12785 synchronized (mAbsoluteVolumeDeviceInfoMapLock) { 12786 return mAbsoluteVolumeDeviceInfoMap.entrySet().stream() 12787 .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior) 12788 .map(Map.Entry::getKey) 12789 .collect(Collectors.toSet()); 12790 } 12791 } 12792 dumpDeviceTypes(@onNull Set<Integer> deviceTypes)12793 private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) { 12794 Iterator<Integer> it = deviceTypes.iterator(); 12795 if (!it.hasNext()) { 12796 return ""; 12797 } 12798 final StringBuilder sb = new StringBuilder(); 12799 sb.append("0x" + Integer.toHexString(it.next())); 12800 while (it.hasNext()) { 12801 sb.append("," + "0x" + Integer.toHexString(it.next())); 12802 } 12803 return sb.toString(); 12804 } 12805 12806 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)12807 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12808 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 12809 12810 sLifecycleLogger.dump(pw); 12811 if (mAudioHandler != null) { 12812 pw.println("\nMessage handler (watch for unhandled messages):"); 12813 mAudioHandler.dump(new PrintWriterPrinter(pw), " "); 12814 } else { 12815 pw.println("\nMessage handler is null"); 12816 } 12817 dumpFlags(pw); 12818 mHardeningLogger.dump(pw); 12819 mMediaFocusControl.dump(pw); 12820 dumpStreamStates(pw); 12821 dumpVolumeGroups(pw); 12822 dumpRingerMode(pw); 12823 dumpAudioMode(pw); 12824 pw.println("\nAudio routes:"); 12825 pw.print(" mMainType=0x"); pw.println(Integer.toHexString( 12826 mDeviceBroker.getCurAudioRoutes().mainType)); 12827 pw.print(" mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName); 12828 12829 pw.println("\nOther state:"); 12830 pw.print(" mUseVolumeGroupAliases="); pw.println(mUseVolumeGroupAliases); 12831 pw.print(" mVolumeController="); pw.println(mVolumeController); 12832 mSoundDoseHelper.dump(pw); 12833 pw.print(" sIndependentA11yVolume="); pw.println(sIndependentA11yVolume); 12834 pw.print(" mCameraSoundForced="); pw.println(isCameraSoundForced()); 12835 pw.print(" mHasVibrator="); pw.println(mHasVibrator); 12836 pw.print(" mVolumePolicy="); pw.println(mVolumePolicy); 12837 pw.print(" mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported); 12838 pw.print(" mBtScoOnByApp="); pw.println(mBtScoOnByApp); 12839 pw.print(" mIsSingleVolume="); pw.println(mIsSingleVolume); 12840 pw.print(" mUseFixedVolume="); pw.println(mUseFixedVolume); 12841 pw.print(" mNotifAliasRing="); pw.println(mNotifAliasRing); 12842 pw.print(" mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices)); 12843 pw.print(" mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices)); 12844 pw.print(" absolute volume devices="); pw.println(dumpDeviceTypes( 12845 getAbsoluteVolumeDevicesWithBehavior( 12846 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE))); 12847 pw.print(" adjust-only absolute volume devices="); pw.println(dumpDeviceTypes( 12848 getAbsoluteVolumeDevicesWithBehavior( 12849 AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY))); 12850 pw.print(" pre-scale for bluetooth absolute volume "); 12851 if (disablePrescaleAbsoluteVolume()) { 12852 pw.println("= disabled"); 12853 } else { 12854 pw.println("=" + mPrescaleAbsoluteVolume[0] 12855 + ", " + mPrescaleAbsoluteVolume[1] 12856 + ", " + mPrescaleAbsoluteVolume[2]); 12857 } 12858 pw.print(" mExtVolumeController="); pw.println(mExtVolumeController); 12859 pw.print(" mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient); 12860 pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient); 12861 pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient); 12862 pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported); 12863 synchronized (mHdmiClientLock) { 12864 pw.print(" mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled); 12865 } 12866 pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported); 12867 pw.println(" mic mute FromSwitch=" + mMicMuteFromSwitch 12868 + " FromRestrictions=" + mMicMuteFromRestrictions 12869 + " FromApi=" + mMicMuteFromApi 12870 + " from system=" + mMicMuteFromSystemCached); 12871 pw.print(" mMasterMute="); pw.println(mMasterMute.get()); 12872 dumpAccessibilityServiceUids(pw); 12873 dumpAssistantServicesUids(pw); 12874 12875 pw.print(" supportsBluetoothVariableLatency="); 12876 pw.println(AudioSystem.supportsBluetoothVariableLatency()); 12877 pw.print(" isBluetoothVariableLatencyEnabled="); 12878 pw.println(AudioSystem.isBluetoothVariableLatencyEnabled()); 12879 12880 dumpAudioPolicies(pw); 12881 mDynPolicyLogger.dump(pw); 12882 mPlaybackMonitor.dump(pw); 12883 mRecordMonitor.dump(pw); 12884 12885 pw.println("\nAudioDeviceBroker:"); 12886 mDeviceBroker.dump(pw, " "); 12887 pw.println("\nSoundEffects:"); 12888 mSfxHelper.dump(pw, " "); 12889 12890 pw.println("\n"); 12891 pw.println("\nEvent logs:"); 12892 mModeLogger.dump(pw); 12893 pw.println("\n"); 12894 sDeviceLogger.dump(pw); 12895 pw.println("\n"); 12896 sForceUseLogger.dump(pw); 12897 pw.println("\n"); 12898 sVolumeLogger.dump(pw); 12899 pw.println("\n"); 12900 sMuteLogger.dump(pw); 12901 pw.println("\n"); 12902 dumpSupportedSystemUsage(pw); 12903 12904 pw.println("\n"); 12905 pw.println("\nSpatial audio:"); 12906 pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)"); 12907 pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)"); 12908 mSpatializerHelper.dump(pw); 12909 sSpatialLogger.dump(pw); 12910 12911 pw.println("\n"); 12912 pw.println("\nLoudness alignment:"); 12913 mLoudnessCodecHelper.dump(pw); 12914 12915 pw.println("\nAbsolute volume devices with their volume driving streams:"); 12916 synchronized (mCachedAbsVolDrivingStreamsLock) { 12917 mCachedAbsVolDrivingStreams.forEach((dev, stream) -> pw.println( 12918 "Device type: 0x" + Integer.toHexString(dev) + ", driving stream " + stream)); 12919 } 12920 12921 mAudioSystem.dump(pw); 12922 } 12923 dumpSupportedSystemUsage(PrintWriter pw)12924 private void dumpSupportedSystemUsage(PrintWriter pw) { 12925 pw.println("Supported System Usages:"); 12926 synchronized (mSupportedSystemUsagesLock) { 12927 for (int i = 0; i < mSupportedSystemUsages.length; i++) { 12928 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i])); 12929 } 12930 } 12931 } 12932 dumpAssistantServicesUids(PrintWriter pw)12933 private void dumpAssistantServicesUids(PrintWriter pw) { 12934 synchronized (mSettingsLock) { 12935 if (mAssistantUids.size() > 0) { 12936 pw.println(" Assistant service UIDs:"); 12937 for (int uid : mAssistantUids) { 12938 pw.println(" - " + uid); 12939 } 12940 } else { 12941 pw.println(" No Assistant service Uids."); 12942 } 12943 } 12944 } 12945 dumpAccessibilityServiceUids(PrintWriter pw)12946 private void dumpAccessibilityServiceUids(PrintWriter pw) { 12947 synchronized (mSupportedSystemUsagesLock) { 12948 if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) { 12949 pw.println(" Accessibility service Uids:"); 12950 for (int uid : mAccessibilityServiceUids) { 12951 pw.println(" - " + uid); 12952 } 12953 } else { 12954 pw.println(" No accessibility service Uids."); 12955 } 12956 } 12957 } 12958 12959 /** 12960 * Audio Analytics ids. 12961 */ 12962 private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE 12963 + MediaMetrics.SEPARATOR; 12964 initializeAudioServerPermissionProvider( Context context, AudioPolicyFacade audioPolicy, Executor audioserverExecutor)12965 private static AudioServerPermissionProvider initializeAudioServerPermissionProvider( 12966 Context context, AudioPolicyFacade audioPolicy, Executor audioserverExecutor) { 12967 Collection<PackageState> packageStates = null; 12968 try (PackageManagerLocal.UnfilteredSnapshot snapshot = 12969 LocalManagerRegistry.getManager(PackageManagerLocal.class) 12970 .withUnfilteredSnapshot()) { 12971 packageStates = snapshot.getPackageStates().values(); 12972 } 12973 var umi = LocalServices.getService(UserManagerInternal.class); 12974 var pmsi = LocalServices.getService(PermissionManagerServiceInternal.class); 12975 var provider = new AudioServerPermissionProvider(packageStates, 12976 (Integer uid, String perm) -> ActivityManager.checkComponentPermission(perm, uid, 12977 /* owningUid = */ -1, /* exported */true) 12978 == PackageManager.PERMISSION_GRANTED, 12979 () -> umi.getUserIds() 12980 ); 12981 audioPolicy.registerOnStartTask(() -> { 12982 provider.onServiceStart(audioPolicy.getPermissionController()); 12983 sLifecycleLogger.enqueue(new EventLogger.StringEvent( 12984 "Controller start task complete").printLog(ALOGI, TAG)); 12985 }); 12986 12987 IntentFilter packageUpdateFilter = new IntentFilter(); 12988 packageUpdateFilter.addAction(ACTION_PACKAGE_ADDED); 12989 packageUpdateFilter.addDataScheme("package"); 12990 12991 context.registerReceiverForAllUsers(new BroadcastReceiver() { 12992 @Override 12993 public void onReceive(Context context, Intent intent) { 12994 String action = intent.getAction(); 12995 String pkgName = intent.getData().getEncodedSchemeSpecificPart(); 12996 int uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID); 12997 if (intent.getBooleanExtra(EXTRA_REPLACING, false) || 12998 intent.getBooleanExtra(EXTRA_ARCHIVAL, false)) return; 12999 if (ACTION_PACKAGE_ADDED.equals(action)) { 13000 audioserverExecutor.execute(() -> 13001 provider.onModifyPackageState(uid, pkgName, false /* isRemoved */)); 13002 } 13003 } 13004 }, packageUpdateFilter, null, null); // main thread is fine, since dispatch on executor 13005 return provider; 13006 } 13007 13008 // Inform AudioFlinger of our device's low RAM attribute readAndSetLowRamDevice()13009 private static void readAndSetLowRamDevice() 13010 { 13011 boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic(); 13012 long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails. 13013 13014 try { 13015 final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo(); 13016 ActivityManager.getService().getMemoryInfo(info); 13017 totalMemory = info.totalMem; 13018 } catch (RemoteException e) { 13019 Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device"); 13020 isLowRamDevice = true; 13021 } 13022 13023 final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory); 13024 if (status != 0) { 13025 Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); 13026 } 13027 } 13028 enforceVolumeController(String action)13029 private void enforceVolumeController(String action) { 13030 mContext.enforceCallingOrSelfPermission(Manifest.permission.STATUS_BAR_SERVICE, 13031 "Only SystemUI can " + action); 13032 } 13033 13034 @Override setVolumeController(final IVolumeController controller)13035 public void setVolumeController(final IVolumeController controller) { 13036 enforceVolumeController("set the volume controller"); 13037 13038 // return early if things are not actually changing 13039 if (mVolumeController.isSameBinder(controller)) { 13040 return; 13041 } 13042 13043 // dismiss the old volume controller 13044 mVolumeController.postDismiss(); 13045 if (controller != null) { 13046 // we are about to register a new controller, listen for its death 13047 try { 13048 controller.asBinder().linkToDeath(new DeathRecipient() { 13049 @Override 13050 public void binderDied() { 13051 if (mVolumeController.isSameBinder(controller)) { 13052 Log.w(TAG, "Current remote volume controller died, unregistering"); 13053 setVolumeController(null); 13054 } 13055 } 13056 }, 0); 13057 } catch (RemoteException e) { 13058 // noop 13059 } 13060 } 13061 mVolumeController.setController(controller); 13062 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 13063 } 13064 13065 @Override 13066 @Nullable getVolumeController()13067 public IVolumeController getVolumeController() { 13068 enforceVolumeController("get the volume controller"); 13069 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 13070 13071 return mVolumeController.getController(); 13072 } 13073 13074 @Override notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)13075 public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) { 13076 enforceVolumeController("notify about volume controller visibility"); 13077 13078 // return early if the controller is not current 13079 if (!mVolumeController.isSameBinder(controller)) { 13080 return; 13081 } 13082 13083 mVolumeController.setVisible(visible); 13084 if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible); 13085 } 13086 13087 /** @see AudioManager#setVolumeControllerLongPressTimeoutEnabled(boolean) */ 13088 @Override 13089 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setVolumeControllerLongPressTimeoutEnabled(boolean enable)13090 public void setVolumeControllerLongPressTimeoutEnabled(boolean enable) { 13091 super.setVolumeControllerLongPressTimeoutEnabled_enforcePermission(); 13092 mVolumeControllerLongPressEnabled.set(enable); 13093 Log.i(TAG, "Volume controller long press timeout enabled: " + enable); 13094 } 13095 13096 @Override setVolumePolicy(VolumePolicy policy)13097 public void setVolumePolicy(VolumePolicy policy) { 13098 enforceVolumeController("set volume policy"); 13099 if (policy != null && !policy.equals(mVolumePolicy)) { 13100 mVolumePolicy = policy; 13101 if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy); 13102 } 13103 } 13104 13105 @Override getVolumePolicy()13106 public VolumePolicy getVolumePolicy() { 13107 return mVolumePolicy; 13108 } 13109 13110 /** Interface used for enforcing the safe hearing standard. */ 13111 public interface ISafeHearingVolumeController { 13112 /** Displays an instructional safeguard as required by the safe hearing standard. */ postDisplaySafeVolumeWarning(int flags)13113 void postDisplaySafeVolumeWarning(int flags); 13114 13115 /** Displays a warning about transient exposure to high level playback */ postDisplayCsdWarning(@udioManager.CsdWarning int csdEvent, int displayDurationMs)13116 void postDisplayCsdWarning(@AudioManager.CsdWarning int csdEvent, int displayDurationMs); 13117 } 13118 13119 /** Wrapper which encapsulates the {@link IVolumeController} functionality. */ 13120 public class VolumeController implements ISafeHearingVolumeController { 13121 private static final String TAG = "VolumeController"; 13122 13123 private IVolumeController mController; 13124 private boolean mVisible; 13125 private long mNextLongPress; 13126 private int mLongPressTimeout; 13127 setController(IVolumeController controller)13128 public void setController(IVolumeController controller) { 13129 mController = controller; 13130 mVisible = false; 13131 } 13132 getController()13133 public IVolumeController getController() { 13134 return mController; 13135 } 13136 loadSettings(ContentResolver cr)13137 public void loadSettings(ContentResolver cr) { 13138 mLongPressTimeout = mSettings.getSecureIntForUser(cr, 13139 Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT); 13140 } 13141 suppressAdjustment(int resolvedStream, int flags, boolean isMute)13142 public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) { 13143 if (isMute) { 13144 return false; 13145 } 13146 boolean suppress = false; 13147 // Intended behavior: 13148 // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved 13149 // in bringing up the UI) 13150 // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress 13151 // 3/ otherwise suppress the first adjustments that occur during the "long press 13152 // timeout" interval. Note this is true regardless of whether this is a "real long 13153 // press" (where the user keeps pressing on the volume button), or repeated single 13154 // presses (here we don't know if we are in a real long press, or repeated fast 13155 // button presses). 13156 // Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress. 13157 // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly 13158 // the volume when media is playing (whether by long press or repeated individual 13159 // presses), or to bring up the volume UI when media is not playing, in order to make 13160 // another change (e.g. switch ringer modes) without changing media volume. 13161 if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) { 13162 // never suppress media vol adjustement during media playback 13163 if (resolvedStream == AudioSystem.STREAM_MUSIC 13164 && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout)) 13165 { 13166 // media is playing, adjust the volume right away 13167 return false; 13168 } 13169 13170 final long now = SystemClock.uptimeMillis(); 13171 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) { 13172 // UI is not visible yet, adjustment is ignored 13173 if (mNextLongPress < now) { 13174 mNextLongPress = 13175 now + (mVolumeControllerLongPressEnabled.get() ? mLongPressTimeout 13176 : 0); 13177 } 13178 suppress = true; 13179 } else if (mNextLongPress > 0) { // in a long-press 13180 if (now > mNextLongPress) { 13181 // long press triggered, no more suppression 13182 mNextLongPress = 0; 13183 } else { 13184 // keep suppressing until the long press triggers 13185 suppress = true; 13186 } 13187 } 13188 } 13189 return suppress; 13190 } 13191 setVisible(boolean visible)13192 public void setVisible(boolean visible) { 13193 mVisible = visible; 13194 } 13195 isSameBinder(IVolumeController controller)13196 public boolean isSameBinder(IVolumeController controller) { 13197 return Objects.equals(asBinder(), binder(controller)); 13198 } 13199 asBinder()13200 public IBinder asBinder() { 13201 return binder(mController); 13202 } 13203 binder(IVolumeController controller)13204 private IBinder binder(IVolumeController controller) { 13205 return controller == null ? null : controller.asBinder(); 13206 } 13207 13208 @Override toString()13209 public String toString() { 13210 return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")"; 13211 } 13212 13213 @Override postDisplaySafeVolumeWarning(int flags)13214 public void postDisplaySafeVolumeWarning(int flags) { 13215 if (mController == null) 13216 return; 13217 flags = flags | AudioManager.FLAG_SHOW_UI; 13218 try { 13219 mController.displaySafeVolumeWarning(flags); 13220 } catch (RemoteException e) { 13221 Log.w(TAG, "Error calling displaySafeVolumeWarning", e); 13222 } 13223 } 13224 13225 @Override postDisplayCsdWarning( @udioManager.CsdWarning int csdWarning, int displayDurationMs)13226 public void postDisplayCsdWarning( 13227 @AudioManager.CsdWarning int csdWarning, int displayDurationMs) { 13228 if (mController == null) { 13229 Log.e(TAG, "Unable to display CSD warning, no controller"); 13230 return; 13231 } 13232 try { 13233 mController.displayCsdWarning(csdWarning, displayDurationMs); 13234 } catch (RemoteException e) { 13235 Log.w(TAG, "Error calling displayCsdWarning for warning " + csdWarning, e); 13236 } 13237 } 13238 postVolumeChanged(int streamType, int flags)13239 public void postVolumeChanged(int streamType, int flags) { 13240 if (mController == null) 13241 return; 13242 try { 13243 mController.volumeChanged(streamType, flags); 13244 } catch (RemoteException e) { 13245 Log.w(TAG, "Error calling volumeChanged", e); 13246 } 13247 } 13248 postMasterMuteChanged(int flags)13249 public void postMasterMuteChanged(int flags) { 13250 if (mController == null) 13251 return; 13252 try { 13253 mController.masterMuteChanged(flags); 13254 } catch (RemoteException e) { 13255 Log.w(TAG, "Error calling masterMuteChanged", e); 13256 } 13257 } 13258 setLayoutDirection(int layoutDirection)13259 public void setLayoutDirection(int layoutDirection) { 13260 if (mController == null) 13261 return; 13262 try { 13263 mController.setLayoutDirection(layoutDirection); 13264 } catch (RemoteException e) { 13265 Log.w(TAG, "Error calling setLayoutDirection", e); 13266 } 13267 } 13268 postDismiss()13269 public void postDismiss() { 13270 if (mController == null) 13271 return; 13272 try { 13273 mController.dismiss(); 13274 } catch (RemoteException e) { 13275 Log.w(TAG, "Error calling dismiss", e); 13276 } 13277 } 13278 setA11yMode(int a11yMode)13279 public void setA11yMode(int a11yMode) { 13280 if (mController == null) 13281 return; 13282 try { 13283 mController.setA11yMode(a11yMode); 13284 } catch (RemoteException e) { 13285 Log.w(TAG, "Error calling setA11Mode", e); 13286 } 13287 } 13288 } 13289 13290 /** 13291 * Interface for system components to get some extra functionality through 13292 * LocalServices. 13293 */ 13294 final class AudioServiceInternal extends AudioManagerInternal { 13295 @Override setRingerModeDelegate(RingerModeDelegate delegate)13296 public void setRingerModeDelegate(RingerModeDelegate delegate) { 13297 mRingerModeDelegate = delegate; 13298 if (mRingerModeDelegate != null) { 13299 synchronized (mSettingsLock) { 13300 updateRingerAndZenModeAffectedStreams(); 13301 } 13302 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate"); 13303 } 13304 } 13305 13306 @Override getRingerModeInternal()13307 public int getRingerModeInternal() { 13308 return AudioService.this.getRingerModeInternal(); 13309 } 13310 13311 @Override setRingerModeInternal(int ringerMode, String caller)13312 public void setRingerModeInternal(int ringerMode, String caller) { 13313 AudioService.this.setRingerModeInternal(ringerMode, caller); 13314 } 13315 13316 @Override silenceRingerModeInternal(String caller)13317 public void silenceRingerModeInternal(String caller) { 13318 AudioService.this.silenceRingerModeInternal(caller); 13319 } 13320 13321 @Override updateRingerModeAffectedStreamsInternal()13322 public void updateRingerModeAffectedStreamsInternal() { 13323 synchronized (mSettingsLock) { 13324 if (updateRingerAndZenModeAffectedStreams()) { 13325 setRingerModeInt(getRingerModeInternal(), false); 13326 } 13327 } 13328 } 13329 13330 @Override addAssistantServiceUid(int uid, int owningUid)13331 public void addAssistantServiceUid(int uid, int owningUid) { 13332 if (audioserverPermissions()) { 13333 mPermissionProvider.setIsolatedServiceUid(uid, owningUid); 13334 } 13335 sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 13336 uid, 0, null, 0); 13337 } 13338 13339 @Override removeAssistantServiceUid(int uid)13340 public void removeAssistantServiceUid(int uid) { 13341 if (audioserverPermissions()) { 13342 mPermissionProvider.clearIsolatedServiceUid(uid); 13343 } 13344 sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE, 13345 uid, 0, null, 0); 13346 } 13347 13348 @Override setActiveAssistantServicesUids(IntArray activeUids)13349 public void setActiveAssistantServicesUids(IntArray activeUids) { 13350 synchronized (mSettingsLock) { 13351 if (activeUids.size() == 0) { 13352 mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS; 13353 } else { 13354 boolean changed = (mActiveAssistantServiceUids == null) 13355 || (mActiveAssistantServiceUids.length != activeUids.size()); 13356 if (!changed) { 13357 for (int i = 0; i < mActiveAssistantServiceUids.length; i++) { 13358 if (activeUids.get(i) != mActiveAssistantServiceUids[i]) { 13359 changed = true; 13360 break; 13361 } 13362 } 13363 } 13364 if (changed) { 13365 mActiveAssistantServiceUids = activeUids.toArray(); 13366 } 13367 } 13368 } 13369 sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE, 13370 0, 0, null, 0); 13371 } 13372 13373 @Override setAccessibilityServiceUids(IntArray uids)13374 public void setAccessibilityServiceUids(IntArray uids) { 13375 // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service 13376 if (isPlatformAutomotive()) { 13377 return; 13378 } 13379 13380 synchronized (mAccessibilityServiceUidsLock) { 13381 if (uids.size() == 0) { 13382 mAccessibilityServiceUids = null; 13383 } else { 13384 boolean changed = (mAccessibilityServiceUids == null) 13385 || (mAccessibilityServiceUids.length != uids.size()); 13386 if (!changed) { 13387 for (int i = 0; i < mAccessibilityServiceUids.length; i++) { 13388 if (uids.get(i) != mAccessibilityServiceUids[i]) { 13389 changed = true; 13390 break; 13391 } 13392 } 13393 } 13394 if (changed) { 13395 mAccessibilityServiceUids = uids.toArray(); 13396 } 13397 } 13398 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE, 13399 0, 0, null, 0); 13400 } 13401 } 13402 13403 /** 13404 * {@inheritDoc} 13405 */ 13406 @Override setInputMethodServiceUid(int uid)13407 public void setInputMethodServiceUid(int uid) { 13408 synchronized (mInputMethodServiceUidLock) { 13409 if (mInputMethodServiceUid != uid) { 13410 mAudioSystem.setCurrentImeUid(uid); 13411 mInputMethodServiceUid = uid; 13412 } 13413 } 13414 } 13415 } 13416 onUpdateAccessibilityServiceUids()13417 private void onUpdateAccessibilityServiceUids() { 13418 int[] accessibilityServiceUids; 13419 synchronized (mAccessibilityServiceUidsLock) { 13420 accessibilityServiceUids = mAccessibilityServiceUids; 13421 } 13422 AudioSystem.setA11yServicesUids(accessibilityServiceUids); 13423 } 13424 13425 //========================================================================================== 13426 // Audio policy management 13427 //========================================================================================== registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection, AttributionSource attributionSource)13428 public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, 13429 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 13430 boolean isVolumeController, IMediaProjection projection, 13431 AttributionSource attributionSource) { 13432 Objects.requireNonNull(attributionSource); 13433 AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback); 13434 13435 if (!isPolicyRegisterAllowed(policyConfig, 13436 isFocusPolicy || isTestFocusPolicy || hasFocusListener, 13437 isVolumeController, 13438 projection)) { 13439 Slog.w(TAG, "Permission denied to register audio policy for pid " 13440 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid() 13441 + ", need system permission or a MediaProjection that can project audio"); 13442 return null; 13443 } 13444 13445 String regId = null; 13446 synchronized (mAudioPolicies) { 13447 if (mAudioPolicies.containsKey(pcb.asBinder())) { 13448 Slog.e(TAG, "Cannot re-register policy"); 13449 return null; 13450 } 13451 try { 13452 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener, 13453 isFocusPolicy, isTestFocusPolicy, isVolumeController, projection, 13454 attributionSource); 13455 pcb.asBinder().linkToDeath(app, 0/*flags*/); 13456 13457 // logging after registration so we have the registration id 13458 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("registerAudioPolicy for " 13459 + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/" 13460 + Binder.getCallingPid() + " with config:" + app.toCompactLogString())) 13461 .printLog(TAG)); 13462 13463 regId = app.getRegistrationId(); 13464 mAudioPolicies.put(pcb.asBinder(), app); 13465 } catch (RemoteException e) { 13466 // audio policy owner has already died! 13467 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb + 13468 " binder death", e); 13469 return null; 13470 } catch (IllegalStateException e) { 13471 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e); 13472 return null; 13473 } 13474 } 13475 return regId; 13476 } 13477 13478 /** 13479 * Called by an AudioPolicyProxy when the client dies. 13480 * Checks if an active playback for media use case is currently routed to one of the 13481 * remote submix devices owned by this dynamic policy and broadcasts a becoming noisy 13482 * intend in this case. 13483 * @param addresses list of remote submix device addresses to check. 13484 */ onPolicyClientDeath(List<String> addresses)13485 private void onPolicyClientDeath(List<String> addresses) { 13486 for (String address : addresses) { 13487 if (mPlaybackMonitor.hasActiveMediaPlaybackOnSubmixWithAddress(address)) { 13488 mDeviceBroker.postBroadcastBecomingNoisy(); 13489 return; 13490 } 13491 } 13492 } 13493 /** 13494 * Apps with MODIFY_AUDIO_ROUTING can register any policy. 13495 * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy 13496 * as those policy do not modify the audio routing. 13497 */ isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)13498 private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, 13499 boolean hasFocusAccess, 13500 boolean isVolumeController, 13501 IMediaProjection projection) { 13502 13503 boolean requireValidProjection = false; 13504 boolean requireCaptureAudioOrMediaOutputPerm = false; 13505 boolean requireModifyRouting = false; 13506 boolean requireCallAudioInterception = false; 13507 ArrayList<AudioMix> voiceCommunicationCaptureMixes = null; 13508 13509 13510 if (hasFocusAccess || isVolumeController) { 13511 requireModifyRouting |= true; 13512 } else if (policyConfig.getMixes().isEmpty()) { 13513 // An empty policy could be used to lock the focus or add mixes later 13514 requireModifyRouting |= true; 13515 } 13516 for (AudioMix mix : policyConfig.getMixes()) { 13517 // If mix is requesting privileged capture 13518 if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) { 13519 // then its format must be low quality enough 13520 String privilegedMediaCaptureError = 13521 mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat()); 13522 if (privilegedMediaCaptureError != null) { 13523 Log.e(TAG, privilegedMediaCaptureError); 13524 return false; 13525 } 13526 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission 13527 requireCaptureAudioOrMediaOutputPerm |= true; 13528 13529 } 13530 // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION 13531 if (mix.containsMatchAttributeRuleForUsage( 13532 AudioAttributes.USAGE_VOICE_COMMUNICATION) 13533 && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) { 13534 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission 13535 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced 13536 // in AudioPolicyMix 13537 if (voiceCommunicationCaptureMixes == null) { 13538 voiceCommunicationCaptureMixes = new ArrayList<AudioMix>(); 13539 } 13540 voiceCommunicationCaptureMixes.add(mix); 13541 } 13542 13543 // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough 13544 // otherwise MODIFY_AUDIO_ROUTING permission is required 13545 if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) { 13546 requireValidProjection |= true; 13547 } else if (mix.isForCallRedirection()) { 13548 requireCallAudioInterception |= true; 13549 } else if (mix.containsMatchAttributeRuleForUsage( 13550 AudioAttributes.USAGE_VOICE_COMMUNICATION)) { 13551 requireModifyRouting |= true; 13552 } 13553 } 13554 13555 if (requireCaptureAudioOrMediaOutputPerm 13556 && !callerHasPermission(CAPTURE_MEDIA_OUTPUT) 13557 && !callerHasPermission(CAPTURE_AUDIO_OUTPUT)) { 13558 Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or " 13559 + "CAPTURE_AUDIO_OUTPUT system permission"); 13560 return false; 13561 } 13562 13563 if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) { 13564 if (!callerHasPermission( 13565 Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) { 13566 Log.e(TAG, "Audio capture for voice communication requires " 13567 + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission"); 13568 return false; 13569 } 13570 13571 // If permission check succeeded, we set the flag in each of the mixing rules 13572 for (AudioMix mix : voiceCommunicationCaptureMixes) { 13573 mix.getRule().setVoiceCommunicationCaptureAllowed(true); 13574 } 13575 } 13576 13577 if (requireValidProjection && !canProjectAudio(projection)) { 13578 return false; 13579 } 13580 13581 if (requireModifyRouting 13582 && !callerHasPermission(MODIFY_AUDIO_ROUTING)) { 13583 Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING"); 13584 return false; 13585 } 13586 13587 if (requireCallAudioInterception && !callerHasPermission(CALL_AUDIO_INTERCEPTION)) { 13588 Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION"); 13589 return false; 13590 } 13591 13592 return true; 13593 } 13594 callerHasPermission(String permission)13595 private boolean callerHasPermission(String permission) { 13596 return mContext.checkCallingOrSelfPermission(permission) 13597 == PackageManager.PERMISSION_GRANTED; 13598 } 13599 13600 /** @return true if projection is a valid MediaProjection that can project audio. */ canProjectAudio(IMediaProjection projection)13601 private boolean canProjectAudio(IMediaProjection projection) { 13602 if (projection == null) { 13603 Log.e(TAG, "MediaProjection is null"); 13604 return false; 13605 } 13606 13607 IMediaProjectionManager projectionService = getProjectionService(); 13608 if (projectionService == null) { 13609 Log.e(TAG, "Can't get service IMediaProjectionManager"); 13610 return false; 13611 } 13612 13613 final long token = Binder.clearCallingIdentity(); 13614 try { 13615 if (!projectionService.isCurrentProjection(projection)) { 13616 Log.w(TAG, "App passed invalid MediaProjection token"); 13617 return false; 13618 } 13619 } catch (RemoteException e) { 13620 Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager" 13621 + projectionService.asBinder(), e); 13622 return false; 13623 } finally { 13624 Binder.restoreCallingIdentity(token); 13625 } 13626 13627 try { 13628 if (!projection.canProjectAudio()) { 13629 Log.w(TAG, "App passed MediaProjection that can not project audio"); 13630 return false; 13631 } 13632 } catch (RemoteException e) { 13633 Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection" 13634 + projection.asBinder(), e); 13635 return false; 13636 } 13637 13638 return true; 13639 } 13640 getProjectionService()13641 private IMediaProjectionManager getProjectionService() { 13642 if (mProjectionService == null) { 13643 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 13644 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 13645 } 13646 return mProjectionService; 13647 } 13648 13649 /** 13650 * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)} 13651 * Declared oneway 13652 * @param pcb nullable because on service interface 13653 */ unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)13654 public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) { 13655 if (pcb == null) { 13656 return; 13657 } 13658 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync"); 13659 } 13660 13661 /** 13662 * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)} 13663 * @param pcb nullable because on service interface 13664 */ unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)13665 public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) { 13666 if (pcb == null) { 13667 return; 13668 } 13669 unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy"); 13670 } 13671 13672 unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)13673 private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) { 13674 mDynPolicyLogger.enqueue((new EventLogger.StringEvent(operationName + " for " 13675 + pcb.asBinder()).printLog(TAG))); 13676 synchronized (mAudioPolicies) { 13677 AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder()); 13678 if (app == null) { 13679 Slog.w(TAG, "Trying to unregister unknown audio policy for pid " 13680 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 13681 return; 13682 } else { 13683 pcb.asBinder().unlinkToDeath(app, 0/*flags*/); 13684 } 13685 app.release(); 13686 } 13687 // TODO implement clearing mix attribute matching info in native audio policy 13688 } 13689 13690 /** 13691 * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered. 13692 * @param errorMsg log warning if permission check failed. 13693 * @return null if the operation on the audio mixes should be cancelled. 13694 */ 13695 @GuardedBy("mAudioPolicies") checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)13696 private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) { 13697 // permission check 13698 final boolean hasPermissionForPolicy = 13699 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 13700 MODIFY_AUDIO_ROUTING)); 13701 if (!hasPermissionForPolicy) { 13702 Slog.w(TAG, errorMsg + " for pid " + 13703 + Binder.getCallingPid() + " / uid " 13704 + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); 13705 return null; 13706 } 13707 // policy registered? 13708 final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder()); 13709 if (app == null) { 13710 Slog.w(TAG, errorMsg + " for pid " + 13711 + Binder.getCallingPid() + " / uid " 13712 + Binder.getCallingUid() + ", unregistered policy"); 13713 return null; 13714 } 13715 return app; 13716 } 13717 13718 /** 13719 * Retrieves all audioMixes registered with the AudioPolicyManager 13720 * @return list of registered audio mixes 13721 */ getRegisteredPolicyMixes()13722 public List<AudioMix> getRegisteredPolicyMixes() { 13723 if (!android.media.audiopolicy.Flags.audioMixTestApi()) { 13724 return Collections.emptyList(); 13725 } 13726 13727 synchronized (mAudioPolicies) { 13728 return mAudioSystem.getRegisteredPolicyMixes(); 13729 } 13730 } 13731 addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)13732 public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 13733 if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder() 13734 + " with config:" + policyConfig); } 13735 synchronized (mAudioPolicies) { 13736 final AudioPolicyProxy app = 13737 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 13738 if (app == null){ 13739 return AudioManager.ERROR; 13740 } 13741 return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 13742 ? AudioManager.SUCCESS : AudioManager.ERROR; 13743 } 13744 } 13745 removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)13746 public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) { 13747 if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder() 13748 + " with config:" + policyConfig); } 13749 synchronized (mAudioPolicies) { 13750 final AudioPolicyProxy app = 13751 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 13752 if (app == null) { 13753 return AudioManager.ERROR; 13754 } 13755 if (android.media.audiopolicy.Flags.audioMixOwnership()) { 13756 for (AudioMix mix : policyConfig.getMixes()) { 13757 if (!app.getMixes().contains(mix)) { 13758 Slog.e(TAG, 13759 "removeMixForPolicy attempted to unregister AudioMix(es) not " 13760 + "belonging to the AudioPolicy"); 13761 return AudioManager.ERROR; 13762 } 13763 } 13764 } 13765 return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS 13766 ? AudioManager.SUCCESS : AudioManager.ERROR; 13767 } 13768 } 13769 13770 /** 13771 * Update {@link AudioMixingRule}-s for already registered {@link AudioMix}-es. 13772 * 13773 * @param mixesToUpdate - array of already registered {@link AudioMix}-es to update. 13774 * @param updatedMixingRules - array of {@link AudioMixingRule}-s corresponding to 13775 * {@code mixesToUpdate} mixes. The array must be same size as 13776 * {@code mixesToUpdate} and i-th {@link AudioMixingRule} must 13777 * correspond to i-th {@link AudioMix} from mixesToUpdate array. 13778 * @param pcb - {@link IAudioPolicyCallback} corresponding to the registered 13779 * {@link AudioPolicy} all {@link AudioMix}-es for {@code mixesToUpdate} 13780 * are part of. 13781 * @return {@link AudioManager#SUCCESS} iff the mixing rules were updated successfully, 13782 * {@link AudioManager#ERROR} otherwise. 13783 */ 13784 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) updateMixingRulesForPolicy( @onNull AudioMix[] mixesToUpdate, @NonNull AudioMixingRule[] updatedMixingRules, @NonNull IAudioPolicyCallback pcb)13785 public int updateMixingRulesForPolicy( 13786 @NonNull AudioMix[] mixesToUpdate, 13787 @NonNull AudioMixingRule[] updatedMixingRules, 13788 @NonNull IAudioPolicyCallback pcb) { 13789 super.updateMixingRulesForPolicy_enforcePermission(); 13790 Objects.requireNonNull(mixesToUpdate); 13791 Objects.requireNonNull(updatedMixingRules); 13792 Objects.requireNonNull(pcb); 13793 if (mixesToUpdate.length != updatedMixingRules.length) { 13794 Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules " 13795 + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length 13796 + ", updatedMixingRules.length = " + updatedMixingRules.length + ")."); 13797 return AudioManager.ERROR; 13798 } 13799 if (DEBUG_AP) { 13800 Log.d(TAG, "updateMixingRules for " + pcb.asBinder() + "with mix rules: "); 13801 } 13802 synchronized (mAudioPolicies) { 13803 final AudioPolicyProxy app = 13804 checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); 13805 if (app == null) { 13806 return AudioManager.ERROR; 13807 } 13808 return app.updateMixingRules(mixesToUpdate, updatedMixingRules) == AudioSystem.SUCCESS 13809 ? AudioManager.SUCCESS : AudioManager.ERROR; 13810 } 13811 } 13812 13813 /** see AudioPolicy.setUidDeviceAffinity() */ setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)13814 public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, 13815 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 13816 if (DEBUG_AP) { 13817 Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 13818 } 13819 synchronized (mAudioPolicies) { 13820 final AudioPolicyProxy app = 13821 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 13822 if (app == null) { 13823 return AudioManager.ERROR; 13824 } 13825 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 13826 return AudioManager.ERROR; 13827 } 13828 return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses); 13829 } 13830 } 13831 13832 /** see AudioPolicy.setUserIdDeviceAffinity() */ setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)13833 public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, 13834 @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { 13835 if (DEBUG_AP) { 13836 Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId); 13837 } 13838 13839 synchronized (mAudioPolicies) { 13840 final AudioPolicyProxy app = 13841 checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); 13842 if (app == null) { 13843 return AudioManager.ERROR; 13844 } 13845 if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { 13846 return AudioManager.ERROR; 13847 } 13848 return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses); 13849 } 13850 } 13851 13852 /** see AudioPolicy.removeUidDeviceAffinity() */ removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)13853 public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) { 13854 if (DEBUG_AP) { 13855 Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid); 13856 } 13857 synchronized (mAudioPolicies) { 13858 final AudioPolicyProxy app = 13859 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 13860 if (app == null) { 13861 return AudioManager.ERROR; 13862 } 13863 return app.removeUidDeviceAffinities(uid); 13864 } 13865 } 13866 13867 /** see AudioPolicy.removeUserIdDeviceAffinity() */ removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)13868 public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) { 13869 if (DEBUG_AP) { 13870 Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder() 13871 + " userId:" + userId); 13872 } 13873 synchronized (mAudioPolicies) { 13874 final AudioPolicyProxy app = 13875 checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); 13876 if (app == null) { 13877 return AudioManager.ERROR; 13878 } 13879 return app.removeUserIdDeviceAffinities(userId); 13880 } 13881 } 13882 setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)13883 public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { 13884 if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior 13885 + " policy " + pcb.asBinder()); 13886 synchronized (mAudioPolicies) { 13887 final AudioPolicyProxy app = 13888 checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties"); 13889 if (app == null){ 13890 return AudioManager.ERROR; 13891 } 13892 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 13893 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy"); 13894 return AudioManager.ERROR; 13895 } 13896 if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 13897 // is there already one policy managing ducking? 13898 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 13899 if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 13900 Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled"); 13901 return AudioManager.ERROR; 13902 } 13903 } 13904 } 13905 app.mFocusDuckBehavior = duckingBehavior; 13906 mMediaFocusControl.setDuckingInExtPolicyAvailable( 13907 duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY); 13908 } 13909 return AudioManager.SUCCESS; 13910 } 13911 13912 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 13913 /* @see AudioPolicy#getFocusStack() */ getFocusStack()13914 public List<AudioFocusInfo> getFocusStack() { 13915 super.getFocusStack_enforcePermission(); 13916 13917 return mMediaFocusControl.getFocusStack(); 13918 } 13919 13920 /** 13921 * @param focusLoser non-null entry that may be in the stack 13922 * @see AudioPolicy#sendFocusLossAndUpdate(AudioFocusInfo) 13923 */ 13924 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) sendFocusLossAndUpdate(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)13925 public void sendFocusLossAndUpdate(@NonNull AudioFocusInfo focusLoser, 13926 @NonNull IAudioPolicyCallback apcb) { 13927 super.sendFocusLossAndUpdate_enforcePermission(); 13928 Objects.requireNonNull(apcb); 13929 if (!mAudioPolicies.containsKey(apcb.asBinder())) { 13930 throw new IllegalStateException("Only registered AudioPolicy can change focus"); 13931 } 13932 if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) { 13933 throw new IllegalStateException("AudioPolicy must have focus listener to change focus"); 13934 } 13935 13936 mMediaFocusControl.sendFocusLossAndUpdate(Objects.requireNonNull(focusLoser)); 13937 } 13938 13939 /* @see AudioPolicy#sendFocusLoss(AudioFocusInfo) */ 13940 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)13941 public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser, 13942 @NonNull IAudioPolicyCallback apcb) { 13943 super.sendFocusLoss_enforcePermission(); 13944 Objects.requireNonNull(focusLoser); 13945 Objects.requireNonNull(apcb); 13946 if (!mAudioPolicies.containsKey(apcb.asBinder())) { 13947 throw new IllegalStateException("Only registered AudioPolicy can change focus"); 13948 } 13949 if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) { 13950 throw new IllegalStateException("AudioPolicy must have focus listener to change focus"); 13951 } 13952 return mMediaFocusControl.sendFocusLoss(focusLoser); 13953 } 13954 13955 /** 13956 * see {@link AudioPolicy#setFadeManagerConfigurationForFocusLoss(FadeManagerConfiguration)} 13957 */ 13958 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setFadeManagerConfigurationForFocusLoss( @onNull FadeManagerConfiguration fmcForFocusLoss)13959 public int setFadeManagerConfigurationForFocusLoss( 13960 @NonNull FadeManagerConfiguration fmcForFocusLoss) { 13961 super.setFadeManagerConfigurationForFocusLoss_enforcePermission(); 13962 ensureFadeManagerConfigIsEnabled(); 13963 Objects.requireNonNull(fmcForFocusLoss, 13964 "Fade manager config for focus loss cannot be null"); 13965 validateFadeManagerConfiguration(fmcForFocusLoss); 13966 13967 return mPlaybackMonitor.setFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS, 13968 fmcForFocusLoss); 13969 } 13970 13971 /** 13972 * see {@link AudioPolicy#clearFadeManagerConfigurationForFocusLoss()} 13973 */ 13974 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) clearFadeManagerConfigurationForFocusLoss()13975 public int clearFadeManagerConfigurationForFocusLoss() { 13976 super.clearFadeManagerConfigurationForFocusLoss_enforcePermission(); 13977 ensureFadeManagerConfigIsEnabled(); 13978 13979 return mPlaybackMonitor.clearFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS); 13980 } 13981 13982 /** 13983 * see {@link AudioPolicy#getFadeManagerConfigurationForFocusLoss()} 13984 */ 13985 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) getFadeManagerConfigurationForFocusLoss()13986 public FadeManagerConfiguration getFadeManagerConfigurationForFocusLoss() { 13987 super.getFadeManagerConfigurationForFocusLoss_enforcePermission(); 13988 ensureFadeManagerConfigIsEnabled(); 13989 13990 return mPlaybackMonitor.getFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS); 13991 } 13992 13993 /** 13994 * @see AudioManager#getHalVersion 13995 */ getHalVersion()13996 public @Nullable AudioHalVersionInfo getHalVersion() { 13997 for (AudioHalVersionInfo version : AudioHalVersionInfo.VERSIONS) { 13998 try { 13999 String versionStr = version.getMajorVersion() + "." + version.getMinorVersion(); 14000 final String aidlStr = "android.hardware.audio.core.IModule/default"; 14001 final String hidlStr = String.format("android.hardware.audio@%s::IDevicesFactory", 14002 versionStr); 14003 if (null != ServiceManager.checkService(aidlStr)) { 14004 return version; 14005 } else { 14006 HwBinder.getService(hidlStr, "default"); 14007 return version; 14008 } 14009 } catch (NoSuchElementException e) { 14010 // Ignore, the specified HAL interface is not found. 14011 } catch (RemoteException re) { 14012 Log.e(TAG, "Remote exception when getting hardware audio service:", re); 14013 } 14014 } 14015 return null; 14016 } 14017 14018 /** see AudioManager.hasRegisteredDynamicPolicy */ hasRegisteredDynamicPolicy()14019 public boolean hasRegisteredDynamicPolicy() { 14020 synchronized (mAudioPolicies) { 14021 return !mAudioPolicies.isEmpty(); 14022 } 14023 } 14024 14025 /** 14026 * @see AudioManager#setPreferredMixerAttributes( 14027 * AudioAttributes, AudioDeviceInfo, AudioMixerAttributes) 14028 */ setPreferredMixerAttributes(AudioAttributes attributes, int portId, AudioMixerAttributes mixerAttributes)14029 public int setPreferredMixerAttributes(AudioAttributes attributes, 14030 int portId, AudioMixerAttributes mixerAttributes) { 14031 Objects.requireNonNull(attributes); 14032 Objects.requireNonNull(mixerAttributes); 14033 if (!checkAudioSettingsPermission("setPreferredMixerAttributes()")) { 14034 return AudioSystem.PERMISSION_DENIED; 14035 } 14036 final int uid = Binder.getCallingUid(); 14037 final int pid = Binder.getCallingPid(); 14038 int status = AudioSystem.SUCCESS; 14039 final long token = Binder.clearCallingIdentity(); 14040 try { 14041 final String logString = TextUtils.formatSimple( 14042 "setPreferredMixerAttributes u/pid:%d/%d attr:%s mixerAttributes:%s portId:%d", 14043 uid, pid, attributes.toString(), mixerAttributes.toString(), portId); 14044 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 14045 14046 status = mAudioSystem.setPreferredMixerAttributes( 14047 attributes, portId, uid, mixerAttributes); 14048 if (status == AudioSystem.SUCCESS) { 14049 dispatchPreferredMixerAttributesChanged(attributes, portId, mixerAttributes); 14050 } else { 14051 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString)); 14052 } 14053 } finally { 14054 Binder.restoreCallingIdentity(token); 14055 } 14056 return status; 14057 } 14058 14059 /** 14060 * @see AudioManager#clearPreferredMixerAttributes(AudioAttributes, AudioDeviceInfo) 14061 */ clearPreferredMixerAttributes(AudioAttributes attributes, int portId)14062 public int clearPreferredMixerAttributes(AudioAttributes attributes, int portId) { 14063 Objects.requireNonNull(attributes); 14064 if (!checkAudioSettingsPermission("clearPreferredMixerAttributes()")) { 14065 return AudioSystem.PERMISSION_DENIED; 14066 } 14067 final int uid = Binder.getCallingUid(); 14068 final int pid = Binder.getCallingPid(); 14069 int status = AudioSystem.SUCCESS; 14070 final long token = Binder.clearCallingIdentity(); 14071 try { 14072 final String logString = TextUtils.formatSimple( 14073 "clearPreferredMixerAttributes u/pid:%d/%d attr:%s", 14074 uid, pid, attributes.toString()); 14075 sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG)); 14076 14077 status = mAudioSystem.clearPreferredMixerAttributes(attributes, portId, uid); 14078 if (status == AudioSystem.SUCCESS) { 14079 dispatchPreferredMixerAttributesChanged(attributes, portId, null /*mixerAttr*/); 14080 } else { 14081 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString)); 14082 } 14083 } finally { 14084 Binder.restoreCallingIdentity(token); 14085 } 14086 return status; 14087 } 14088 dispatchPreferredMixerAttributesChanged( AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr)14089 void dispatchPreferredMixerAttributesChanged( 14090 AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr) { 14091 Bundle bundle = new Bundle(); 14092 bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, attr); 14093 bundle.putParcelable(KEY_AUDIO_MIXER_ATTRIBUTES, mixerAttr); 14094 sendBundleMsg(mAudioHandler, MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES, SENDMSG_QUEUE, 14095 deviceId, 0, null, bundle, 0); 14096 } 14097 14098 final RemoteCallbackList<IPreferredMixerAttributesDispatcher> mPrefMixerAttrDispatcher = 14099 new RemoteCallbackList<IPreferredMixerAttributesDispatcher>(); 14100 private static final String KEY_AUDIO_ATTRIBUTES = "audio_attributes"; 14101 private static final String KEY_AUDIO_MIXER_ATTRIBUTES = "audio_mixer_attributes"; 14102 14103 /** @see AudioManager#addOnPreferredMixerAttributesChangedListener( 14104 * Executor, AudioManager.OnPreferredMixerAttributesChangedListener) 14105 */ registerPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)14106 public void registerPreferredMixerAttributesDispatcher( 14107 @Nullable IPreferredMixerAttributesDispatcher dispatcher) { 14108 if (dispatcher == null) { 14109 return; 14110 } 14111 mPrefMixerAttrDispatcher.register(dispatcher); 14112 } 14113 14114 /** @see AudioManager#removeOnPreferredMixerAttributesChangedListener( 14115 * AudioManager.OnPreferredMixerAttributesChangedListener) 14116 */ unregisterPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)14117 public void unregisterPreferredMixerAttributesDispatcher( 14118 @Nullable IPreferredMixerAttributesDispatcher dispatcher) { 14119 if (dispatcher == null) { 14120 return; 14121 } 14122 mPrefMixerAttrDispatcher.unregister(dispatcher); 14123 } 14124 onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId)14125 protected void onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId) { 14126 final int nbDispathers = mPrefMixerAttrDispatcher.beginBroadcast(); 14127 final AudioAttributes attr = data.getParcelable( 14128 KEY_AUDIO_ATTRIBUTES, AudioAttributes.class); 14129 final AudioMixerAttributes mixerAttr = data.getParcelable( 14130 KEY_AUDIO_MIXER_ATTRIBUTES, AudioMixerAttributes.class); 14131 for (int i = 0; i < nbDispathers; i++) { 14132 try { 14133 mPrefMixerAttrDispatcher.getBroadcastItem(i) 14134 .dispatchPrefMixerAttributesChanged(attr, deviceId, mixerAttr); 14135 } catch (RemoteException e) { 14136 Log.e(TAG, "Can't call dispatchPrefMixerAttributesChanged() " 14137 + "IPreferredMixerAttributesDispatcher " 14138 + mPrefMixerAttrDispatcher.getBroadcastItem(i).asBinder(), e); 14139 } 14140 } 14141 mPrefMixerAttrDispatcher.finishBroadcast(); 14142 } 14143 14144 14145 /** @see AudioManager#supportsBluetoothVariableLatency() */ 14146 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) supportsBluetoothVariableLatency()14147 public boolean supportsBluetoothVariableLatency() { 14148 super.supportsBluetoothVariableLatency_enforcePermission(); 14149 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 14150 return AudioSystem.supportsBluetoothVariableLatency(); 14151 } 14152 } 14153 14154 /** @see AudioManager#setBluetoothVariableLatencyEnabled(boolean) */ 14155 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) setBluetoothVariableLatencyEnabled(boolean enabled)14156 public void setBluetoothVariableLatencyEnabled(boolean enabled) { 14157 super.setBluetoothVariableLatencyEnabled_enforcePermission(); 14158 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 14159 AudioSystem.setBluetoothVariableLatencyEnabled(enabled); 14160 } 14161 } 14162 14163 /** @see AudioManager#isBluetoothVariableLatencyEnabled(boolean) */ 14164 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) isBluetoothVariableLatencyEnabled()14165 public boolean isBluetoothVariableLatencyEnabled() { 14166 super.isBluetoothVariableLatencyEnabled_enforcePermission(); 14167 try (SafeCloseable ignored = ClearCallingIdentityContext.create()) { 14168 return AudioSystem.isBluetoothVariableLatencyEnabled(); 14169 } 14170 } 14171 14172 private final Object mExtVolumeControllerLock = new Object(); 14173 private IAudioPolicyCallback mExtVolumeController; setExtVolumeController(IAudioPolicyCallback apc)14174 private void setExtVolumeController(IAudioPolicyCallback apc) { 14175 if (!mContext.getResources().getBoolean( 14176 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) { 14177 Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" + 14178 " handled in PhoneWindowManager"); 14179 return; 14180 } 14181 synchronized (mExtVolumeControllerLock) { 14182 if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) { 14183 Log.e(TAG, "Cannot set external volume controller: existing controller"); 14184 } 14185 mExtVolumeController = apc; 14186 } 14187 } 14188 dumpAudioPolicies(PrintWriter pw)14189 private void dumpAudioPolicies(PrintWriter pw) { 14190 pw.println("\nAudio policies:"); 14191 synchronized (mAudioPolicies) { 14192 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 14193 pw.println(policy.toLogFriendlyString()); 14194 } 14195 } 14196 } 14197 ensureFadeManagerConfigIsEnabled()14198 private void ensureFadeManagerConfigIsEnabled() { 14199 Preconditions.checkState(enableFadeManagerConfiguration(), 14200 "Fade manager configuration not supported"); 14201 } 14202 validateFadeManagerConfiguration(FadeManagerConfiguration fmc)14203 private void validateFadeManagerConfiguration(FadeManagerConfiguration fmc) { 14204 // validate permission of audio attributes 14205 List<AudioAttributes> attrs = fmc.getAudioAttributesWithVolumeShaperConfigs(); 14206 for (int index = 0; index < attrs.size(); index++) { 14207 validateAudioAttributesUsage(attrs.get(index)); 14208 } 14209 } 14210 14211 //====================== 14212 // Audio policy callbacks from AudioSystem for dynamic policies 14213 //====================== 14214 private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback = 14215 new AudioSystem.DynamicPolicyCallback() { 14216 public void onDynamicPolicyMixStateUpdate(String regId, int state) { 14217 if (!TextUtils.isEmpty(regId)) { 14218 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE, 14219 state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/); 14220 } 14221 } 14222 }; 14223 onDynPolicyMixStateUpdate(String regId, int state)14224 private void onDynPolicyMixStateUpdate(String regId, int state) { 14225 if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")"); 14226 synchronized (mAudioPolicies) { 14227 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 14228 for (AudioMix mix : policy.getMixes()) { 14229 if (mix.getRegistration().equals(regId)) { 14230 try { 14231 policy.mPolicyCallback.notifyMixStateUpdate(regId, state); 14232 } catch (RemoteException e) { 14233 Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback " 14234 + policy.mPolicyCallback.asBinder(), e); 14235 } 14236 return; 14237 } 14238 } 14239 } 14240 } 14241 } 14242 14243 //====================== 14244 // Audio policy callbacks from AudioSystem for recording configuration updates 14245 //====================== 14246 private final RecordingActivityMonitor mRecordMonitor; 14247 registerRecordingCallback(IRecordingConfigDispatcher rcdb)14248 public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) { 14249 final boolean isPrivileged = 14250 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 14251 MODIFY_AUDIO_ROUTING)); 14252 mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged); 14253 } 14254 unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)14255 public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) { 14256 mRecordMonitor.unregisterRecordingCallback(rcdb); 14257 } 14258 getActiveRecordingConfigurations()14259 public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() { 14260 final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID 14261 || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 14262 MODIFY_AUDIO_ROUTING)); 14263 return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged); 14264 } 14265 14266 //====================== 14267 // Audio recording state notification from clients 14268 //====================== 14269 /** 14270 * Track a recorder provided by the client 14271 */ trackRecorder(IBinder recorder)14272 public int trackRecorder(IBinder recorder) { 14273 return mRecordMonitor.trackRecorder(recorder); 14274 } 14275 14276 /** 14277 * Receive an event from the client about a tracked recorder 14278 */ recorderEvent(int riid, int event)14279 public void recorderEvent(int riid, int event) { 14280 mRecordMonitor.recorderEvent(riid, event); 14281 } 14282 14283 /** 14284 * Stop tracking the recorder 14285 */ releaseRecorder(int riid)14286 public void releaseRecorder(int riid) { 14287 mRecordMonitor.releaseRecorder(riid); 14288 } 14289 14290 //====================== 14291 // Audio playback notification 14292 //====================== 14293 private final PlaybackActivityMonitor mPlaybackMonitor; 14294 registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)14295 public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 14296 final boolean isPrivileged = 14297 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 14298 MODIFY_AUDIO_ROUTING)); 14299 mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged); 14300 } 14301 unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)14302 public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) { 14303 mPlaybackMonitor.unregisterPlaybackCallback(pcdb); 14304 } 14305 getActivePlaybackConfigurations()14306 public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() { 14307 final boolean isPrivileged = 14308 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( 14309 MODIFY_AUDIO_ROUTING)); 14310 return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged); 14311 } 14312 trackPlayer(PlayerBase.PlayerIdCard pic)14313 public int trackPlayer(PlayerBase.PlayerIdCard pic) { 14314 if (pic != null && pic.mAttributes != null) { 14315 validateAudioAttributesUsage(pic.mAttributes); 14316 } 14317 return mPlaybackMonitor.trackPlayer(pic); 14318 } 14319 playerAttributes(int piid, AudioAttributes attr)14320 public void playerAttributes(int piid, AudioAttributes attr) { 14321 if (attr != null) { 14322 validateAudioAttributesUsage(attr); 14323 } 14324 mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid()); 14325 } 14326 14327 /** 14328 * Update player session ID 14329 * @param piid Player id to update 14330 * @param sessionId The new audio session ID 14331 */ playerSessionId(int piid, int sessionId)14332 public void playerSessionId(int piid, int sessionId) { 14333 if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) { 14334 throw new IllegalArgumentException("invalid session Id " + sessionId); 14335 } 14336 mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid()); 14337 } 14338 14339 /** 14340 * Update player event 14341 * @param piid Player id to update 14342 * @param event The new player event 14343 * @param eventValues The values associated with this event 14344 */ playerEvent(int piid, int event, int[] eventValues)14345 public void playerEvent(int piid, int event, int[] eventValues) { 14346 mPlaybackMonitor.playerEvent(piid, event, eventValues, Binder.getCallingUid()); 14347 } 14348 14349 /** 14350 * Update event for port id 14351 * @param portId Port id to update 14352 * @param event The new event for the given port 14353 * @param extras Bundle of extra values to describe the event 14354 */ portEvent(int portId, int event, @Nullable PersistableBundle extras)14355 public void portEvent(int portId, int event, @Nullable PersistableBundle extras) { 14356 mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid()); 14357 } 14358 playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)14359 public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) { 14360 mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid()); 14361 } 14362 releasePlayer(int piid)14363 public void releasePlayer(int piid) { 14364 mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid()); 14365 } 14366 14367 /** 14368 * Specifies whether the audio played by this app may or may not be captured by other apps or 14369 * the system. 14370 * 14371 * @param capturePolicy one of 14372 * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, 14373 * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, 14374 * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. 14375 * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed. 14376 * @throws IllegalArgumentException if the argument is not a valid value. 14377 */ setAllowedCapturePolicy(int capturePolicy)14378 public int setAllowedCapturePolicy(int capturePolicy) { 14379 int callingUid = Binder.getCallingUid(); 14380 int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); 14381 final long identity = Binder.clearCallingIdentity(); 14382 try { 14383 synchronized (mPlaybackMonitor) { 14384 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags); 14385 if (result == AudioSystem.AUDIO_STATUS_OK) { 14386 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy); 14387 } 14388 return result; 14389 } 14390 } finally { 14391 Binder.restoreCallingIdentity(identity); 14392 } 14393 } 14394 14395 /** 14396 * Return the capture policy. 14397 * @return the cached capture policy for the calling uid. 14398 */ getAllowedCapturePolicy()14399 public int getAllowedCapturePolicy() { 14400 int callingUid = Binder.getCallingUid(); 14401 final long identity = Binder.clearCallingIdentity(); 14402 try { 14403 return mPlaybackMonitor.getAllowedCapturePolicy(callingUid); 14404 } finally { 14405 Binder.restoreCallingIdentity(identity); 14406 } 14407 } 14408 14409 /* package */ isPlaybackActiveForUid(int uid)14410 boolean isPlaybackActiveForUid(int uid) { 14411 return mPlaybackMonitor.isPlaybackActiveForUid(uid); 14412 } 14413 14414 /* package */ isRecordingActiveForUid(int uid)14415 boolean isRecordingActiveForUid(int uid) { 14416 return mRecordMonitor.isRecordingActiveForUid(uid); 14417 } 14418 14419 //====================== 14420 // Audio device management 14421 //====================== 14422 private final AudioDeviceBroker mDeviceBroker; 14423 14424 //====================== 14425 // Audio policy proxy 14426 //====================== 14427 private static final class AudioDeviceArray { 14428 final @NonNull int[] mDeviceTypes; 14429 final @NonNull String[] mDeviceAddresses; AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)14430 AudioDeviceArray(@NonNull int[] types, @NonNull String[] addresses) { 14431 mDeviceTypes = types; 14432 mDeviceAddresses = addresses; 14433 } 14434 } 14435 14436 /** 14437 * This internal class inherits from AudioPolicyConfig, each instance contains all the 14438 * mixes of an AudioPolicy and their configurations. 14439 */ 14440 public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient { 14441 private static final String TAG = "AudioPolicyProxy"; 14442 final IAudioPolicyCallback mPolicyCallback; 14443 final AttributionSource mAttributionSource; 14444 final boolean mHasFocusListener; 14445 final boolean mIsVolumeController; 14446 final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities = 14447 new HashMap<Integer, AudioDeviceArray>(); 14448 14449 final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities = 14450 new HashMap<>(); 14451 14452 final IMediaProjection mProjection; 14453 private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub { onStop()14454 public void onStop() { 14455 unregisterAudioPolicyAsync(mPolicyCallback); 14456 } 14457 14458 @Override onCapturedContentResize(int width, int height)14459 public void onCapturedContentResize(int width, int height) { 14460 // Ignore resize of the captured content. 14461 } 14462 14463 @Override onCapturedContentVisibilityChanged(boolean isVisible)14464 public void onCapturedContentVisibilityChanged(boolean isVisible) { 14465 // Ignore visibility changes of the captured content. 14466 } 14467 }; 14468 UnregisterOnStopCallback mProjectionCallback; 14469 14470 /** 14471 * Audio focus ducking behavior for an audio policy. 14472 * This variable reflects the value that was successfully set in 14473 * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This 14474 * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy 14475 * is handling ducking for audio focus. 14476 */ 14477 int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT; 14478 boolean mIsFocusPolicy = false; 14479 boolean mIsTestFocusPolicy = false; 14480 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection, AttributionSource attributionSource)14481 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, 14482 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, 14483 boolean isVolumeController, IMediaProjection projection, 14484 AttributionSource attributionSource) { 14485 super(config); 14486 setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++)); 14487 mPolicyCallback = token; 14488 mAttributionSource = attributionSource; 14489 mHasFocusListener = hasFocusListener; 14490 mIsVolumeController = isVolumeController; 14491 mProjection = projection; 14492 if (mHasFocusListener) { 14493 mMediaFocusControl.addFocusFollower(mPolicyCallback); 14494 // can only ever be true if there is a focus listener 14495 if (isFocusPolicy) { 14496 mIsFocusPolicy = true; 14497 mIsTestFocusPolicy = isTestFocusPolicy; 14498 mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 14499 } 14500 } 14501 if (mIsVolumeController) { 14502 setExtVolumeController(mPolicyCallback); 14503 } 14504 if (mProjection != null) { 14505 mProjectionCallback = new UnregisterOnStopCallback(); 14506 try { 14507 mProjection.registerCallback(mProjectionCallback); 14508 } catch (RemoteException e) { 14509 release(); 14510 throw new IllegalStateException("MediaProjection callback registration failed, " 14511 + "could not link to " + projection + " binder death", e); 14512 } 14513 } 14514 14515 int status = connectMixes(); 14516 if (status != AudioSystem.SUCCESS) { 14517 release(); 14518 throw new IllegalStateException("Could not connect mix, error: " + status); 14519 } 14520 } 14521 binderDied()14522 public void binderDied() { 14523 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("AudioPolicy " 14524 + mPolicyCallback.asBinder() + " died").printLog(TAG))); 14525 14526 List<String> addresses = new ArrayList<>(); 14527 for (AudioMix mix : mMixes) { 14528 addresses.add(mix.getRegistration()); 14529 } 14530 onPolicyClientDeath(addresses); 14531 14532 release(); 14533 } 14534 getRegistrationId()14535 String getRegistrationId() { 14536 return getRegistration(); 14537 } 14538 release()14539 void release() { 14540 if (mIsFocusPolicy) { 14541 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy); 14542 } 14543 if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 14544 mMediaFocusControl.setDuckingInExtPolicyAvailable(false); 14545 } 14546 if (mHasFocusListener) { 14547 mMediaFocusControl.removeFocusFollower(mPolicyCallback); 14548 } 14549 if (mProjectionCallback != null) { 14550 try { 14551 mProjection.unregisterCallback(mProjectionCallback); 14552 } catch (RemoteException e) { 14553 Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection"); 14554 } 14555 } 14556 if (mIsVolumeController) { 14557 synchronized (mExtVolumeControllerLock) { 14558 mExtVolumeController = null; 14559 } 14560 } 14561 final long identity = Binder.clearCallingIdentity(); 14562 try { 14563 if (android.media.audiopolicy.Flags.audioMixOwnership()) { 14564 synchronized (mMixes) { 14565 removeMixes(new ArrayList(mMixes)); 14566 } 14567 } else { 14568 mAudioSystem.registerPolicyMixes(mMixes, false); 14569 } 14570 } finally { 14571 Binder.restoreCallingIdentity(identity); 14572 } 14573 synchronized (mAudioPolicies) { 14574 mAudioPolicies.remove(mPolicyCallback.asBinder()); 14575 } 14576 try { 14577 mPolicyCallback.notifyUnregistration(); 14578 } catch (RemoteException e) { } 14579 } 14580 hasMixAffectingUsage(int usage, int excludedFlags)14581 boolean hasMixAffectingUsage(int usage, int excludedFlags) { 14582 for (AudioMix mix : mMixes) { 14583 if (mix.isAffectingUsage(usage) 14584 && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) { 14585 return true; 14586 } 14587 } 14588 return false; 14589 } 14590 14591 // Verify all the devices in the array are served by mixes defined in this policy hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)14592 boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes, 14593 @NonNull String[] deviceAddresses) { 14594 for (int i = 0; i < deviceTypes.length; i++) { 14595 boolean hasDevice = false; 14596 for (AudioMix mix : mMixes) { 14597 // this will check both that the mix has ROUTE_FLAG_RENDER and the device 14598 // is reached by this mix 14599 if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) { 14600 hasDevice = true; 14601 break; 14602 } 14603 } 14604 if (!hasDevice) { 14605 return false; 14606 } 14607 } 14608 return true; 14609 } 14610 addMixes(@onNull ArrayList<AudioMix> mixes)14611 int addMixes(@NonNull ArrayList<AudioMix> mixes) { 14612 synchronized (mMixes) { 14613 if (android.media.audiopolicy.Flags.audioMixOwnership()) { 14614 for (AudioMix mix : mixes) { 14615 setMixRegistration(mix); 14616 mix.setVirtualDeviceId(mAttributionSource.getDeviceId()); 14617 } 14618 14619 int result = mAudioSystem.registerPolicyMixes(mixes, true); 14620 if (result == AudioSystem.SUCCESS) { 14621 this.add(mixes); 14622 } 14623 return result; 14624 } 14625 this.add(mixes); 14626 return mAudioSystem.registerPolicyMixes(mixes, true); 14627 } 14628 } 14629 removeMixes(@onNull ArrayList<AudioMix> mixes)14630 int removeMixes(@NonNull ArrayList<AudioMix> mixes) { 14631 synchronized (mMixes) { 14632 this.remove(mixes); 14633 return mAudioSystem.registerPolicyMixes(mixes, false); 14634 } 14635 } 14636 connectMixes()14637 @AudioSystem.AudioSystemError int connectMixes() { 14638 final long identity = Binder.clearCallingIdentity(); 14639 try { 14640 for (AudioMix mix : mMixes) { 14641 mix.setVirtualDeviceId(mAttributionSource.getDeviceId()); 14642 } 14643 mAudioSystem.registerPolicyMixes(mMixes, false); 14644 return mAudioSystem.registerPolicyMixes(mMixes, true); 14645 } finally { 14646 Binder.restoreCallingIdentity(identity); 14647 } 14648 14649 } 14650 updateMixingRules( @onNull AudioMix[] mixesToUpdate, @NonNull AudioMixingRule[] updatedMixingRules)14651 @AudioSystem.AudioSystemError int updateMixingRules( 14652 @NonNull AudioMix[] mixesToUpdate, 14653 @NonNull AudioMixingRule[] updatedMixingRules) { 14654 Objects.requireNonNull(mixesToUpdate); 14655 Objects.requireNonNull(updatedMixingRules); 14656 14657 for (AudioMix mix : mixesToUpdate) { 14658 mix.setVirtualDeviceId(mAttributionSource.getDeviceId()); 14659 } 14660 if (mixesToUpdate.length != updatedMixingRules.length) { 14661 Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules " 14662 + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length 14663 + ", updatedMixingRules.length = " + updatedMixingRules.length + ")."); 14664 return AudioSystem.BAD_VALUE; 14665 } 14666 14667 synchronized (mMixes) { 14668 try (SafeCloseable unused = ClearCallingIdentityContext.create()) { 14669 int ret = mAudioSystem.updateMixingRules(mixesToUpdate, updatedMixingRules); 14670 if (ret == AudioSystem.SUCCESS) { 14671 for (int i = 0; i < mixesToUpdate.length; i++) { 14672 AudioMix audioMixToUpdate = mixesToUpdate[i]; 14673 AudioMixingRule audioMixingRule = updatedMixingRules[i]; 14674 mMixes.stream().filter(audioMixToUpdate::equals).findAny().ifPresent( 14675 mix -> mix.setAudioMixingRule(audioMixingRule)); 14676 } 14677 } 14678 return ret; 14679 } 14680 } 14681 } 14682 setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)14683 int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { 14684 final Integer Uid = new Integer(uid); 14685 if (mUidDeviceAffinities.remove(Uid) != null) { 14686 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) { 14687 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, " 14688 + " cannot call AudioSystem.setUidDeviceAffinities"); 14689 return AudioManager.ERROR; 14690 } 14691 } 14692 AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses); 14693 if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) { 14694 mUidDeviceAffinities.put(Uid, deviceArray); 14695 return AudioManager.SUCCESS; 14696 } 14697 Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed"); 14698 return AudioManager.ERROR; 14699 } 14700 removeUidDeviceAffinities(int uid)14701 int removeUidDeviceAffinities(int uid) { 14702 if (mUidDeviceAffinities.remove(new Integer(uid)) != null) { 14703 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) { 14704 return AudioManager.SUCCESS; 14705 } 14706 } 14707 Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed"); 14708 return AudioManager.ERROR; 14709 } 14710 removeUidDeviceAffinitiesFromSystem(int uid)14711 @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) { 14712 final long identity = Binder.clearCallingIdentity(); 14713 try { 14714 return mAudioSystem.removeUidDeviceAffinities(uid); 14715 } finally { 14716 Binder.restoreCallingIdentity(identity); 14717 } 14718 } 14719 setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)14720 @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid, 14721 AudioDeviceArray deviceArray) { 14722 final long identity = Binder.clearCallingIdentity(); 14723 try { 14724 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes, 14725 deviceArray.mDeviceAddresses); 14726 } finally { 14727 Binder.restoreCallingIdentity(identity); 14728 } 14729 } 14730 setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)14731 int setUserIdDeviceAffinities(int userId, 14732 @NonNull int[] types, @NonNull String[] addresses) { 14733 final Integer UserId = new Integer(userId); 14734 if (mUserIdDeviceAffinities.remove(UserId) != null) { 14735 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) { 14736 Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities(" 14737 + UserId + ") failed, " 14738 + " cannot call AudioSystem.setUserIdDeviceAffinities"); 14739 return AudioManager.ERROR; 14740 } 14741 } 14742 AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses); 14743 if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray) 14744 == AudioSystem.SUCCESS) { 14745 mUserIdDeviceAffinities.put(UserId, audioDeviceArray); 14746 return AudioManager.SUCCESS; 14747 } 14748 Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed"); 14749 return AudioManager.ERROR; 14750 } 14751 removeUserIdDeviceAffinities(int userId)14752 int removeUserIdDeviceAffinities(int userId) { 14753 if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) { 14754 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) { 14755 return AudioManager.SUCCESS; 14756 } 14757 } 14758 Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed"); 14759 return AudioManager.ERROR; 14760 } 14761 removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)14762 @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem( 14763 @UserIdInt int userId) { 14764 final long identity = Binder.clearCallingIdentity(); 14765 try { 14766 return mAudioSystem.removeUserIdDeviceAffinities(userId); 14767 } finally { 14768 Binder.restoreCallingIdentity(identity); 14769 } 14770 } 14771 setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)14772 @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem( 14773 @UserIdInt int userId, AudioDeviceArray deviceArray) { 14774 final long identity = Binder.clearCallingIdentity(); 14775 try { 14776 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes, 14777 deviceArray.mDeviceAddresses); 14778 } finally { 14779 Binder.restoreCallingIdentity(identity); 14780 } 14781 } 14782 setupDeviceAffinities()14783 @AudioSystem.AudioSystemError int setupDeviceAffinities() { 14784 for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) { 14785 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey()); 14786 if (uidStatus != AudioSystem.SUCCESS) { 14787 Log.e(TAG, 14788 "setupDeviceAffinities failed to remove device affinity for uid " 14789 + uidEntry.getKey()); 14790 return uidStatus; 14791 } 14792 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue()); 14793 if (uidStatus != AudioSystem.SUCCESS) { 14794 Log.e(TAG, 14795 "setupDeviceAffinities failed to set device affinity for uid " 14796 + uidEntry.getKey()); 14797 return uidStatus; 14798 } 14799 } 14800 14801 for (Map.Entry<Integer, AudioDeviceArray> userIdEntry : 14802 mUserIdDeviceAffinities.entrySet()) { 14803 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey()); 14804 if (userIdStatus != AudioSystem.SUCCESS) { 14805 Log.e(TAG, 14806 "setupDeviceAffinities failed to remove device affinity for userId " 14807 + userIdEntry.getKey()); 14808 return userIdStatus; 14809 } 14810 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(), 14811 userIdEntry.getValue()); 14812 if (userIdStatus != AudioSystem.SUCCESS) { 14813 Log.e(TAG, 14814 "setupDeviceAffinities failed to set device affinity for userId " 14815 + userIdEntry.getKey()); 14816 return userIdStatus; 14817 } 14818 } 14819 return AudioSystem.SUCCESS; 14820 } 14821 14822 /** @return human readable debug informations summarizing the state of the object. */ toLogFriendlyString()14823 public String toLogFriendlyString() { 14824 String textDump = super.toLogFriendlyString(); 14825 textDump += " Uid Device Affinities:\n"; 14826 String spacer = " "; 14827 textDump += logFriendlyAttributeDeviceArrayMap("Uid", 14828 mUidDeviceAffinities, spacer); 14829 textDump += " UserId Device Affinities:\n"; 14830 textDump += logFriendlyAttributeDeviceArrayMap("UserId", 14831 mUserIdDeviceAffinities, spacer); 14832 textDump += " Proxy:\n"; 14833 textDump += " is focus policy= " + mIsFocusPolicy + "\n"; 14834 if (mIsFocusPolicy) { 14835 textDump += " focus duck behaviour= " + mFocusDuckBehavior + "\n"; 14836 textDump += " is test focus policy= " + mIsTestFocusPolicy + "\n"; 14837 textDump += " has focus listener= " + mHasFocusListener + "\n"; 14838 } 14839 textDump += " media projection= " + mProjection + "\n"; 14840 return textDump; 14841 } 14842 logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)14843 private String logFriendlyAttributeDeviceArrayMap(String attribute, 14844 Map<Integer, AudioDeviceArray> map, String spacer) { 14845 final StringBuilder stringBuilder = new StringBuilder(); 14846 for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) { 14847 stringBuilder.append(spacer).append(attribute).append(": ") 14848 .append(mapEntry.getKey()).append("\n"); 14849 AudioDeviceArray deviceArray = mapEntry.getValue(); 14850 String deviceSpacer = spacer + " "; 14851 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) { 14852 stringBuilder.append(deviceSpacer).append("Type: 0x") 14853 .append(Integer.toHexString(deviceArray.mDeviceTypes[i])) 14854 .append(" Address: ").append(deviceArray.mDeviceAddresses[i]) 14855 .append("\n"); 14856 } 14857 } 14858 return stringBuilder.toString(); 14859 } 14860 }; 14861 14862 //====================== 14863 // Audio policy: focus 14864 //====================== 14865 /** */ dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)14866 public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) { 14867 if (afi == null) { 14868 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 14869 } 14870 if (pcb == null) { 14871 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 14872 } 14873 synchronized (mAudioPolicies) { 14874 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 14875 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch"); 14876 } 14877 return mMediaFocusControl.dispatchFocusChange(afi, focusChange); 14878 } 14879 } 14880 setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)14881 public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, 14882 IAudioPolicyCallback pcb) { 14883 if (afi == null) { 14884 throw new IllegalArgumentException("Illegal null AudioFocusInfo"); 14885 } 14886 if (pcb == null) { 14887 throw new IllegalArgumentException("Illegal null AudioPolicy callback"); 14888 } 14889 synchronized (mAudioPolicies) { 14890 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 14891 throw new IllegalStateException("Unregistered AudioPolicy for external focus"); 14892 } 14893 mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult); 14894 } 14895 } 14896 14897 /** 14898 * see {@link AudioManager#dispatchAudioFocusChangeWithFade(AudioFocusInfo, int, AudioPolicy, 14899 * List, FadeManagerConfiguration)} 14900 */ 14901 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) dispatchFocusChangeWithFade(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb, List<AudioFocusInfo> otherActiveAfis, FadeManagerConfiguration transientFadeMgrConfig)14902 public int dispatchFocusChangeWithFade(AudioFocusInfo afi, int focusChange, 14903 IAudioPolicyCallback pcb, List<AudioFocusInfo> otherActiveAfis, 14904 FadeManagerConfiguration transientFadeMgrConfig) { 14905 super.dispatchFocusChangeWithFade_enforcePermission(); 14906 ensureFadeManagerConfigIsEnabled(); 14907 Objects.requireNonNull(afi, "AudioFocusInfo cannot be null"); 14908 Objects.requireNonNull(pcb, "AudioPolicy callback cannot be null"); 14909 Objects.requireNonNull(otherActiveAfis, 14910 "Other active AudioFocusInfo list cannot be null"); 14911 if (transientFadeMgrConfig != null) { 14912 validateFadeManagerConfiguration(transientFadeMgrConfig); 14913 } 14914 14915 synchronized (mAudioPolicies) { 14916 Preconditions.checkState(mAudioPolicies.containsKey(pcb.asBinder()), 14917 "Unregistered AudioPolicy for focus dispatch with fade"); 14918 14919 // set the transient fade manager config to be used for handling this focus change 14920 if (transientFadeMgrConfig != null) { 14921 mPlaybackMonitor.setTransientFadeManagerConfiguration(focusChange, 14922 transientFadeMgrConfig); 14923 } 14924 int status = mMediaFocusControl.dispatchFocusChangeWithFade(afi, focusChange, 14925 otherActiveAfis); 14926 14927 if (transientFadeMgrConfig != null) { 14928 mPlaybackMonitor.clearTransientFadeManagerConfiguration(focusChange); 14929 } 14930 return status; 14931 } 14932 } 14933 14934 14935 /** 14936 * @see AudioManager#shouldNotificationSoundPlay(AudioAttributes) 14937 */ 14938 @android.annotation.EnforcePermission(QUERY_AUDIO_STATE) shouldNotificationSoundPlay(@onNull final AudioAttributes aa)14939 public boolean shouldNotificationSoundPlay(@NonNull final AudioAttributes aa) { 14940 super.shouldNotificationSoundPlay_enforcePermission(); 14941 Objects.requireNonNull(aa); 14942 14943 // don't play notifications if the stream volume associated with the 14944 // AudioAttributes of the notification record is 0 (non-zero volume implies 14945 // not silenced by SILENT or VIBRATE ringer mode) 14946 final int stream = AudioAttributes.toLegacyStreamType(aa); 14947 final boolean mutingFromVolume = getStreamVolume(stream) == 0; 14948 if (mutingFromVolume) { 14949 Slog.i(TAG, "shouldNotificationSoundPlay false: muted stream:" + stream 14950 + " attr:" + aa); 14951 return false; 14952 } 14953 14954 // don't play notifications if there is a user of GAIN_TRANSIENT_EXCLUSIVE audio focus 14955 // and the focus owner is recording 14956 final int uid = mMediaFocusControl.getExclusiveFocusOwnerUid(); 14957 if (uid == -1) { // return value is -1 if focus isn't GAIN_TRANSIENT_EXCLUSIVE 14958 return true; 14959 } 14960 // is the owner of GAIN_TRANSIENT_EXCLUSIVE focus also recording? 14961 final boolean mutingFromFocusAndRecording = mRecordMonitor.isRecordingActiveForUid(uid); 14962 if (mutingFromFocusAndRecording) { 14963 Slog.i(TAG, "shouldNotificationSoundPlay false: exclusive focus owner recording " 14964 + " uid:" + uid + " attr:" + aa); 14965 return false; 14966 } 14967 return true; 14968 } 14969 14970 /** 14971 * @see AudioManager#setEnableHardening(boolean) 14972 */ 14973 @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED) setEnableHardening(boolean shouldEnable)14974 public void setEnableHardening(boolean shouldEnable) { 14975 super.setEnableHardening_enforcePermission(); 14976 mShouldEnableAllHardening.set(shouldEnable); 14977 mAudioPolicy.setEnableHardening(shouldEnable); 14978 } 14979 14980 //====================== 14981 // Audioserver state dispatch 14982 //====================== 14983 private class AsdProxy implements IBinder.DeathRecipient { 14984 private final IAudioServerStateDispatcher mAsd; 14985 AsdProxy(IAudioServerStateDispatcher asd)14986 AsdProxy(IAudioServerStateDispatcher asd) { 14987 mAsd = asd; 14988 } 14989 binderDied()14990 public void binderDied() { 14991 synchronized (mAudioServerStateListeners) { 14992 mAudioServerStateListeners.remove(mAsd.asBinder()); 14993 } 14994 } 14995 callback()14996 IAudioServerStateDispatcher callback() { 14997 return mAsd; 14998 } 14999 } 15000 15001 private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners = 15002 new HashMap<IBinder, AsdProxy>(); 15003 checkMonitorAudioServerStatePermission()15004 private void checkMonitorAudioServerStatePermission() { 15005 if (!(mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE) 15006 == PackageManager.PERMISSION_GRANTED 15007 || mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING) 15008 == PackageManager.PERMISSION_GRANTED)) { 15009 throw new SecurityException("Not allowed to monitor audioserver state"); 15010 } 15011 } 15012 registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)15013 public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 15014 checkMonitorAudioServerStatePermission(); 15015 synchronized (mAudioServerStateListeners) { 15016 if (mAudioServerStateListeners.containsKey(asd.asBinder())) { 15017 Slog.w(TAG, "Cannot re-register audio server state dispatcher"); 15018 return; 15019 } 15020 AsdProxy asdp = new AsdProxy(asd); 15021 try { 15022 asd.asBinder().linkToDeath(asdp, 0/*flags*/); 15023 } catch (RemoteException e) { 15024 15025 } 15026 mAudioServerStateListeners.put(asd.asBinder(), asdp); 15027 } 15028 } 15029 unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)15030 public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) { 15031 checkMonitorAudioServerStatePermission(); 15032 synchronized (mAudioServerStateListeners) { 15033 AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder()); 15034 if (asdp == null) { 15035 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid " 15036 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 15037 return; 15038 } else { 15039 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/); 15040 } 15041 } 15042 } 15043 isAudioServerRunning()15044 public boolean isAudioServerRunning() { 15045 checkMonitorAudioServerStatePermission(); 15046 return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK); 15047 } 15048 15049 //====================== 15050 // Audio HAL process dump 15051 //====================== 15052 15053 private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio"; 15054 getAudioAidlHalPids(HashSet<Integer> pids)15055 private void getAudioAidlHalPids(HashSet<Integer> pids) { 15056 try { 15057 ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo(); 15058 if (infos == null) return; 15059 for (ServiceDebugInfo info : infos) { 15060 if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 15061 pids.add(info.debugPid); 15062 } 15063 } 15064 } catch (RuntimeException e) { 15065 // ignored, pid hashset does not change 15066 } 15067 } 15068 getAudioHalHidlPids(HashSet<Integer> pids)15069 private void getAudioHalHidlPids(HashSet<Integer> pids) { 15070 try { 15071 IServiceManager serviceManager = IServiceManager.getService(); 15072 ArrayList<IServiceManager.InstanceDebugInfo> dump = 15073 serviceManager.debugDump(); 15074 for (IServiceManager.InstanceDebugInfo info : dump) { 15075 if (info.pid != IServiceManager.PidConstant.NO_PID 15076 && info.interfaceName != null 15077 && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { 15078 pids.add(info.pid); 15079 } 15080 } 15081 } catch (RemoteException | RuntimeException e) { 15082 // ignored, pid hashset does not change 15083 } 15084 } 15085 getAudioHalPids()15086 private Set<Integer> getAudioHalPids() { 15087 HashSet<Integer> pids = new HashSet<>(); 15088 getAudioAidlHalPids(pids); 15089 getAudioHalHidlPids(pids); 15090 return pids; 15091 } 15092 updateAudioHalPids()15093 private void updateAudioHalPids() { 15094 Set<Integer> pidsSet = getAudioHalPids(); 15095 if (pidsSet.isEmpty()) { 15096 Slog.w(TAG, "Could not retrieve audio HAL service pids"); 15097 return; 15098 } 15099 int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray(); 15100 AudioSystem.setAudioHalPids(pidsArray); 15101 } 15102 15103 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 15104 //====================== 15105 // Multi Audio Focus 15106 //====================== setMultiAudioFocusEnabled(boolean enabled)15107 public void setMultiAudioFocusEnabled(boolean enabled) { 15108 super.setMultiAudioFocusEnabled_enforcePermission(); 15109 15110 if (mMediaFocusControl != null) { 15111 boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled(); 15112 if (mafEnabled != enabled) { 15113 mMediaFocusControl.updateMultiAudioFocus(enabled); 15114 if (!enabled) { 15115 mDeviceBroker.postBroadcastBecomingNoisy(); 15116 } 15117 } 15118 } 15119 } 15120 15121 /** 15122 * @hide 15123 * Sets an additional audio output device delay in milliseconds. 15124 * 15125 * The additional output delay is a request to the output device to 15126 * delay audio presentation (generally with respect to video presentation for better 15127 * synchronization). 15128 * It may not be supported by all output devices, 15129 * and typically increases the audio latency by the amount of additional 15130 * audio delay requested. 15131 * 15132 * If additional audio delay is supported by an audio output device, 15133 * it is expected to be supported for all output streams (and configurations) 15134 * opened on that device. 15135 * 15136 * @param deviceType 15137 * @param address 15138 * @param delayMillis delay in milliseconds desired. This should be in range of {@code 0} 15139 * to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}. 15140 * @return true if successful, false if the device does not support output device delay 15141 * or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}. 15142 */ 15143 @Override 15144 //@RequiresPermission(MODIFY_AUDIO_ROUTING) setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)15145 public boolean setAdditionalOutputDeviceDelay( 15146 @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) { 15147 Objects.requireNonNull(device, "device must not be null"); 15148 enforceModifyAudioRoutingPermission(); 15149 15150 device = retrieveBluetoothAddress(device); 15151 15152 final String getterKey = "additional_output_device_delay=" 15153 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id. 15154 final String setterKey = getterKey + "," + delayMillis; // append the delay for setter 15155 return mRestorableParameters.setParameters(getterKey, setterKey) 15156 == AudioSystem.AUDIO_STATUS_OK; 15157 } 15158 15159 /** 15160 * @hide 15161 * Returns the current audio output device delay value of key in milliseconds. 15162 * 15163 * In aidl implementation, the param of getParameters is "key" and reply delay of all supported 15164 * devices which be composited as "key=device,address,delay|device,address,delay|...". 15165 * e.g. 15166 * param: additional_output_device_delay= 15167 * reply: additional_output_device_delay=2,,0|4,,0|8,,0|128,,0|256,,0|512,,0|1024,,0|8192,,0| 15168 * 16384,,0|262144,,0|262145,,0|524288,,0|67108864,,0|134217728,,0|536870912,,0|536870913,,0| 15169 * 536870914,,0 15170 * 15171 * In hidl implementation, the param of getParameters is "key=device,address" and reply a 15172 * specific device delay which be composited as "key=device,address,delay". 15173 * e.g. 15174 * param: additional_output_device_delay=2, 15175 * reply: additional_output_device_delay=2,,0 15176 * 15177 * @param key 15178 * @param deviceType 15179 * @param address 15180 * @return the delay value of key. This is a non-negative number. 15181 * {@code 0} is returned if unsupported. 15182 */ getDelayByKeyDevice(@onNull String key, @NonNull AudioDeviceAttributes device)15183 private long getDelayByKeyDevice(@NonNull String key, @NonNull AudioDeviceAttributes device) { 15184 long delayMillis = 0; 15185 15186 try { 15187 if (AudioHalVersionInfo.AUDIO_HAL_TYPE_AIDL == getHalVersion().getHalType()) { 15188 final String reply = AudioSystem.getParameters(key); 15189 final String keyDeviceAddressPrefix = 15190 Integer.toUnsignedString(device.getInternalType()) + "," + device.getAddress() + 15191 ","; 15192 int start = reply.indexOf(keyDeviceAddressPrefix); 15193 int end = -1; 15194 if (start != -1) { 15195 start += keyDeviceAddressPrefix.length(); 15196 end = reply.indexOf("|", start); 15197 delayMillis = Long.parseLong( 15198 end == -1 ? reply.substring(start) : reply.substring(start, end)); 15199 } 15200 } else { 15201 final String reply = AudioSystem.getParameters( 15202 key + "=" + device.getInternalType() + "," + device.getAddress()); 15203 if (reply.contains(key)) { 15204 delayMillis = Long.parseLong(reply.substring(key.length() + 1)); 15205 } 15206 } 15207 } catch (NullPointerException e) { 15208 Log.w(TAG, "NullPointerException when getting delay for device " + device, e); 15209 } 15210 15211 return delayMillis; 15212 } 15213 15214 /** 15215 * @hide 15216 * Returns the current additional audio output device delay in milliseconds. 15217 * 15218 * @param deviceType 15219 * @param address 15220 * @return the additional output device delay. This is a non-negative number. 15221 * {@code 0} is returned if unsupported. 15222 */ 15223 @Override 15224 @IntRange(from = 0) getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)15225 public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 15226 Objects.requireNonNull(device, "device must not be null"); 15227 15228 device = retrieveBluetoothAddress(device); 15229 15230 final String key = "additional_output_device_delay"; 15231 15232 return getDelayByKeyDevice(key, device); 15233 } 15234 15235 /** 15236 * @hide 15237 * Returns the maximum additional audio output device delay in milliseconds. 15238 * 15239 * @param deviceType 15240 * @param address 15241 * @return the maximum output device delay in milliseconds that can be set. 15242 * This is a non-negative number 15243 * representing the additional audio delay supported for the device. 15244 * {@code 0} is returned if unsupported. 15245 */ 15246 @Override 15247 @IntRange(from = 0) getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)15248 public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) { 15249 Objects.requireNonNull(device, "device must not be null"); 15250 15251 device = retrieveBluetoothAddress(device); 15252 15253 final String key = "max_additional_output_device_delay"; 15254 15255 return getDelayByKeyDevice(key, device); 15256 } 15257 15258 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 15259 /** @see AudioManager#addAssistantServicesUids(int []) */ 15260 @Override addAssistantServicesUids(int [] assistantUids)15261 public void addAssistantServicesUids(int [] assistantUids) { 15262 super.addAssistantServicesUids_enforcePermission(); 15263 15264 Objects.requireNonNull(assistantUids); 15265 15266 synchronized (mSettingsLock) { 15267 addAssistantServiceUidsLocked(assistantUids); 15268 } 15269 } 15270 15271 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 15272 /** @see AudioManager#removeAssistantServicesUids(int []) */ 15273 @Override removeAssistantServicesUids(int [] assistantUids)15274 public void removeAssistantServicesUids(int [] assistantUids) { 15275 super.removeAssistantServicesUids_enforcePermission(); 15276 15277 Objects.requireNonNull(assistantUids); 15278 synchronized (mSettingsLock) { 15279 removeAssistantServiceUidsLocked(assistantUids); 15280 } 15281 } 15282 15283 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 15284 /** @see AudioManager#getAssistantServicesUids() */ 15285 @Override getAssistantServicesUids()15286 public int[] getAssistantServicesUids() { 15287 super.getAssistantServicesUids_enforcePermission(); 15288 15289 int [] assistantUids; 15290 synchronized (mSettingsLock) { 15291 assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray(); 15292 } 15293 return assistantUids; 15294 } 15295 15296 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 15297 /** @see AudioManager#setActiveAssistantServiceUids(int []) */ 15298 @Override setActiveAssistantServiceUids(int [] activeAssistantUids)15299 public void setActiveAssistantServiceUids(int [] activeAssistantUids) { 15300 super.setActiveAssistantServiceUids_enforcePermission(); 15301 15302 Objects.requireNonNull(activeAssistantUids); 15303 synchronized (mSettingsLock) { 15304 mActiveAssistantServiceUids = activeAssistantUids; 15305 } 15306 updateActiveAssistantServiceUids(); 15307 } 15308 15309 @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING) 15310 /** @see AudioManager#getActiveAssistantServiceUids() */ 15311 @Override getActiveAssistantServiceUids()15312 public int[] getActiveAssistantServiceUids() { 15313 super.getActiveAssistantServiceUids_enforcePermission(); 15314 15315 int [] activeAssistantUids; 15316 synchronized (mSettingsLock) { 15317 activeAssistantUids = mActiveAssistantServiceUids.clone(); 15318 } 15319 return activeAssistantUids; 15320 } 15321 15322 @Override 15323 /** @see AudioManager#permissionUpdateBarrier() */ permissionUpdateBarrier()15324 public void permissionUpdateBarrier() { 15325 if (!audioserverPermissions()) return; 15326 if (PropertyInvalidatedCache.separatePermissionNotificationsEnabled()) { 15327 mCacheWatcher.doCheck(); 15328 } else { 15329 mAudioSystem.triggerSystemPropertyUpdate(mSysPropListenerNativeHandle); 15330 } 15331 List<Future> snapshot; 15332 synchronized (mScheduledPermissionTasks) { 15333 snapshot = List.copyOf(mScheduledPermissionTasks); 15334 } 15335 for (var x : snapshot) { 15336 try { 15337 x.get(); 15338 } catch (CancellationException e) { 15339 // Task completed 15340 } catch (InterruptedException | ExecutionException e) { 15341 Log.wtf(TAG, "Exception which should never occur", e); 15342 } 15343 } 15344 } 15345 getDeviceIdentityAddresses(AudioDeviceAttributes device)15346 List<String> getDeviceIdentityAddresses(AudioDeviceAttributes device) { 15347 return mDeviceBroker.getDeviceIdentityAddresses(device); 15348 } 15349 15350 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) getMusicFxHelper()15351 MusicFxHelper getMusicFxHelper() { 15352 return mMusicFxHelper; 15353 } 15354 15355 //====================== 15356 // misc 15357 //====================== 15358 private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = 15359 new HashMap<IBinder, AudioPolicyProxy>(); 15360 @GuardedBy("mAudioPolicies") 15361 private int mAudioPolicyCounter = 0; 15362 15363 //====================== 15364 // Helper functions for full and fixed volume device 15365 //====================== isFixedVolumeDevice(int deviceType)15366 private boolean isFixedVolumeDevice(int deviceType) { 15367 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 15368 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 15369 return false; 15370 } 15371 return mFixedVolumeDevices.contains(deviceType); 15372 } 15373 isFullVolumeDevice(int deviceType)15374 private boolean isFullVolumeDevice(int deviceType) { 15375 if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX 15376 && mRecordMonitor.isLegacyRemoteSubmixActive()) { 15377 return false; 15378 } 15379 return mFullVolumeDevices.contains(deviceType); 15380 } 15381 15382 /** 15383 * Returns the input device which uses absolute volume behavior, including its variants, 15384 * or {@code null} if there is no mapping for the device type 15385 */ 15386 @Nullable getAbsoluteVolumeDeviceInfo(int deviceType)15387 private AbsoluteVolumeDeviceInfo getAbsoluteVolumeDeviceInfo(int deviceType) { 15388 synchronized (mAbsoluteVolumeDeviceInfoMapLock) { 15389 return mAbsoluteVolumeDeviceInfoMap.get(deviceType); 15390 } 15391 } 15392 15393 /** 15394 * Returns whether the input device uses absolute volume behavior, including its variants. 15395 * For included volume behaviors, see 15396 * {@link AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior}. 15397 * <p>This is distinct from Bluetooth A2DP absolute volume behavior 15398 * ({@link #isA2dpAbsoluteVolumeDevice}). 15399 */ isAbsoluteVolumeDevice(int deviceType)15400 private boolean isAbsoluteVolumeDevice(int deviceType) { 15401 synchronized (mAbsoluteVolumeDeviceInfoMapLock) { 15402 return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType); 15403 } 15404 } 15405 15406 /** 15407 * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume 15408 * behavior. This is distinct from the general implementation of absolute volume behavior 15409 * ({@link #isAbsoluteVolumeDevice}). 15410 */ isA2dpAbsoluteVolumeDevice(int deviceType)15411 private boolean isA2dpAbsoluteVolumeDevice(int deviceType) { 15412 return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType); 15413 } 15414 15415 //==================== 15416 // Helper functions for {set,get}DeviceVolumeBehavior 15417 //==================== getSettingsNameForDeviceVolumeBehavior(int deviceType)15418 private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) { 15419 return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType); 15420 } 15421 persistDeviceVolumeBehavior(int deviceType, @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior)15422 private void persistDeviceVolumeBehavior(int deviceType, 15423 @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior) { 15424 if (DEBUG_VOL) { 15425 Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType); 15426 } 15427 final long callingIdentity = Binder.clearCallingIdentity(); 15428 try { 15429 mSettings.putSystemIntForUser(mContentResolver, 15430 getSettingsNameForDeviceVolumeBehavior(deviceType), 15431 deviceVolumeBehavior, 15432 UserHandle.USER_CURRENT); 15433 } finally { 15434 Binder.restoreCallingIdentity(callingIdentity); 15435 } 15436 } 15437 15438 @AudioDeviceVolumeManager.DeviceVolumeBehaviorState retrieveStoredDeviceVolumeBehavior(int deviceType)15439 private int retrieveStoredDeviceVolumeBehavior(int deviceType) { 15440 return mSettings.getSystemIntForUser(mContentResolver, 15441 getSettingsNameForDeviceVolumeBehavior(deviceType), 15442 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET, 15443 UserHandle.USER_CURRENT); 15444 } 15445 restoreDeviceVolumeBehavior()15446 private void restoreDeviceVolumeBehavior() { 15447 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) { 15448 if (DEBUG_VOL) { 15449 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType); 15450 } 15451 int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType); 15452 if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) { 15453 if (DEBUG_VOL) { 15454 Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType); 15455 } 15456 continue; 15457 } 15458 15459 setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""), 15460 deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()"); 15461 } 15462 } 15463 15464 /** 15465 * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_* 15466 * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume 15467 * behavior 15468 */ hasDeviceVolumeBehavior( int audioSystemDeviceOut)15469 private boolean hasDeviceVolumeBehavior( 15470 int audioSystemDeviceOut) { 15471 return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut) 15472 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET; 15473 } 15474 addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)15475 private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) { 15476 if (DEBUG_VOL) { 15477 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 15478 + " to mFixedVolumeDevices"); 15479 } 15480 return mFixedVolumeDevices.add(audioSystemDeviceOut); 15481 } 15482 removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)15483 private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) { 15484 if (DEBUG_VOL) { 15485 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 15486 + " from mFixedVolumeDevices"); 15487 } 15488 return mFixedVolumeDevices.remove(audioSystemDeviceOut); 15489 } 15490 addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)15491 private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) { 15492 if (DEBUG_VOL) { 15493 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 15494 + " to mFullVolumeDevices"); 15495 } 15496 return mFullVolumeDevices.add(audioSystemDeviceOut); 15497 } 15498 removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)15499 private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) { 15500 if (DEBUG_VOL) { 15501 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 15502 + " from mFullVolumeDevices"); 15503 } 15504 return mFullVolumeDevices.remove(audioSystemDeviceOut); 15505 } 15506 addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)15507 private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, 15508 AbsoluteVolumeDeviceInfo info) { 15509 if (info == null) { 15510 Log.e(TAG, "Cannot add null absolute volume info for audioSystemDeviceOut " 15511 + audioSystemDeviceOut); 15512 return; 15513 } 15514 if (DEBUG_VOL) { 15515 Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 15516 + " to mAbsoluteVolumeDeviceInfoMap with behavior " 15517 + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior) 15518 ); 15519 } 15520 synchronized (mAbsoluteVolumeDeviceInfoMapLock) { 15521 mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info); 15522 } 15523 } 15524 removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)15525 private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices( 15526 int audioSystemDeviceOut) { 15527 if (DEBUG_VOL) { 15528 Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut) 15529 + " from mAbsoluteVolumeDeviceInfoMap"); 15530 } 15531 15532 synchronized (mAbsoluteVolumeDeviceInfoMapLock) { 15533 return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut); 15534 } 15535 } 15536 getAudioPermissionsDelay()15537 private long getAudioPermissionsDelay() { 15538 return isAudioPermissionUpdatesAddtionallyDelayed() 15539 ? SCHEDULED_PERMISSION_UPDATE_LONG_DELAY_MS 15540 : SCHEDULED_PERMISSION_UPDATE_DELAY_MS; 15541 } 15542 isAudioPermissionUpdatesAddtionallyDelayed()15543 private boolean isAudioPermissionUpdatesAddtionallyDelayed() { 15544 // Additional delays on low core devices in order to optimize app launch latencies 15545 return deferWearPermissionUpdates() 15546 && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH); 15547 } 15548 15549 //==================== 15550 // Helper functions for app ops 15551 //==================== 15552 /** 15553 * Validates, and notes an app op for a given uid and package name. 15554 * Validation comes from exception catching: a security exception indicates the package 15555 * doesn't exist, an IAE indicates the uid and package don't match. The code only checks 15556 * if exception was thrown for robustness to code changes in op validation 15557 * @param op the app op to check 15558 * @param uid the uid of the caller 15559 * @param packageName the package to check 15560 * @return true if the origin of the call is valid (no uid / package mismatch) and the caller 15561 * is allowed to perform the operation 15562 */ checkNoteAppOp(int op, int uid, String packageName, String attributionTag)15563 private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) { 15564 try { 15565 if (mAppOps.noteOp(op, uid, packageName, attributionTag, null) 15566 != AppOpsManager.MODE_ALLOWED) { 15567 return false; 15568 } 15569 } catch (Exception e) { 15570 Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:" 15571 + packageName, e); 15572 return false; 15573 } 15574 return true; 15575 } 15576 getPackageNameForUid(int uid)15577 private String getPackageNameForUid(int uid) { 15578 final long token = Binder.clearCallingIdentity(); 15579 try { 15580 final String[] names = AudioService.this.mContext. 15581 getPackageManager().getPackagesForUid(uid); 15582 if (names == null 15583 || names.length == 0 15584 || TextUtils.isEmpty(names[0])) { 15585 return "[" + uid + "]"; 15586 } 15587 return names[0]; 15588 } finally { 15589 Binder.restoreCallingIdentity(token); 15590 } 15591 } 15592 15593 15594 } 15595