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