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