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