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