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.os.Process.FIRST_APPLICATION_UID; 24 25 import android.Manifest; 26 import android.app.ActivityManager; 27 import android.app.ActivityManagerInternal; 28 import android.app.ActivityManagerNative; 29 import android.app.AppGlobals; 30 import android.app.AppOpsManager; 31 import android.app.NotificationManager; 32 import android.bluetooth.BluetoothA2dp; 33 import android.bluetooth.BluetoothAdapter; 34 import android.bluetooth.BluetoothClass; 35 import android.bluetooth.BluetoothDevice; 36 import android.bluetooth.BluetoothHeadset; 37 import android.bluetooth.BluetoothProfile; 38 import android.content.BroadcastReceiver; 39 import android.content.ComponentName; 40 import android.content.ContentResolver; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.IntentFilter; 44 import android.content.pm.ApplicationInfo; 45 import android.content.pm.PackageInfo; 46 import android.content.pm.PackageManager; 47 import android.content.pm.UserInfo; 48 import android.content.res.Configuration; 49 import android.content.res.Resources; 50 import android.content.res.XmlResourceParser; 51 import android.database.ContentObserver; 52 import android.hardware.hdmi.HdmiControlManager; 53 import android.hardware.hdmi.HdmiPlaybackClient; 54 import android.hardware.hdmi.HdmiTvClient; 55 import android.hardware.usb.UsbManager; 56 import android.media.AudioAttributes; 57 import android.media.AudioDevicePort; 58 import android.media.AudioSystem; 59 import android.media.AudioFormat; 60 import android.media.AudioManager; 61 import android.media.AudioManagerInternal; 62 import android.media.AudioPort; 63 import android.media.AudioRecordingConfiguration; 64 import android.media.AudioRoutesInfo; 65 import android.media.IAudioFocusDispatcher; 66 import android.media.IAudioRoutesObserver; 67 import android.media.IAudioService; 68 import android.media.IRecordingConfigDispatcher; 69 import android.media.IRingtonePlayer; 70 import android.media.IVolumeController; 71 import android.media.MediaPlayer; 72 import android.media.SoundPool; 73 import android.media.VolumePolicy; 74 import android.media.MediaPlayer.OnCompletionListener; 75 import android.media.MediaPlayer.OnErrorListener; 76 import android.media.audiopolicy.AudioMix; 77 import android.media.audiopolicy.AudioPolicy; 78 import android.media.audiopolicy.AudioPolicyConfig; 79 import android.media.audiopolicy.IAudioPolicyCallback; 80 import android.os.Binder; 81 import android.os.Build; 82 import android.os.Bundle; 83 import android.os.Environment; 84 import android.os.Handler; 85 import android.os.IBinder; 86 import android.os.Looper; 87 import android.os.Message; 88 import android.os.PowerManager; 89 import android.os.RemoteCallbackList; 90 import android.os.RemoteException; 91 import android.os.SystemClock; 92 import android.os.SystemProperties; 93 import android.os.UserHandle; 94 import android.os.UserManager; 95 import android.os.UserManagerInternal; 96 import android.os.UserManagerInternal.UserRestrictionsListener; 97 import android.os.Vibrator; 98 import android.provider.Settings; 99 import android.provider.Settings.System; 100 import android.telecom.TelecomManager; 101 import android.text.TextUtils; 102 import android.util.AndroidRuntimeException; 103 import android.util.ArrayMap; 104 import android.util.ArraySet; 105 import android.util.Log; 106 import android.util.MathUtils; 107 import android.util.Slog; 108 import android.util.SparseIntArray; 109 import android.view.KeyEvent; 110 import android.view.accessibility.AccessibilityManager; 111 112 import com.android.internal.util.XmlUtils; 113 import com.android.server.EventLogTags; 114 import com.android.server.LocalServices; 115 import com.android.server.SystemService; 116 import com.android.server.pm.UserManagerService; 117 118 import org.xmlpull.v1.XmlPullParserException; 119 120 import java.io.FileDescriptor; 121 import java.io.IOException; 122 import java.io.PrintWriter; 123 import java.lang.reflect.Field; 124 import java.util.ArrayList; 125 import java.util.HashMap; 126 import java.util.Iterator; 127 import java.util.List; 128 import java.util.NoSuchElementException; 129 import java.util.Objects; 130 131 /** 132 * The implementation of the volume manager service. 133 * <p> 134 * This implementation focuses on delivering a responsive UI. Most methods are 135 * asynchronous to external calls. For example, the task of setting a volume 136 * will update our internal state, but in a separate thread will set the system 137 * volume and later persist to the database. Similarly, setting the ringer mode 138 * will update the state and broadcast a change and in a separate thread later 139 * persist the ringer mode. 140 * 141 * @hide 142 */ 143 public class AudioService extends IAudioService.Stub { 144 145 private static final String TAG = "AudioService"; 146 147 /** Debug audio mode */ 148 protected static final boolean DEBUG_MODE = Log.isLoggable(TAG + ".MOD", Log.DEBUG); 149 150 /** Debug audio policy feature */ 151 protected static final boolean DEBUG_AP = Log.isLoggable(TAG + ".AP", Log.DEBUG); 152 153 /** Debug volumes */ 154 protected static final boolean DEBUG_VOL = Log.isLoggable(TAG + ".VOL", Log.DEBUG); 155 156 /** debug calls to devices APIs */ 157 protected static final boolean DEBUG_DEVICES = Log.isLoggable(TAG + ".DEVICES", Log.DEBUG); 158 159 /** How long to delay before persisting a change in volume/ringer mode. */ 160 private static final int PERSIST_DELAY = 500; 161 162 /** How long to delay after a volume down event before unmuting a stream */ 163 private static final int UNMUTE_STREAM_DELAY = 350; 164 165 /** 166 * Only used in the result from {@link #checkForRingerModeChange(int, int, int)} 167 */ 168 private static final int FLAG_ADJUST_VOLUME = 1; 169 170 private final Context mContext; 171 private final ContentResolver mContentResolver; 172 private final AppOpsManager mAppOps; 173 174 // the platform type affects volume and silent mode behavior 175 private final int mPlatformType; 176 isPlatformVoice()177 private boolean isPlatformVoice() { 178 return mPlatformType == AudioSystem.PLATFORM_VOICE; 179 } 180 isPlatformTelevision()181 private boolean isPlatformTelevision() { 182 return mPlatformType == AudioSystem.PLATFORM_TELEVISION; 183 } 184 185 /** The controller for the volume UI. */ 186 private final VolumeController mVolumeController = new VolumeController(); 187 private final ControllerService mControllerService = new ControllerService(); 188 189 // sendMsg() flags 190 /** If the msg is already queued, replace it with this one. */ 191 private static final int SENDMSG_REPLACE = 0; 192 /** If the msg is already queued, ignore this one and leave the old. */ 193 private static final int SENDMSG_NOOP = 1; 194 /** If the msg is already queued, queue this one and leave the old. */ 195 private static final int SENDMSG_QUEUE = 2; 196 197 // AudioHandler messages 198 private static final int MSG_SET_DEVICE_VOLUME = 0; 199 private static final int MSG_PERSIST_VOLUME = 1; 200 private static final int MSG_PERSIST_RINGER_MODE = 3; 201 private static final int MSG_AUDIO_SERVER_DIED = 4; 202 private static final int MSG_PLAY_SOUND_EFFECT = 5; 203 private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6; 204 private static final int MSG_LOAD_SOUND_EFFECTS = 7; 205 private static final int MSG_SET_FORCE_USE = 8; 206 private static final int MSG_BT_HEADSET_CNCT_FAILED = 9; 207 private static final int MSG_SET_ALL_VOLUMES = 10; 208 private static final int MSG_REPORT_NEW_ROUTES = 12; 209 private static final int MSG_SET_FORCE_BT_A2DP_USE = 13; 210 private static final int MSG_CHECK_MUSIC_ACTIVE = 14; 211 private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 15; 212 private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 16; 213 private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 17; 214 private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 18; 215 private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 19; 216 private static final int MSG_UNLOAD_SOUND_EFFECTS = 20; 217 private static final int MSG_SYSTEM_READY = 21; 218 private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 22; 219 private static final int MSG_UNMUTE_STREAM = 24; 220 private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 25; 221 private static final int MSG_INDICATE_SYSTEM_READY = 26; 222 // start of messages handled under wakelock 223 // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), 224 // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) 225 private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 100; 226 private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101; 227 private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102; 228 // end of messages handled under wakelock 229 230 private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000; 231 // Timeout for connection to bluetooth headset service 232 private static final int BT_HEADSET_CNCT_TIMEOUT_MS = 3000; 233 234 // retry delay in case of failure to indicate system ready to AudioFlinger 235 private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; 236 237 /** @see AudioSystemThread */ 238 private AudioSystemThread mAudioSystemThread; 239 /** @see AudioHandler */ 240 private AudioHandler mAudioHandler; 241 /** @see VolumeStreamState */ 242 private VolumeStreamState[] mStreamStates; 243 private SettingsObserver mSettingsObserver; 244 245 private int mMode = AudioSystem.MODE_NORMAL; 246 // protects mRingerMode 247 private final Object mSettingsLock = new Object(); 248 249 private SoundPool mSoundPool; 250 private final Object mSoundEffectsLock = new Object(); 251 private static final int NUM_SOUNDPOOL_CHANNELS = 4; 252 253 /* Sound effect file names */ 254 private static final String SOUND_EFFECTS_PATH = "/media/audio/ui/"; 255 private static final List<String> SOUND_EFFECT_FILES = new ArrayList<String>(); 256 257 /* Sound effect file name mapping sound effect id (AudioManager.FX_xxx) to 258 * file index in SOUND_EFFECT_FILES[] (first column) and indicating if effect 259 * uses soundpool (second column) */ 260 private final int[][] SOUND_EFFECT_FILES_MAP = new int[AudioManager.NUM_SOUND_EFFECTS][2]; 261 262 /** Maximum volume index values for audio streams */ 263 private static int[] MAX_STREAM_VOLUME = new int[] { 264 5, // STREAM_VOICE_CALL 265 7, // STREAM_SYSTEM 266 7, // STREAM_RING 267 15, // STREAM_MUSIC 268 7, // STREAM_ALARM 269 7, // STREAM_NOTIFICATION 270 15, // STREAM_BLUETOOTH_SCO 271 7, // STREAM_SYSTEM_ENFORCED 272 15, // STREAM_DTMF 273 15 // STREAM_TTS 274 }; 275 276 /** Minimum volume index values for audio streams */ 277 private static int[] MIN_STREAM_VOLUME = new int[] { 278 1, // STREAM_VOICE_CALL 279 0, // STREAM_SYSTEM 280 0, // STREAM_RING 281 0, // STREAM_MUSIC 282 0, // STREAM_ALARM 283 0, // STREAM_NOTIFICATION 284 0, // STREAM_BLUETOOTH_SCO 285 0, // STREAM_SYSTEM_ENFORCED 286 0, // STREAM_DTMF 287 0 // STREAM_TTS 288 }; 289 290 /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings 291 * of another stream: This avoids multiplying the volume settings for hidden 292 * stream types that follow other stream behavior for volume settings 293 * NOTE: do not create loops in aliases! 294 * Some streams alias to different streams according to device category (phone or tablet) or 295 * use case (in call vs off call...). See updateStreamVolumeAlias() for more details. 296 * mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device 297 * (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and 298 * STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/ 299 private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] { 300 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 301 AudioSystem.STREAM_RING, // STREAM_SYSTEM 302 AudioSystem.STREAM_RING, // STREAM_RING 303 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 304 AudioSystem.STREAM_ALARM, // STREAM_ALARM 305 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 306 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 307 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 308 AudioSystem.STREAM_RING, // STREAM_DTMF 309 AudioSystem.STREAM_MUSIC // STREAM_TTS 310 }; 311 private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { 312 AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL 313 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM 314 AudioSystem.STREAM_MUSIC, // STREAM_RING 315 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 316 AudioSystem.STREAM_MUSIC, // STREAM_ALARM 317 AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION 318 AudioSystem.STREAM_MUSIC, // STREAM_BLUETOOTH_SCO 319 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED 320 AudioSystem.STREAM_MUSIC, // STREAM_DTMF 321 AudioSystem.STREAM_MUSIC // STREAM_TTS 322 }; 323 private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { 324 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 325 AudioSystem.STREAM_RING, // STREAM_SYSTEM 326 AudioSystem.STREAM_RING, // STREAM_RING 327 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 328 AudioSystem.STREAM_ALARM, // STREAM_ALARM 329 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 330 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 331 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 332 AudioSystem.STREAM_RING, // STREAM_DTMF 333 AudioSystem.STREAM_MUSIC // STREAM_TTS 334 }; 335 private int[] mStreamVolumeAlias; 336 337 /** 338 * Map AudioSystem.STREAM_* constants to app ops. This should be used 339 * after mapping through mStreamVolumeAlias. 340 */ 341 private static final int[] STREAM_VOLUME_OPS = new int[] { 342 AppOpsManager.OP_AUDIO_VOICE_VOLUME, // STREAM_VOICE_CALL 343 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM 344 AppOpsManager.OP_AUDIO_RING_VOLUME, // STREAM_RING 345 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_MUSIC 346 AppOpsManager.OP_AUDIO_ALARM_VOLUME, // STREAM_ALARM 347 AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, // STREAM_NOTIFICATION 348 AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, // STREAM_BLUETOOTH_SCO 349 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED 350 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF 351 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS 352 }; 353 354 private final boolean mUseFixedVolume; 355 356 private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() { 357 public void onError(int error) { 358 switch (error) { 359 case AudioSystem.AUDIO_STATUS_SERVER_DIED: 360 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, 361 SENDMSG_NOOP, 0, 0, null, 0); 362 break; 363 default: 364 break; 365 } 366 } 367 }; 368 369 /** 370 * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL}, 371 * {@link AudioManager#RINGER_MODE_SILENT}, or 372 * {@link AudioManager#RINGER_MODE_VIBRATE}. 373 */ 374 // protected by mSettingsLock 375 private int mRingerMode; // internal ringer mode, affects muting of underlying streams 376 private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager) 377 378 /** @see System#MODE_RINGER_STREAMS_AFFECTED */ 379 private int mRingerModeAffectedStreams = 0; 380 381 // Streams currently muted by ringer mode 382 private int mRingerModeMutedStreams; 383 384 /** Streams that can be muted. Do not resolve to aliases when checking. 385 * @see System#MUTE_STREAMS_AFFECTED */ 386 private int mMuteAffectedStreams; 387 388 /** 389 * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated. 390 * mVibrateSetting is just maintained during deprecation period but vibration policy is 391 * now only controlled by mHasVibrator and mRingerMode 392 */ 393 private int mVibrateSetting; 394 395 // Is there a vibrator 396 private final boolean mHasVibrator; 397 398 // Broadcast receiver for device connections intent broadcasts 399 private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); 400 401 /** Interface for UserManagerService. */ 402 private final UserManagerInternal mUserManagerInternal; 403 404 private final UserRestrictionsListener mUserRestrictionsListener = 405 new AudioServiceUserRestrictionsListener(); 406 407 // Devices currently connected 408 // Use makeDeviceListKey() to make a unique key for this list. 409 private class DeviceListSpec { 410 int mDeviceType; 411 String mDeviceName; 412 String mDeviceAddress; 413 DeviceListSpec(int deviceType, String deviceName, String deviceAddress)414 public DeviceListSpec(int deviceType, String deviceName, String deviceAddress) { 415 mDeviceType = deviceType; 416 mDeviceName = deviceName; 417 mDeviceAddress = deviceAddress; 418 } 419 toString()420 public String toString() { 421 return "[type:0x" + Integer.toHexString(mDeviceType) + " name:" + mDeviceName 422 + " address:" + mDeviceAddress + "]"; 423 } 424 } 425 426 // Generate a unique key for the mConnectedDevices List by composing the device "type" 427 // and the "address" associated with a specific instance of that device type makeDeviceListKey(int device, String deviceAddress)428 private String makeDeviceListKey(int device, String deviceAddress) { 429 return "0x" + Integer.toHexString(device) + ":" + deviceAddress; 430 } 431 432 private final ArrayMap<String, DeviceListSpec> mConnectedDevices = new ArrayMap<>(); 433 434 // Forced device usage for communications 435 private int mForcedUseForComm; 436 437 // List of binder death handlers for setMode() client processes. 438 // The last process to have called setMode() is at the top of the list. 439 private final ArrayList <SetModeDeathHandler> mSetModeDeathHandlers = new ArrayList <SetModeDeathHandler>(); 440 441 // List of clients having issued a SCO start request 442 private final ArrayList <ScoClient> mScoClients = new ArrayList <ScoClient>(); 443 444 // BluetoothHeadset API to control SCO connection 445 private BluetoothHeadset mBluetoothHeadset; 446 447 // Bluetooth headset device 448 private BluetoothDevice mBluetoothHeadsetDevice; 449 450 // Indicate if SCO audio connection is currently active and if the initiator is 451 // audio service (internal) or bluetooth headset (external) 452 private int mScoAudioState; 453 // SCO audio state is not active 454 private static final int SCO_STATE_INACTIVE = 0; 455 // SCO audio activation request waiting for headset service to connect 456 private static final int SCO_STATE_ACTIVATE_REQ = 1; 457 // SCO audio state is active or starting due to a request from AudioManager API 458 private static final int SCO_STATE_ACTIVE_INTERNAL = 3; 459 // SCO audio deactivation request waiting for headset service to connect 460 private static final int SCO_STATE_DEACTIVATE_REQ = 5; 461 462 // SCO audio state is active due to an action in BT handsfree (either voice recognition or 463 // in call audio) 464 private static final int SCO_STATE_ACTIVE_EXTERNAL = 2; 465 // Deactivation request for all SCO connections (initiated by audio mode change) 466 // waiting for headset service to connect 467 private static final int SCO_STATE_DEACTIVATE_EXT_REQ = 4; 468 469 // Indicates the mode used for SCO audio connection. The mode is virtual call if the request 470 // originated from an app targeting an API version before JB MR2 and raw audio after that. 471 private int mScoAudioMode; 472 // SCO audio mode is undefined 473 private static final int SCO_MODE_UNDEFINED = -1; 474 // SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall()) 475 private static final int SCO_MODE_VIRTUAL_CALL = 0; 476 // SCO audio mode is raw audio (BluetoothHeadset.connectAudio()) 477 private static final int SCO_MODE_RAW = 1; 478 // SCO audio mode is Voice Recognition (BluetoothHeadset.startVoiceRecognition()) 479 private static final int SCO_MODE_VR = 2; 480 481 private static final int SCO_MODE_MAX = 2; 482 483 // Current connection state indicated by bluetooth headset 484 private int mScoConnectionState; 485 486 // true if boot sequence has been completed 487 private boolean mSystemReady; 488 // true if Intent.ACTION_USER_SWITCHED has ever been received 489 private boolean mUserSwitchedReceived; 490 // listener for SoundPool sample load completion indication 491 private SoundPoolCallback mSoundPoolCallBack; 492 // thread for SoundPool listener 493 private SoundPoolListenerThread mSoundPoolListenerThread; 494 // message looper for SoundPool listener 495 private Looper mSoundPoolLooper = null; 496 // volume applied to sound played with playSoundEffect() 497 private static int sSoundEffectVolumeDb; 498 // previous volume adjustment direction received by checkForRingerModeChange() 499 private int mPrevVolDirection = AudioManager.ADJUST_SAME; 500 // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume 501 // is controlled by Vol keys. 502 private int mVolumeControlStream = -1; 503 private final Object mForceControlStreamLock = new Object(); 504 // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system 505 // server process so in theory it is not necessary to monitor the client death. 506 // However it is good to be ready for future evolutions. 507 private ForceControlStreamClient mForceControlStreamClient = null; 508 // Used to play ringtones outside system_server 509 private volatile IRingtonePlayer mRingtonePlayer; 510 511 private int mDeviceOrientation = Configuration.ORIENTATION_UNDEFINED; 512 513 // Request to override default use of A2DP for media. 514 private boolean mBluetoothA2dpEnabled; 515 private final Object mBluetoothA2dpEnabledLock = new Object(); 516 517 // Monitoring of audio routes. Protected by mCurAudioRoutes. 518 final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo(); 519 final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers 520 = new RemoteCallbackList<IAudioRoutesObserver>(); 521 522 // Devices for which the volume is fixed and VolumePanel slider should be disabled 523 int mFixedVolumeDevices = AudioSystem.DEVICE_OUT_HDMI | 524 AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET | 525 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET | 526 AudioSystem.DEVICE_OUT_HDMI_ARC | 527 AudioSystem.DEVICE_OUT_SPDIF | 528 AudioSystem.DEVICE_OUT_AUX_LINE; 529 int mFullVolumeDevices = 0; 530 531 // TODO merge orientation and rotation 532 private final boolean mMonitorOrientation; 533 private final boolean mMonitorRotation; 534 535 private boolean mDockAudioMediaEnabled = true; 536 537 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 538 539 // Used when safe volume warning message display is requested by setStreamVolume(). In this 540 // case, the new requested volume, stream type and device are stored in mPendingVolumeCommand 541 // and used later when/if disableSafeMediaVolume() is called. 542 private StreamVolumeCommand mPendingVolumeCommand; 543 544 private PowerManager.WakeLock mAudioEventWakeLock; 545 546 private final MediaFocusControl mMediaFocusControl; 547 548 // Reference to BluetoothA2dp to query for AbsoluteVolume. 549 private BluetoothA2dp mA2dp; 550 // lock always taken synchronized on mConnectedDevices 551 private final Object mA2dpAvrcpLock = new Object(); 552 // If absolute volume is supported in AVRCP device 553 private boolean mAvrcpAbsVolSupported = false; 554 555 private static Long mLastDeviceConnectMsgTime = new Long(0); 556 557 private NotificationManager mNm; 558 private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; 559 private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; 560 private long mLoweredFromNormalToVibrateTime; 561 562 // Intent "extra" data keys. 563 public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName"; 564 public static final String CONNECT_INTENT_KEY_STATE = "state"; 565 public static final String CONNECT_INTENT_KEY_ADDRESS = "address"; 566 public static final String CONNECT_INTENT_KEY_HAS_PLAYBACK = "hasPlayback"; 567 public static final String CONNECT_INTENT_KEY_HAS_CAPTURE = "hasCapture"; 568 public static final String CONNECT_INTENT_KEY_HAS_MIDI = "hasMIDI"; 569 public static final String CONNECT_INTENT_KEY_DEVICE_CLASS = "class"; 570 571 // Defines the format for the connection "address" for ALSA devices makeAlsaAddressString(int card, int device)572 public static String makeAlsaAddressString(int card, int device) { 573 return "card=" + card + ";device=" + device + ";"; 574 } 575 576 public static final class Lifecycle extends SystemService { 577 private AudioService mService; 578 Lifecycle(Context context)579 public Lifecycle(Context context) { 580 super(context); 581 mService = new AudioService(context); 582 } 583 584 @Override onStart()585 public void onStart() { 586 publishBinderService(Context.AUDIO_SERVICE, mService); 587 } 588 589 @Override onBootPhase(int phase)590 public void onBootPhase(int phase) { 591 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 592 mService.systemReady(); 593 } 594 } 595 } 596 597 /////////////////////////////////////////////////////////////////////////// 598 // Construction 599 /////////////////////////////////////////////////////////////////////////// 600 601 /** @hide */ AudioService(Context context)602 public AudioService(Context context) { 603 mContext = context; 604 mContentResolver = context.getContentResolver(); 605 mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 606 607 mPlatformType = AudioSystem.getPlatformType(context); 608 609 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 610 611 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 612 mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); 613 614 Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 615 mHasVibrator = vibrator == null ? false : vibrator.hasVibrator(); 616 617 // Initialize volume 618 int maxVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", 619 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]); 620 if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { 621 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxVolume; 622 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = (maxVolume * 3) / 4; 623 } 624 maxVolume = SystemProperties.getInt("ro.config.media_vol_steps", 625 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]); 626 if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { 627 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume; 628 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = (maxVolume * 3) / 4; 629 } 630 631 sSoundEffectVolumeDb = context.getResources().getInteger( 632 com.android.internal.R.integer.config_soundEffectVolumeDb); 633 634 mForcedUseForComm = AudioSystem.FORCE_NONE; 635 636 createAudioSystemThread(); 637 638 AudioSystem.setErrorCallback(mAudioSystemCallback); 639 640 boolean cameraSoundForced = readCameraSoundForced(); 641 mCameraSoundForced = new Boolean(cameraSoundForced); 642 sendMsg(mAudioHandler, 643 MSG_SET_FORCE_USE, 644 SENDMSG_QUEUE, 645 AudioSystem.FOR_SYSTEM, 646 cameraSoundForced ? 647 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 648 null, 649 0); 650 651 mSafeMediaVolumeState = new Integer(Settings.Global.getInt(mContentResolver, 652 Settings.Global.AUDIO_SAFE_VOLUME_STATE, 653 SAFE_MEDIA_VOLUME_NOT_CONFIGURED)); 654 // The default safe volume index read here will be replaced by the actual value when 655 // the mcc is read by onConfigureSafeVolume() 656 mSafeMediaVolumeIndex = mContext.getResources().getInteger( 657 com.android.internal.R.integer.config_safe_media_volume_index) * 10; 658 659 mUseFixedVolume = mContext.getResources().getBoolean( 660 com.android.internal.R.bool.config_useFixedVolume); 661 662 // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[] 663 // array initialized by updateStreamVolumeAlias() 664 updateStreamVolumeAlias(false /*updateVolumes*/, TAG); 665 readPersistedSettings(); 666 readUserRestrictions(); 667 mSettingsObserver = new SettingsObserver(); 668 createStreamStates(); 669 670 mMediaFocusControl = new MediaFocusControl(mContext); 671 672 readAndSetLowRamDevice(); 673 674 // Call setRingerModeInt() to apply correct mute 675 // state on streams affected by ringer mode. 676 mRingerModeMutedStreams = 0; 677 setRingerModeInt(getRingerModeInternal(), false); 678 679 // Register for device connection intent broadcasts. 680 IntentFilter intentFilter = 681 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 682 intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); 683 intentFilter.addAction(Intent.ACTION_DOCK_EVENT); 684 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 685 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 686 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 687 intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); 688 intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); 689 intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 690 intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 691 692 intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 693 // TODO merge orientation and rotation 694 mMonitorOrientation = SystemProperties.getBoolean("ro.audio.monitorOrientation", false); 695 if (mMonitorOrientation) { 696 Log.v(TAG, "monitoring device orientation"); 697 // initialize orientation in AudioSystem 698 setOrientationForAudioSystem(); 699 } 700 mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); 701 if (mMonitorRotation) { 702 RotationHelper.init(mContext, mAudioHandler); 703 } 704 705 context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null); 706 707 LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); 708 709 mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); 710 711 mRecordMonitor.initMonitor(); 712 } 713 systemReady()714 public void systemReady() { 715 sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 716 0, 0, null, 0); 717 } 718 onSystemReady()719 public void onSystemReady() { 720 mSystemReady = true; 721 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 722 0, 0, null, 0); 723 724 mScoConnectionState = AudioManager.SCO_AUDIO_STATE_ERROR; 725 resetBluetoothSco(); 726 getBluetoothHeadset(); 727 //FIXME: this is to maintain compatibility with deprecated intent 728 // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate. 729 Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED); 730 newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 731 AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 732 sendStickyBroadcastToAll(newIntent); 733 734 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 735 if (adapter != null) { 736 adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, 737 BluetoothProfile.A2DP); 738 } 739 740 mHdmiManager = 741 (HdmiControlManager) mContext.getSystemService(Context.HDMI_CONTROL_SERVICE); 742 if (mHdmiManager != null) { 743 synchronized (mHdmiManager) { 744 mHdmiTvClient = mHdmiManager.getTvClient(); 745 if (mHdmiTvClient != null) { 746 mFixedVolumeDevices &= ~AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER; 747 } 748 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); 749 mHdmiCecSink = false; 750 } 751 } 752 753 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 754 755 sendMsg(mAudioHandler, 756 MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED, 757 SENDMSG_REPLACE, 758 0, 759 0, 760 TAG, 761 SAFE_VOLUME_CONFIGURE_TIMEOUT_MS); 762 763 StreamOverride.init(mContext); 764 mControllerService.init(); 765 onIndicateSystemReady(); 766 } 767 onIndicateSystemReady()768 void onIndicateSystemReady() { 769 if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { 770 return; 771 } 772 sendMsg(mAudioHandler, 773 MSG_INDICATE_SYSTEM_READY, 774 SENDMSG_REPLACE, 775 0, 776 0, 777 null, 778 INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 779 } 780 onAudioServerDied()781 public void onAudioServerDied() { 782 if (!mSystemReady || 783 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { 784 Log.e(TAG, "Audioserver died."); 785 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, 786 null, 500); 787 return; 788 } 789 Log.e(TAG, "Audioserver started."); 790 791 // indicate to audio HAL that we start the reconfiguration phase after a media 792 // server crash 793 // Note that we only execute this when the media server 794 // process restarts after a crash, not the first time it is started. 795 AudioSystem.setParameters("restarting=true"); 796 797 readAndSetLowRamDevice(); 798 799 // Restore device connection states 800 synchronized (mConnectedDevices) { 801 for (int i = 0; i < mConnectedDevices.size(); i++) { 802 DeviceListSpec spec = mConnectedDevices.valueAt(i); 803 AudioSystem.setDeviceConnectionState( 804 spec.mDeviceType, 805 AudioSystem.DEVICE_STATE_AVAILABLE, 806 spec.mDeviceAddress, 807 spec.mDeviceName); 808 } 809 } 810 // Restore call state 811 AudioSystem.setPhoneState(mMode); 812 813 // Restore forced usage for communcations and record 814 AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm); 815 AudioSystem.setForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm); 816 AudioSystem.setForceUse(AudioSystem.FOR_SYSTEM, mCameraSoundForced ? 817 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE); 818 819 // Restore stream volumes 820 int numStreamTypes = AudioSystem.getNumStreamTypes(); 821 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 822 VolumeStreamState streamState = mStreamStates[streamType]; 823 AudioSystem.initStreamVolume( 824 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); 825 826 streamState.applyAllVolumes(); 827 } 828 829 // Restore mono mode 830 updateMasterMono(mContentResolver); 831 832 // Restore ringer mode 833 setRingerModeInt(getRingerModeInternal(), false); 834 835 // Reset device orientation (if monitored for this device) 836 if (mMonitorOrientation) { 837 setOrientationForAudioSystem(); 838 } 839 if (mMonitorRotation) { 840 RotationHelper.updateOrientation(); 841 } 842 843 synchronized (mBluetoothA2dpEnabledLock) { 844 AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, 845 mBluetoothA2dpEnabled ? 846 AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP); 847 } 848 849 synchronized (mSettingsLock) { 850 AudioSystem.setForceUse(AudioSystem.FOR_DOCK, 851 mDockAudioMediaEnabled ? 852 AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE); 853 sendEncodedSurroundMode(mContentResolver); 854 } 855 if (mHdmiManager != null) { 856 synchronized (mHdmiManager) { 857 if (mHdmiTvClient != null) { 858 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); 859 } 860 } 861 } 862 863 synchronized (mAudioPolicies) { 864 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 865 policy.connectMixes(); 866 } 867 } 868 869 onIndicateSystemReady(); 870 // indicate the end of reconfiguration phase to audio HAL 871 AudioSystem.setParameters("restarting=false"); 872 } 873 createAudioSystemThread()874 private void createAudioSystemThread() { 875 mAudioSystemThread = new AudioSystemThread(); 876 mAudioSystemThread.start(); 877 waitForAudioHandlerCreation(); 878 } 879 880 /** Waits for the volume handler to be created by the other thread. */ waitForAudioHandlerCreation()881 private void waitForAudioHandlerCreation() { 882 synchronized(this) { 883 while (mAudioHandler == null) { 884 try { 885 // Wait for mAudioHandler to be set by the other thread 886 wait(); 887 } catch (InterruptedException e) { 888 Log.e(TAG, "Interrupted while waiting on volume handler."); 889 } 890 } 891 } 892 } 893 checkAllAliasStreamVolumes()894 private void checkAllAliasStreamVolumes() { 895 synchronized (VolumeStreamState.class) { 896 int numStreamTypes = AudioSystem.getNumStreamTypes(); 897 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 898 if (streamType != mStreamVolumeAlias[streamType]) { 899 mStreamStates[streamType]. 900 setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], 901 TAG); 902 } 903 // apply stream volume 904 if (!mStreamStates[streamType].mIsMuted) { 905 mStreamStates[streamType].applyAllVolumes(); 906 } 907 } 908 } 909 } 910 checkAllFixedVolumeDevices()911 private void checkAllFixedVolumeDevices() 912 { 913 int numStreamTypes = AudioSystem.getNumStreamTypes(); 914 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 915 mStreamStates[streamType].checkFixedVolumeDevices(); 916 } 917 } 918 checkAllFixedVolumeDevices(int streamType)919 private void checkAllFixedVolumeDevices(int streamType) { 920 mStreamStates[streamType].checkFixedVolumeDevices(); 921 } 922 checkMuteAffectedStreams()923 private void checkMuteAffectedStreams() { 924 // any stream with a min level > 0 is not muteable by definition 925 for (int i = 0; i < mStreamStates.length; i++) { 926 final VolumeStreamState vss = mStreamStates[i]; 927 if (vss.mIndexMin > 0) { 928 mMuteAffectedStreams &= ~(1 << vss.mStreamType); 929 } 930 } 931 } 932 createStreamStates()933 private void createStreamStates() { 934 int numStreamTypes = AudioSystem.getNumStreamTypes(); 935 VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes]; 936 937 for (int i = 0; i < numStreamTypes; i++) { 938 streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[mStreamVolumeAlias[i]], i); 939 } 940 941 checkAllFixedVolumeDevices(); 942 checkAllAliasStreamVolumes(); 943 checkMuteAffectedStreams(); 944 } 945 dumpStreamStates(PrintWriter pw)946 private void dumpStreamStates(PrintWriter pw) { 947 pw.println("\nStream volumes (device: index)"); 948 int numStreamTypes = AudioSystem.getNumStreamTypes(); 949 for (int i = 0; i < numStreamTypes; i++) { 950 pw.println("- " + AudioSystem.STREAM_NAMES[i] + ":"); 951 mStreamStates[i].dump(pw); 952 pw.println(""); 953 } 954 pw.print("\n- mute affected streams = 0x"); 955 pw.println(Integer.toHexString(mMuteAffectedStreams)); 956 } 957 updateStreamVolumeAlias(boolean updateVolumes, String caller)958 private void updateStreamVolumeAlias(boolean updateVolumes, String caller) { 959 int dtmfStreamAlias; 960 961 switch (mPlatformType) { 962 case AudioSystem.PLATFORM_VOICE: 963 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE; 964 dtmfStreamAlias = AudioSystem.STREAM_RING; 965 break; 966 case AudioSystem.PLATFORM_TELEVISION: 967 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION; 968 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 969 break; 970 default: 971 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT; 972 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 973 } 974 975 if (isPlatformTelevision()) { 976 mRingerModeAffectedStreams = 0; 977 } else { 978 if (isInCommunication()) { 979 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL; 980 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 981 } else { 982 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 983 } 984 } 985 986 mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; 987 if (updateVolumes) { 988 mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias], 989 caller); 990 // apply stream mute states according to new value of mRingerModeAffectedStreams 991 setRingerModeInt(getRingerModeInternal(), false); 992 sendMsg(mAudioHandler, 993 MSG_SET_ALL_VOLUMES, 994 SENDMSG_QUEUE, 995 0, 996 0, 997 mStreamStates[AudioSystem.STREAM_DTMF], 0); 998 } 999 } 1000 readDockAudioSettings(ContentResolver cr)1001 private void readDockAudioSettings(ContentResolver cr) 1002 { 1003 mDockAudioMediaEnabled = Settings.Global.getInt( 1004 cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1; 1005 1006 sendMsg(mAudioHandler, 1007 MSG_SET_FORCE_USE, 1008 SENDMSG_QUEUE, 1009 AudioSystem.FOR_DOCK, 1010 mDockAudioMediaEnabled ? 1011 AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE, 1012 null, 1013 0); 1014 } 1015 1016 updateMasterMono(ContentResolver cr)1017 private void updateMasterMono(ContentResolver cr) 1018 { 1019 final boolean masterMono = System.getIntForUser( 1020 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1; 1021 if (DEBUG_VOL) { 1022 Log.d(TAG, String.format("Master mono %b", masterMono)); 1023 } 1024 AudioSystem.setMasterMono(masterMono); 1025 } 1026 sendEncodedSurroundMode(ContentResolver cr)1027 private void sendEncodedSurroundMode(ContentResolver cr) 1028 { 1029 int encodedSurroundMode = Settings.Global.getInt( 1030 cr, Settings.Global.ENCODED_SURROUND_OUTPUT, 1031 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 1032 sendEncodedSurroundMode(encodedSurroundMode); 1033 } 1034 sendEncodedSurroundMode(int encodedSurroundMode)1035 private void sendEncodedSurroundMode(int encodedSurroundMode) 1036 { 1037 // initialize to guaranteed bad value 1038 int forceSetting = AudioSystem.NUM_FORCE_CONFIG; 1039 switch (encodedSurroundMode) { 1040 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 1041 forceSetting = AudioSystem.FORCE_NONE; 1042 break; 1043 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 1044 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER; 1045 break; 1046 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 1047 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS; 1048 break; 1049 default: 1050 Log.e(TAG, "updateSurroundSoundSettings: illegal value " 1051 + encodedSurroundMode); 1052 break; 1053 } 1054 if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) { 1055 sendMsg(mAudioHandler, 1056 MSG_SET_FORCE_USE, 1057 SENDMSG_QUEUE, 1058 AudioSystem.FOR_ENCODED_SURROUND, 1059 forceSetting, 1060 null, 1061 0); 1062 } 1063 } 1064 readPersistedSettings()1065 private void readPersistedSettings() { 1066 final ContentResolver cr = mContentResolver; 1067 1068 int ringerModeFromSettings = 1069 Settings.Global.getInt( 1070 cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); 1071 int ringerMode = ringerModeFromSettings; 1072 // sanity check in case the settings are restored from a device with incompatible 1073 // ringer modes 1074 if (!isValidRingerMode(ringerMode)) { 1075 ringerMode = AudioManager.RINGER_MODE_NORMAL; 1076 } 1077 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 1078 ringerMode = AudioManager.RINGER_MODE_SILENT; 1079 } 1080 if (ringerMode != ringerModeFromSettings) { 1081 Settings.Global.putInt(cr, Settings.Global.MODE_RINGER, ringerMode); 1082 } 1083 if (mUseFixedVolume || isPlatformTelevision()) { 1084 ringerMode = AudioManager.RINGER_MODE_NORMAL; 1085 } 1086 synchronized(mSettingsLock) { 1087 mRingerMode = ringerMode; 1088 if (mRingerModeExternal == -1) { 1089 mRingerModeExternal = mRingerMode; 1090 } 1091 1092 // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting 1093 // are still needed while setVibrateSetting() and getVibrateSetting() are being 1094 // deprecated. 1095 mVibrateSetting = AudioSystem.getValueForVibrateSetting(0, 1096 AudioManager.VIBRATE_TYPE_NOTIFICATION, 1097 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 1098 : AudioManager.VIBRATE_SETTING_OFF); 1099 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, 1100 AudioManager.VIBRATE_TYPE_RINGER, 1101 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 1102 : AudioManager.VIBRATE_SETTING_OFF); 1103 1104 updateRingerModeAffectedStreams(); 1105 readDockAudioSettings(cr); 1106 sendEncodedSurroundMode(cr); 1107 } 1108 1109 mMuteAffectedStreams = System.getIntForUser(cr, 1110 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, 1111 UserHandle.USER_CURRENT); 1112 1113 updateMasterMono(cr); 1114 1115 // Each stream will read its own persisted settings 1116 1117 // Broadcast the sticky intents 1118 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal); 1119 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode); 1120 1121 // Broadcast vibrate settings 1122 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); 1123 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION); 1124 1125 // Load settings for the volume controller 1126 mVolumeController.loadSettings(cr); 1127 } 1128 readUserRestrictions()1129 private void readUserRestrictions() { 1130 final int currentUser = getCurrentUserId(); 1131 1132 // Check the current user restriction. 1133 boolean masterMute = mUserManagerInternal.getUserRestriction( 1134 currentUser, UserManager.DISALLOW_ADJUST_VOLUME); 1135 if (mUseFixedVolume) { 1136 masterMute = false; 1137 AudioSystem.setMasterVolume(1.0f); 1138 } 1139 if (DEBUG_VOL) { 1140 Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser)); 1141 } 1142 setSystemAudioMute(masterMute); 1143 AudioSystem.setMasterMute(masterMute); 1144 broadcastMasterMuteStatus(masterMute); 1145 1146 boolean microphoneMute = mUserManagerInternal.getUserRestriction( 1147 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE); 1148 if (DEBUG_VOL) { 1149 Log.d(TAG, String.format("Mic mute %s, user=%d", microphoneMute, currentUser)); 1150 } 1151 AudioSystem.muteMicrophone(microphoneMute); 1152 } 1153 rescaleIndex(int index, int srcStream, int dstStream)1154 private int rescaleIndex(int index, int srcStream, int dstStream) { 1155 return (index * mStreamStates[dstStream].getMaxIndex() + mStreamStates[srcStream].getMaxIndex() / 2) / mStreamStates[srcStream].getMaxIndex(); 1156 } 1157 1158 /////////////////////////////////////////////////////////////////////////// 1159 // IPC methods 1160 /////////////////////////////////////////////////////////////////////////// 1161 /** @see AudioManager#adjustVolume(int, int) */ adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller)1162 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 1163 String callingPackage, String caller) { 1164 adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage, 1165 caller, Binder.getCallingUid()); 1166 } 1167 adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller, int uid)1168 private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 1169 String callingPackage, String caller, int uid) { 1170 if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType 1171 + ", flags=" + flags + ", caller=" + caller); 1172 int streamType; 1173 boolean isMute = isMuteAdjust(direction); 1174 if (mVolumeControlStream != -1) { 1175 streamType = mVolumeControlStream; 1176 } else { 1177 streamType = getActiveStreamType(suggestedStreamType); 1178 } 1179 ensureValidStreamType(streamType); 1180 final int resolvedStream = mStreamVolumeAlias[streamType]; 1181 1182 // Play sounds on STREAM_RING only. 1183 if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && 1184 resolvedStream != AudioSystem.STREAM_RING) { 1185 flags &= ~AudioManager.FLAG_PLAY_SOUND; 1186 } 1187 1188 // For notifications/ring, show the ui before making any adjustments 1189 // Don't suppress mute/unmute requests 1190 if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) { 1191 direction = 0; 1192 flags &= ~AudioManager.FLAG_PLAY_SOUND; 1193 flags &= ~AudioManager.FLAG_VIBRATE; 1194 if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); 1195 } 1196 1197 adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid); 1198 } 1199 1200 /** @see AudioManager#adjustStreamVolume(int, int, int) */ adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)1201 public void adjustStreamVolume(int streamType, int direction, int flags, 1202 String callingPackage) { 1203 adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, 1204 Binder.getCallingUid()); 1205 } 1206 adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid)1207 private void adjustStreamVolume(int streamType, int direction, int flags, 1208 String callingPackage, String caller, int uid) { 1209 if (mUseFixedVolume) { 1210 return; 1211 } 1212 if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction 1213 + ", flags=" + flags + ", caller=" + caller); 1214 1215 ensureValidDirection(direction); 1216 ensureValidStreamType(streamType); 1217 1218 boolean isMuteAdjust = isMuteAdjust(direction); 1219 1220 if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { 1221 return; 1222 } 1223 1224 // use stream type alias here so that streams with same alias have the same behavior, 1225 // including with regard to silent mode control (e.g the use of STREAM_RING below and in 1226 // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION) 1227 int streamTypeAlias = mStreamVolumeAlias[streamType]; 1228 1229 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 1230 1231 final int device = getDeviceForStream(streamTypeAlias); 1232 1233 int aliasIndex = streamState.getIndex(device); 1234 boolean adjustVolume = true; 1235 int step; 1236 1237 // skip a2dp absolute volume control request when the device 1238 // is not an a2dp device 1239 if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 && 1240 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 1241 return; 1242 } 1243 1244 // If we are being called by the system (e.g. hardware keys) check for current user 1245 // so we handle user restrictions correctly. 1246 if (uid == android.os.Process.SYSTEM_UID) { 1247 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 1248 } 1249 if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) 1250 != AppOpsManager.MODE_ALLOWED) { 1251 return; 1252 } 1253 1254 // reset any pending volume command 1255 synchronized (mSafeMediaVolumeState) { 1256 mPendingVolumeCommand = null; 1257 } 1258 1259 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 1260 if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && 1261 ((device & mFixedVolumeDevices) != 0)) { 1262 flags |= AudioManager.FLAG_FIXED_VOLUME; 1263 1264 // Always toggle between max safe volume and 0 for fixed volume devices where safe 1265 // volume is enforced, and max and 0 for the others. 1266 // This is simulated by stepping by the full allowed volume range 1267 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && 1268 (device & mSafeMediaVolumeDevices) != 0) { 1269 step = mSafeMediaVolumeIndex; 1270 } else { 1271 step = streamState.getMaxIndex(); 1272 } 1273 if (aliasIndex != 0) { 1274 aliasIndex = step; 1275 } 1276 } else { 1277 // convert one UI step (+/-1) into a number of internal units on the stream alias 1278 step = rescaleIndex(10, streamType, streamTypeAlias); 1279 } 1280 1281 // If either the client forces allowing ringer modes for this adjustment, 1282 // or the stream type is one that is affected by ringer modes 1283 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 1284 (streamTypeAlias == getUiSoundsStreamType())) { 1285 int ringerMode = getRingerModeInternal(); 1286 // do not vibrate if already in vibrate mode 1287 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 1288 flags &= ~AudioManager.FLAG_VIBRATE; 1289 } 1290 // Check if the ringer mode handles this adjustment. If it does we don't 1291 // need to adjust the volume further. 1292 final int result = checkForRingerModeChange(aliasIndex, direction, step, 1293 streamState.mIsMuted, callingPackage, flags); 1294 adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; 1295 // If suppressing a volume adjustment in silent mode, display the UI hint 1296 if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { 1297 flags |= AudioManager.FLAG_SHOW_SILENT_HINT; 1298 } 1299 // If suppressing a volume down adjustment in vibrate mode, display the UI hint 1300 if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { 1301 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 1302 } 1303 } 1304 // If the ringermode is suppressing media, prevent changes 1305 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 1306 adjustVolume = false; 1307 } 1308 int oldIndex = mStreamStates[streamType].getIndex(device); 1309 1310 if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) { 1311 mAudioHandler.removeMessages(MSG_UNMUTE_STREAM); 1312 1313 // Check if volume update should be send to AVRCP 1314 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && 1315 (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && 1316 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 1317 synchronized (mA2dpAvrcpLock) { 1318 if (mA2dp != null && mAvrcpAbsVolSupported) { 1319 mA2dp.adjustAvrcpAbsoluteVolume(direction); 1320 } 1321 } 1322 } 1323 1324 if (isMuteAdjust) { 1325 boolean state; 1326 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) { 1327 state = !streamState.mIsMuted; 1328 } else { 1329 state = direction == AudioManager.ADJUST_MUTE; 1330 } 1331 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 1332 setSystemAudioMute(state); 1333 } 1334 for (int stream = 0; stream < mStreamStates.length; stream++) { 1335 if (streamTypeAlias == mStreamVolumeAlias[stream]) { 1336 if (!(readCameraSoundForced() 1337 && (mStreamStates[stream].getStreamType() 1338 == AudioSystem.STREAM_SYSTEM_ENFORCED))) { 1339 mStreamStates[stream].mute(state); 1340 } 1341 } 1342 } 1343 } else if ((direction == AudioManager.ADJUST_RAISE) && 1344 !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { 1345 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); 1346 mVolumeController.postDisplaySafeVolumeWarning(flags); 1347 } else if (streamState.adjustIndex(direction * step, device, caller) 1348 || streamState.mIsMuted) { 1349 // Post message to set system volume (it in turn will post a 1350 // message to persist). 1351 if (streamState.mIsMuted) { 1352 // Unmute the stream if it was previously muted 1353 if (direction == AudioManager.ADJUST_RAISE) { 1354 // unmute immediately for volume up 1355 streamState.mute(false); 1356 } else if (direction == AudioManager.ADJUST_LOWER) { 1357 if (mPlatformType == AudioSystem.PLATFORM_TELEVISION) { 1358 sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE, 1359 streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY); 1360 } 1361 } 1362 } 1363 sendMsg(mAudioHandler, 1364 MSG_SET_DEVICE_VOLUME, 1365 SENDMSG_QUEUE, 1366 device, 1367 0, 1368 streamState, 1369 0); 1370 } 1371 1372 // Check if volume update should be sent to Hdmi system audio. 1373 int newIndex = mStreamStates[streamType].getIndex(device); 1374 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 1375 setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags); 1376 } 1377 if (mHdmiManager != null) { 1378 synchronized (mHdmiManager) { 1379 // mHdmiCecSink true => mHdmiPlaybackClient != null 1380 if (mHdmiCecSink && 1381 streamTypeAlias == AudioSystem.STREAM_MUSIC && 1382 oldIndex != newIndex) { 1383 synchronized (mHdmiPlaybackClient) { 1384 int keyCode = (direction == -1) ? KeyEvent.KEYCODE_VOLUME_DOWN : 1385 KeyEvent.KEYCODE_VOLUME_UP; 1386 final long ident = Binder.clearCallingIdentity(); 1387 try { 1388 mHdmiPlaybackClient.sendKeyEvent(keyCode, true); 1389 mHdmiPlaybackClient.sendKeyEvent(keyCode, false); 1390 } finally { 1391 Binder.restoreCallingIdentity(ident); 1392 } 1393 } 1394 } 1395 } 1396 } 1397 } 1398 int index = mStreamStates[streamType].getIndex(device); 1399 sendVolumeUpdate(streamType, oldIndex, index, flags); 1400 } 1401 1402 // Called after a delay when volume down is pressed while muted onUnmuteStream(int stream, int flags)1403 private void onUnmuteStream(int stream, int flags) { 1404 VolumeStreamState streamState = mStreamStates[stream]; 1405 streamState.mute(false); 1406 1407 final int device = getDeviceForStream(stream); 1408 final int index = mStreamStates[stream].getIndex(device); 1409 sendVolumeUpdate(stream, index, index, flags); 1410 } 1411 setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags)1412 private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) { 1413 if (mHdmiManager == null 1414 || mHdmiTvClient == null 1415 || oldVolume == newVolume 1416 || (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0) return; 1417 1418 // Sets the audio volume of AVR when we are in system audio mode. The new volume info 1419 // is tranformed to HDMI-CEC commands and passed through CEC bus. 1420 synchronized (mHdmiManager) { 1421 if (!mHdmiSystemAudioSupported) return; 1422 synchronized (mHdmiTvClient) { 1423 final long token = Binder.clearCallingIdentity(); 1424 try { 1425 mHdmiTvClient.setSystemAudioVolume(oldVolume, newVolume, maxVolume); 1426 } finally { 1427 Binder.restoreCallingIdentity(token); 1428 } 1429 } 1430 } 1431 } 1432 1433 // StreamVolumeCommand contains the information needed to defer the process of 1434 // setStreamVolume() in case the user has to acknowledge the safe volume warning message. 1435 class StreamVolumeCommand { 1436 public final int mStreamType; 1437 public final int mIndex; 1438 public final int mFlags; 1439 public final int mDevice; 1440 StreamVolumeCommand(int streamType, int index, int flags, int device)1441 StreamVolumeCommand(int streamType, int index, int flags, int device) { 1442 mStreamType = streamType; 1443 mIndex = index; 1444 mFlags = flags; 1445 mDevice = device; 1446 } 1447 1448 @Override toString()1449 public String toString() { 1450 return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=") 1451 .append(mIndex).append(",flags=").append(mFlags).append(",device=") 1452 .append(mDevice).append('}').toString(); 1453 } 1454 }; 1455 getNewRingerMode(int stream, int index, int flags)1456 private int getNewRingerMode(int stream, int index, int flags) { 1457 // setting volume on ui sounds stream type also controls silent mode 1458 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 1459 (stream == getUiSoundsStreamType())) { 1460 int newRingerMode; 1461 if (index == 0) { 1462 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE 1463 : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT 1464 : AudioManager.RINGER_MODE_NORMAL; 1465 } else { 1466 newRingerMode = AudioManager.RINGER_MODE_NORMAL; 1467 } 1468 return newRingerMode; 1469 } 1470 return getRingerModeExternal(); 1471 } 1472 isAndroidNPlus(String caller)1473 private boolean isAndroidNPlus(String caller) { 1474 try { 1475 final ApplicationInfo applicationInfo = 1476 mContext.getPackageManager().getApplicationInfoAsUser( 1477 caller, 0, UserHandle.getUserId(Binder.getCallingUid())); 1478 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 1479 return true; 1480 } 1481 return false; 1482 } catch (PackageManager.NameNotFoundException e) { 1483 return true; 1484 } 1485 } 1486 wouldToggleZenMode(int newMode)1487 private boolean wouldToggleZenMode(int newMode) { 1488 if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT 1489 && newMode != AudioManager.RINGER_MODE_SILENT) { 1490 return true; 1491 } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT 1492 && newMode == AudioManager.RINGER_MODE_SILENT) { 1493 return true; 1494 } 1495 return false; 1496 } 1497 onSetStreamVolume(int streamType, int index, int flags, int device, String caller)1498 private void onSetStreamVolume(int streamType, int index, int flags, int device, 1499 String caller) { 1500 final int stream = mStreamVolumeAlias[streamType]; 1501 setStreamVolumeInt(stream, index, device, false, caller); 1502 // setting volume on ui sounds stream type also controls silent mode 1503 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 1504 (stream == getUiSoundsStreamType())) { 1505 setRingerMode(getNewRingerMode(stream, index, flags), 1506 TAG + ".onSetStreamVolume", false /*external*/); 1507 } 1508 // setting non-zero volume for a muted stream unmutes the stream and vice versa 1509 mStreamStates[stream].mute(index == 0); 1510 } 1511 1512 /** @see AudioManager#setStreamVolume(int, int, int) */ setStreamVolume(int streamType, int index, int flags, String callingPackage)1513 public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { 1514 setStreamVolume(streamType, index, flags, callingPackage, callingPackage, 1515 Binder.getCallingUid()); 1516 } 1517 setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid)1518 private void setStreamVolume(int streamType, int index, int flags, String callingPackage, 1519 String caller, int uid) { 1520 if (mUseFixedVolume) { 1521 return; 1522 } 1523 1524 ensureValidStreamType(streamType); 1525 int streamTypeAlias = mStreamVolumeAlias[streamType]; 1526 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 1527 1528 final int device = getDeviceForStream(streamType); 1529 int oldIndex; 1530 1531 // skip a2dp absolute volume control request when the device 1532 // is not an a2dp device 1533 if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 && 1534 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 1535 return; 1536 } 1537 // If we are being called by the system (e.g. hardware keys) check for current user 1538 // so we handle user restrictions correctly. 1539 if (uid == android.os.Process.SYSTEM_UID) { 1540 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 1541 } 1542 if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) 1543 != AppOpsManager.MODE_ALLOWED) { 1544 return; 1545 } 1546 1547 if (isAndroidNPlus(callingPackage) 1548 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) 1549 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { 1550 throw new SecurityException("Not allowed to change Do Not Disturb state"); 1551 } 1552 1553 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 1554 return; 1555 } 1556 1557 synchronized (mSafeMediaVolumeState) { 1558 // reset any pending volume command 1559 mPendingVolumeCommand = null; 1560 1561 oldIndex = streamState.getIndex(device); 1562 1563 index = rescaleIndex(index * 10, streamType, streamTypeAlias); 1564 1565 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && 1566 (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && 1567 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 1568 synchronized (mA2dpAvrcpLock) { 1569 if (mA2dp != null && mAvrcpAbsVolSupported) { 1570 mA2dp.setAvrcpAbsoluteVolume(index / 10); 1571 } 1572 } 1573 } 1574 1575 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 1576 setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags); 1577 } 1578 1579 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 1580 if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && 1581 ((device & mFixedVolumeDevices) != 0)) { 1582 flags |= AudioManager.FLAG_FIXED_VOLUME; 1583 1584 // volume is either 0 or max allowed for fixed volume devices 1585 if (index != 0) { 1586 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && 1587 (device & mSafeMediaVolumeDevices) != 0) { 1588 index = mSafeMediaVolumeIndex; 1589 } else { 1590 index = streamState.getMaxIndex(); 1591 } 1592 } 1593 } 1594 1595 if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { 1596 mVolumeController.postDisplaySafeVolumeWarning(flags); 1597 mPendingVolumeCommand = new StreamVolumeCommand( 1598 streamType, index, flags, device); 1599 } else { 1600 onSetStreamVolume(streamType, index, flags, device, caller); 1601 index = mStreamStates[streamType].getIndex(device); 1602 } 1603 } 1604 sendVolumeUpdate(streamType, oldIndex, index, flags); 1605 } 1606 1607 // No ringer affected streams can be changed in total silence mode except those that 1608 // will cause the device to exit total silence mode. volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)1609 private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { 1610 if (mNm.getZenMode() == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS 1611 && isStreamMutedByRingerMode(streamTypeAlias)) { 1612 if (!(((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 1613 (streamTypeAlias == getUiSoundsStreamType()))) { 1614 return false; 1615 } 1616 } 1617 return true; 1618 } 1619 1620 /** @see AudioManager#forceVolumeControlStream(int) */ forceVolumeControlStream(int streamType, IBinder cb)1621 public void forceVolumeControlStream(int streamType, IBinder cb) { 1622 synchronized(mForceControlStreamLock) { 1623 mVolumeControlStream = streamType; 1624 if (mVolumeControlStream == -1) { 1625 if (mForceControlStreamClient != null) { 1626 mForceControlStreamClient.release(); 1627 mForceControlStreamClient = null; 1628 } 1629 } else { 1630 mForceControlStreamClient = new ForceControlStreamClient(cb); 1631 } 1632 } 1633 } 1634 1635 private class ForceControlStreamClient implements IBinder.DeathRecipient { 1636 private IBinder mCb; // To be notified of client's death 1637 ForceControlStreamClient(IBinder cb)1638 ForceControlStreamClient(IBinder cb) { 1639 if (cb != null) { 1640 try { 1641 cb.linkToDeath(this, 0); 1642 } catch (RemoteException e) { 1643 // Client has died! 1644 Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); 1645 cb = null; 1646 } 1647 } 1648 mCb = cb; 1649 } 1650 binderDied()1651 public void binderDied() { 1652 synchronized(mForceControlStreamLock) { 1653 Log.w(TAG, "SCO client died"); 1654 if (mForceControlStreamClient != this) { 1655 Log.w(TAG, "unregistered control stream client died"); 1656 } else { 1657 mForceControlStreamClient = null; 1658 mVolumeControlStream = -1; 1659 } 1660 } 1661 } 1662 release()1663 public void release() { 1664 if (mCb != null) { 1665 mCb.unlinkToDeath(this, 0); 1666 mCb = null; 1667 } 1668 } 1669 } 1670 sendBroadcastToAll(Intent intent)1671 private void sendBroadcastToAll(Intent intent) { 1672 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1673 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1674 final long ident = Binder.clearCallingIdentity(); 1675 try { 1676 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 1677 } finally { 1678 Binder.restoreCallingIdentity(ident); 1679 } 1680 } 1681 sendStickyBroadcastToAll(Intent intent)1682 private void sendStickyBroadcastToAll(Intent intent) { 1683 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1684 final long ident = Binder.clearCallingIdentity(); 1685 try { 1686 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1687 } finally { 1688 Binder.restoreCallingIdentity(ident); 1689 } 1690 } 1691 getCurrentUserId()1692 private int getCurrentUserId() { 1693 final long ident = Binder.clearCallingIdentity(); 1694 try { 1695 UserInfo currentUser = ActivityManagerNative.getDefault().getCurrentUser(); 1696 return currentUser.id; 1697 } catch (RemoteException e) { 1698 // Activity manager not running, nothing we can do assume user 0. 1699 } finally { 1700 Binder.restoreCallingIdentity(ident); 1701 } 1702 return UserHandle.USER_SYSTEM; 1703 } 1704 1705 // UI update and Broadcast Intent sendVolumeUpdate(int streamType, int oldIndex, int index, int flags)1706 private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) { 1707 streamType = mStreamVolumeAlias[streamType]; 1708 1709 if (streamType == AudioSystem.STREAM_MUSIC) { 1710 flags = updateFlagsForSystemAudio(flags); 1711 } 1712 mVolumeController.postVolumeChanged(streamType, flags); 1713 } 1714 1715 // If Hdmi-CEC system audio mode is on, we show volume bar only when TV 1716 // receives volume notification from Audio Receiver. updateFlagsForSystemAudio(int flags)1717 private int updateFlagsForSystemAudio(int flags) { 1718 if (mHdmiTvClient != null) { 1719 synchronized (mHdmiTvClient) { 1720 if (mHdmiSystemAudioSupported && 1721 ((flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0)) { 1722 flags &= ~AudioManager.FLAG_SHOW_UI; 1723 } 1724 } 1725 } 1726 return flags; 1727 } 1728 1729 // UI update and Broadcast Intent sendMasterMuteUpdate(boolean muted, int flags)1730 private void sendMasterMuteUpdate(boolean muted, int flags) { 1731 mVolumeController.postMasterMuteChanged(updateFlagsForSystemAudio(flags)); 1732 broadcastMasterMuteStatus(muted); 1733 } 1734 broadcastMasterMuteStatus(boolean muted)1735 private void broadcastMasterMuteStatus(boolean muted) { 1736 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); 1737 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted); 1738 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 1739 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 1740 sendStickyBroadcastToAll(intent); 1741 } 1742 1743 /** 1744 * Sets the stream state's index, and posts a message to set system volume. 1745 * This will not call out to the UI. Assumes a valid stream type. 1746 * 1747 * @param streamType Type of the stream 1748 * @param index Desired volume index of the stream 1749 * @param device the device whose volume must be changed 1750 * @param force If true, set the volume even if the desired volume is same 1751 * as the current volume. 1752 */ setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller)1753 private void setStreamVolumeInt(int streamType, 1754 int index, 1755 int device, 1756 boolean force, 1757 String caller) { 1758 VolumeStreamState streamState = mStreamStates[streamType]; 1759 1760 if (streamState.setIndex(index, device, caller) || force) { 1761 // Post message to set system volume (it in turn will post a message 1762 // to persist). 1763 sendMsg(mAudioHandler, 1764 MSG_SET_DEVICE_VOLUME, 1765 SENDMSG_QUEUE, 1766 device, 1767 0, 1768 streamState, 1769 0); 1770 } 1771 } 1772 setSystemAudioMute(boolean state)1773 private void setSystemAudioMute(boolean state) { 1774 if (mHdmiManager == null || mHdmiTvClient == null) return; 1775 synchronized (mHdmiManager) { 1776 if (!mHdmiSystemAudioSupported) return; 1777 synchronized (mHdmiTvClient) { 1778 final long token = Binder.clearCallingIdentity(); 1779 try { 1780 mHdmiTvClient.setSystemAudioMute(state); 1781 } finally { 1782 Binder.restoreCallingIdentity(token); 1783 } 1784 } 1785 } 1786 } 1787 1788 /** get stream mute state. */ isStreamMute(int streamType)1789 public boolean isStreamMute(int streamType) { 1790 if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 1791 streamType = getActiveStreamType(streamType); 1792 } 1793 synchronized (VolumeStreamState.class) { 1794 return mStreamStates[streamType].mIsMuted; 1795 } 1796 } 1797 1798 private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient { 1799 private IBinder mICallback; // To be notified of client's death 1800 RmtSbmxFullVolDeathHandler(IBinder cb)1801 RmtSbmxFullVolDeathHandler(IBinder cb) { 1802 mICallback = cb; 1803 try { 1804 cb.linkToDeath(this, 0/*flags*/); 1805 } catch (RemoteException e) { 1806 Log.e(TAG, "can't link to death", e); 1807 } 1808 } 1809 isHandlerFor(IBinder cb)1810 boolean isHandlerFor(IBinder cb) { 1811 return mICallback.equals(cb); 1812 } 1813 forget()1814 void forget() { 1815 try { 1816 mICallback.unlinkToDeath(this, 0/*flags*/); 1817 } catch (NoSuchElementException e) { 1818 Log.e(TAG, "error unlinking to death", e); 1819 } 1820 } 1821 binderDied()1822 public void binderDied() { 1823 Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback); 1824 forceRemoteSubmixFullVolume(false, mICallback); 1825 } 1826 } 1827 1828 /** 1829 * call must be synchronized on mRmtSbmxFullVolDeathHandlers 1830 * @return true if there is a registered death handler, false otherwise */ discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)1831 private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 1832 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 1833 while (it.hasNext()) { 1834 final RmtSbmxFullVolDeathHandler handler = it.next(); 1835 if (handler.isHandlerFor(cb)) { 1836 handler.forget(); 1837 mRmtSbmxFullVolDeathHandlers.remove(handler); 1838 return true; 1839 } 1840 } 1841 return false; 1842 } 1843 1844 /** call synchronized on mRmtSbmxFullVolDeathHandlers */ hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)1845 private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 1846 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 1847 while (it.hasNext()) { 1848 if (it.next().isHandlerFor(cb)) { 1849 return true; 1850 } 1851 } 1852 return false; 1853 } 1854 1855 private int mRmtSbmxFullVolRefCount = 0; 1856 private ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers = 1857 new ArrayList<RmtSbmxFullVolDeathHandler>(); 1858 forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)1859 public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) { 1860 if (cb == null) { 1861 return; 1862 } 1863 if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 1864 android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) { 1865 Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT"); 1866 return; 1867 } 1868 synchronized(mRmtSbmxFullVolDeathHandlers) { 1869 boolean applyRequired = false; 1870 if (startForcing) { 1871 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { 1872 mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); 1873 if (mRmtSbmxFullVolRefCount == 0) { 1874 mFullVolumeDevices |= AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 1875 mFixedVolumeDevices |= AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 1876 applyRequired = true; 1877 } 1878 mRmtSbmxFullVolRefCount++; 1879 } 1880 } else { 1881 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { 1882 mRmtSbmxFullVolRefCount--; 1883 if (mRmtSbmxFullVolRefCount == 0) { 1884 mFullVolumeDevices &= ~AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 1885 mFixedVolumeDevices &= ~AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 1886 applyRequired = true; 1887 } 1888 } 1889 } 1890 if (applyRequired) { 1891 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX 1892 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC); 1893 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes(); 1894 } 1895 } 1896 } 1897 setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId)1898 private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, 1899 int userId) { 1900 // If we are being called by the system check for user we are going to change 1901 // so we handle user restrictions correctly. 1902 if (uid == android.os.Process.SYSTEM_UID) { 1903 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 1904 } 1905 // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. 1906 if (!mute && mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage) 1907 != AppOpsManager.MODE_ALLOWED) { 1908 return; 1909 } 1910 if (userId != UserHandle.getCallingUserId() && 1911 mContext.checkCallingOrSelfPermission( 1912 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 1913 != PackageManager.PERMISSION_GRANTED) { 1914 return; 1915 } 1916 setMasterMuteInternalNoCallerCheck(mute, flags, userId); 1917 } 1918 setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)1919 private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) { 1920 if (DEBUG_VOL) { 1921 Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId)); 1922 } 1923 if (mUseFixedVolume) { 1924 return; // If using fixed volume, we don't mute. 1925 } 1926 if (getCurrentUserId() == userId) { 1927 if (mute != AudioSystem.getMasterMute()) { 1928 setSystemAudioMute(mute); 1929 AudioSystem.setMasterMute(mute); 1930 sendMasterMuteUpdate(mute, flags); 1931 1932 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); 1933 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, mute); 1934 sendBroadcastToAll(intent); 1935 } 1936 } 1937 } 1938 1939 /** get master mute state. */ isMasterMute()1940 public boolean isMasterMute() { 1941 return AudioSystem.getMasterMute(); 1942 } 1943 setMasterMute(boolean mute, int flags, String callingPackage, int userId)1944 public void setMasterMute(boolean mute, int flags, String callingPackage, int userId) { 1945 setMasterMuteInternal(mute, flags, callingPackage, Binder.getCallingUid(), 1946 userId); 1947 } 1948 1949 /** @see AudioManager#getStreamVolume(int) */ getStreamVolume(int streamType)1950 public int getStreamVolume(int streamType) { 1951 ensureValidStreamType(streamType); 1952 int device = getDeviceForStream(streamType); 1953 synchronized (VolumeStreamState.class) { 1954 int index = mStreamStates[streamType].getIndex(device); 1955 1956 // by convention getStreamVolume() returns 0 when a stream is muted. 1957 if (mStreamStates[streamType].mIsMuted) { 1958 index = 0; 1959 } 1960 if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && 1961 (device & mFixedVolumeDevices) != 0) { 1962 index = mStreamStates[streamType].getMaxIndex(); 1963 } 1964 return (index + 5) / 10; 1965 } 1966 } 1967 1968 /** @see AudioManager#getStreamMaxVolume(int) */ getStreamMaxVolume(int streamType)1969 public int getStreamMaxVolume(int streamType) { 1970 ensureValidStreamType(streamType); 1971 return (mStreamStates[streamType].getMaxIndex() + 5) / 10; 1972 } 1973 1974 /** @see AudioManager#getStreamMinVolume(int) */ getStreamMinVolume(int streamType)1975 public int getStreamMinVolume(int streamType) { 1976 ensureValidStreamType(streamType); 1977 return (mStreamStates[streamType].getMinIndex() + 5) / 10; 1978 } 1979 1980 /** Get last audible volume before stream was muted. */ getLastAudibleStreamVolume(int streamType)1981 public int getLastAudibleStreamVolume(int streamType) { 1982 ensureValidStreamType(streamType); 1983 int device = getDeviceForStream(streamType); 1984 return (mStreamStates[streamType].getIndex(device) + 5) / 10; 1985 } 1986 1987 /** @see AudioManager#getUiSoundsStreamType() */ getUiSoundsStreamType()1988 public int getUiSoundsStreamType() { 1989 return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 1990 } 1991 1992 /** @see AudioManager#setMicrophoneMute(boolean) */ 1993 @Override setMicrophoneMute(boolean on, String callingPackage, int userId)1994 public void setMicrophoneMute(boolean on, String callingPackage, int userId) { 1995 // If we are being called by the system check for user we are going to change 1996 // so we handle user restrictions correctly. 1997 int uid = Binder.getCallingUid(); 1998 if (uid == android.os.Process.SYSTEM_UID) { 1999 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 2000 } 2001 // If OP_MUTE_MICROPHONE is set, disallow unmuting. 2002 if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage) 2003 != AppOpsManager.MODE_ALLOWED) { 2004 return; 2005 } 2006 if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 2007 return; 2008 } 2009 if (userId != UserHandle.getCallingUserId() && 2010 mContext.checkCallingOrSelfPermission( 2011 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 2012 != PackageManager.PERMISSION_GRANTED) { 2013 return; 2014 } 2015 setMicrophoneMuteNoCallerCheck(on, userId); 2016 } 2017 setMicrophoneMuteNoCallerCheck(boolean on, int userId)2018 private void setMicrophoneMuteNoCallerCheck(boolean on, int userId) { 2019 if (DEBUG_VOL) { 2020 Log.d(TAG, String.format("Mic mute %s, user=%d", on, userId)); 2021 } 2022 // If mute is for current user actually mute, else just persist the setting 2023 // which will be loaded on user switch. 2024 if (getCurrentUserId() == userId) { 2025 AudioSystem.muteMicrophone(on); 2026 } 2027 // Post a persist microphone msg. 2028 } 2029 2030 @Override getRingerModeExternal()2031 public int getRingerModeExternal() { 2032 synchronized(mSettingsLock) { 2033 return mRingerModeExternal; 2034 } 2035 } 2036 2037 @Override getRingerModeInternal()2038 public int getRingerModeInternal() { 2039 synchronized(mSettingsLock) { 2040 return mRingerMode; 2041 } 2042 } 2043 ensureValidRingerMode(int ringerMode)2044 private void ensureValidRingerMode(int ringerMode) { 2045 if (!isValidRingerMode(ringerMode)) { 2046 throw new IllegalArgumentException("Bad ringer mode " + ringerMode); 2047 } 2048 } 2049 2050 /** @see AudioManager#isValidRingerMode(int) */ isValidRingerMode(int ringerMode)2051 public boolean isValidRingerMode(int ringerMode) { 2052 return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; 2053 } 2054 setRingerModeExternal(int ringerMode, String caller)2055 public void setRingerModeExternal(int ringerMode, String caller) { 2056 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 2057 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) { 2058 throw new SecurityException("Not allowed to change Do Not Disturb state"); 2059 } 2060 2061 setRingerMode(ringerMode, caller, true /*external*/); 2062 } 2063 setRingerModeInternal(int ringerMode, String caller)2064 public void setRingerModeInternal(int ringerMode, String caller) { 2065 enforceVolumeController("setRingerModeInternal"); 2066 setRingerMode(ringerMode, caller, false /*external*/); 2067 } 2068 setRingerMode(int ringerMode, String caller, boolean external)2069 private void setRingerMode(int ringerMode, String caller, boolean external) { 2070 if (mUseFixedVolume || isPlatformTelevision()) { 2071 return; 2072 } 2073 if (caller == null || caller.length() == 0) { 2074 throw new IllegalArgumentException("Bad caller: " + caller); 2075 } 2076 ensureValidRingerMode(ringerMode); 2077 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 2078 ringerMode = AudioManager.RINGER_MODE_SILENT; 2079 } 2080 final long identity = Binder.clearCallingIdentity(); 2081 try { 2082 synchronized (mSettingsLock) { 2083 final int ringerModeInternal = getRingerModeInternal(); 2084 final int ringerModeExternal = getRingerModeExternal(); 2085 if (external) { 2086 setRingerModeExt(ringerMode); 2087 if (mRingerModeDelegate != null) { 2088 ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, 2089 ringerMode, caller, ringerModeInternal, mVolumePolicy); 2090 } 2091 if (ringerMode != ringerModeInternal) { 2092 setRingerModeInt(ringerMode, true /*persist*/); 2093 } 2094 } else /*internal*/ { 2095 if (ringerMode != ringerModeInternal) { 2096 setRingerModeInt(ringerMode, true /*persist*/); 2097 } 2098 if (mRingerModeDelegate != null) { 2099 ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, 2100 ringerMode, caller, ringerModeExternal, mVolumePolicy); 2101 } 2102 setRingerModeExt(ringerMode); 2103 } 2104 } 2105 } finally { 2106 Binder.restoreCallingIdentity(identity); 2107 } 2108 } 2109 setRingerModeExt(int ringerMode)2110 private void setRingerModeExt(int ringerMode) { 2111 synchronized(mSettingsLock) { 2112 if (ringerMode == mRingerModeExternal) return; 2113 mRingerModeExternal = ringerMode; 2114 } 2115 // Send sticky broadcast 2116 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode); 2117 } 2118 muteRingerModeStreams()2119 private void muteRingerModeStreams() { 2120 // Mute stream if not previously muted by ringer mode and ringer mode 2121 // is not RINGER_MODE_NORMAL and stream is affected by ringer mode. 2122 // Unmute stream if previously muted by ringer mode and ringer mode 2123 // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. 2124 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2125 final boolean ringerModeMute = mRingerMode == AudioManager.RINGER_MODE_VIBRATE 2126 || mRingerMode == AudioManager.RINGER_MODE_SILENT; 2127 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 2128 final boolean isMuted = isStreamMutedByRingerMode(streamType); 2129 final boolean shouldMute = ringerModeMute && isStreamAffectedByRingerMode(streamType); 2130 if (isMuted == shouldMute) continue; 2131 if (!shouldMute) { 2132 // unmute 2133 // ring and notifications volume should never be 0 when not silenced 2134 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) { 2135 synchronized (VolumeStreamState.class) { 2136 final VolumeStreamState vss = mStreamStates[streamType]; 2137 for (int i = 0; i < vss.mIndexMap.size(); i++) { 2138 int device = vss.mIndexMap.keyAt(i); 2139 int value = vss.mIndexMap.valueAt(i); 2140 if (value == 0) { 2141 vss.setIndex(10, device, TAG); 2142 } 2143 } 2144 // Persist volume for stream ring when it is changed here 2145 final int device = getDeviceForStream(streamType); 2146 sendMsg(mAudioHandler, 2147 MSG_PERSIST_VOLUME, 2148 SENDMSG_QUEUE, 2149 device, 2150 0, 2151 mStreamStates[streamType], 2152 PERSIST_DELAY); 2153 } 2154 } 2155 mStreamStates[streamType].mute(false); 2156 mRingerModeMutedStreams &= ~(1 << streamType); 2157 } else { 2158 // mute 2159 mStreamStates[streamType].mute(true); 2160 mRingerModeMutedStreams |= (1 << streamType); 2161 } 2162 } 2163 } 2164 setRingerModeInt(int ringerMode, boolean persist)2165 private void setRingerModeInt(int ringerMode, boolean persist) { 2166 final boolean change; 2167 synchronized(mSettingsLock) { 2168 change = mRingerMode != ringerMode; 2169 mRingerMode = ringerMode; 2170 } 2171 2172 muteRingerModeStreams(); 2173 2174 // Post a persist ringer mode msg 2175 if (persist) { 2176 sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, 2177 SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY); 2178 } 2179 if (change) { 2180 // Send sticky broadcast 2181 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode); 2182 } 2183 } 2184 2185 /** @see AudioManager#shouldVibrate(int) */ shouldVibrate(int vibrateType)2186 public boolean shouldVibrate(int vibrateType) { 2187 if (!mHasVibrator) return false; 2188 2189 switch (getVibrateSetting(vibrateType)) { 2190 2191 case AudioManager.VIBRATE_SETTING_ON: 2192 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT; 2193 2194 case AudioManager.VIBRATE_SETTING_ONLY_SILENT: 2195 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE; 2196 2197 case AudioManager.VIBRATE_SETTING_OFF: 2198 // return false, even for incoming calls 2199 return false; 2200 2201 default: 2202 return false; 2203 } 2204 } 2205 2206 /** @see AudioManager#getVibrateSetting(int) */ getVibrateSetting(int vibrateType)2207 public int getVibrateSetting(int vibrateType) { 2208 if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF; 2209 return (mVibrateSetting >> (vibrateType * 2)) & 3; 2210 } 2211 2212 /** @see AudioManager#setVibrateSetting(int, int) */ setVibrateSetting(int vibrateType, int vibrateSetting)2213 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 2214 2215 if (!mHasVibrator) return; 2216 2217 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType, 2218 vibrateSetting); 2219 2220 // Broadcast change 2221 broadcastVibrateSetting(vibrateType); 2222 2223 } 2224 2225 private class SetModeDeathHandler implements IBinder.DeathRecipient { 2226 private IBinder mCb; // To be notified of client's death 2227 private int mPid; 2228 private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client 2229 SetModeDeathHandler(IBinder cb, int pid)2230 SetModeDeathHandler(IBinder cb, int pid) { 2231 mCb = cb; 2232 mPid = pid; 2233 } 2234 binderDied()2235 public void binderDied() { 2236 int newModeOwnerPid = 0; 2237 synchronized(mSetModeDeathHandlers) { 2238 Log.w(TAG, "setMode() client died"); 2239 int index = mSetModeDeathHandlers.indexOf(this); 2240 if (index < 0) { 2241 Log.w(TAG, "unregistered setMode() client died"); 2242 } else { 2243 newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, TAG); 2244 } 2245 } 2246 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all 2247 // SCO connections not started by the application changing the mode 2248 if (newModeOwnerPid != 0) { 2249 final long ident = Binder.clearCallingIdentity(); 2250 disconnectBluetoothSco(newModeOwnerPid); 2251 Binder.restoreCallingIdentity(ident); 2252 } 2253 } 2254 getPid()2255 public int getPid() { 2256 return mPid; 2257 } 2258 setMode(int mode)2259 public void setMode(int mode) { 2260 mMode = mode; 2261 } 2262 getMode()2263 public int getMode() { 2264 return mMode; 2265 } 2266 getBinder()2267 public IBinder getBinder() { 2268 return mCb; 2269 } 2270 } 2271 2272 /** @see AudioManager#setMode(int) */ setMode(int mode, IBinder cb, String callingPackage)2273 public void setMode(int mode, IBinder cb, String callingPackage) { 2274 if (DEBUG_MODE) { Log.v(TAG, "setMode(mode=" + mode + ", callingPackage=" + callingPackage + ")"); } 2275 if (!checkAudioSettingsPermission("setMode()")) { 2276 return; 2277 } 2278 2279 if ( (mode == AudioSystem.MODE_IN_CALL) && 2280 (mContext.checkCallingOrSelfPermission( 2281 android.Manifest.permission.MODIFY_PHONE_STATE) 2282 != PackageManager.PERMISSION_GRANTED)) { 2283 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(MODE_IN_CALL) from pid=" 2284 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 2285 return; 2286 } 2287 2288 if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { 2289 return; 2290 } 2291 2292 int newModeOwnerPid = 0; 2293 synchronized(mSetModeDeathHandlers) { 2294 if (mode == AudioSystem.MODE_CURRENT) { 2295 mode = mMode; 2296 } 2297 newModeOwnerPid = setModeInt(mode, cb, Binder.getCallingPid(), callingPackage); 2298 } 2299 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all 2300 // SCO connections not started by the application changing the mode 2301 if (newModeOwnerPid != 0) { 2302 disconnectBluetoothSco(newModeOwnerPid); 2303 } 2304 } 2305 2306 // must be called synchronized on mSetModeDeathHandlers 2307 // setModeInt() returns a valid PID if the audio mode was successfully set to 2308 // any mode other than NORMAL. setModeInt(int mode, IBinder cb, int pid, String caller)2309 private int setModeInt(int mode, IBinder cb, int pid, String caller) { 2310 if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", caller=" 2311 + caller + ")"); } 2312 int newModeOwnerPid = 0; 2313 if (cb == null) { 2314 Log.e(TAG, "setModeInt() called with null binder"); 2315 return newModeOwnerPid; 2316 } 2317 2318 SetModeDeathHandler hdlr = null; 2319 Iterator iter = mSetModeDeathHandlers.iterator(); 2320 while (iter.hasNext()) { 2321 SetModeDeathHandler h = (SetModeDeathHandler)iter.next(); 2322 if (h.getPid() == pid) { 2323 hdlr = h; 2324 // Remove from client list so that it is re-inserted at top of list 2325 iter.remove(); 2326 hdlr.getBinder().unlinkToDeath(hdlr, 0); 2327 break; 2328 } 2329 } 2330 int status = AudioSystem.AUDIO_STATUS_OK; 2331 do { 2332 if (mode == AudioSystem.MODE_NORMAL) { 2333 // get new mode from client at top the list if any 2334 if (!mSetModeDeathHandlers.isEmpty()) { 2335 hdlr = mSetModeDeathHandlers.get(0); 2336 cb = hdlr.getBinder(); 2337 mode = hdlr.getMode(); 2338 if (DEBUG_MODE) { 2339 Log.w(TAG, " using mode=" + mode + " instead due to death hdlr at pid=" 2340 + hdlr.mPid); 2341 } 2342 } 2343 } else { 2344 if (hdlr == null) { 2345 hdlr = new SetModeDeathHandler(cb, pid); 2346 } 2347 // Register for client death notification 2348 try { 2349 cb.linkToDeath(hdlr, 0); 2350 } catch (RemoteException e) { 2351 // Client has died! 2352 Log.w(TAG, "setMode() could not link to "+cb+" binder death"); 2353 } 2354 2355 // Last client to call setMode() is always at top of client list 2356 // as required by SetModeDeathHandler.binderDied() 2357 mSetModeDeathHandlers.add(0, hdlr); 2358 hdlr.setMode(mode); 2359 } 2360 2361 if (mode != mMode) { 2362 status = AudioSystem.setPhoneState(mode); 2363 if (status == AudioSystem.AUDIO_STATUS_OK) { 2364 if (DEBUG_MODE) { Log.v(TAG, " mode successfully set to " + mode); } 2365 mMode = mode; 2366 } else { 2367 if (hdlr != null) { 2368 mSetModeDeathHandlers.remove(hdlr); 2369 cb.unlinkToDeath(hdlr, 0); 2370 } 2371 // force reading new top of mSetModeDeathHandlers stack 2372 if (DEBUG_MODE) { Log.w(TAG, " mode set to MODE_NORMAL after phoneState pb"); } 2373 mode = AudioSystem.MODE_NORMAL; 2374 } 2375 } else { 2376 status = AudioSystem.AUDIO_STATUS_OK; 2377 } 2378 } while (status != AudioSystem.AUDIO_STATUS_OK && !mSetModeDeathHandlers.isEmpty()); 2379 2380 if (status == AudioSystem.AUDIO_STATUS_OK) { 2381 if (mode != AudioSystem.MODE_NORMAL) { 2382 if (mSetModeDeathHandlers.isEmpty()) { 2383 Log.e(TAG, "setMode() different from MODE_NORMAL with empty mode client stack"); 2384 } else { 2385 newModeOwnerPid = mSetModeDeathHandlers.get(0).getPid(); 2386 } 2387 } 2388 int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); 2389 int device = getDeviceForStream(streamType); 2390 int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device); 2391 setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, caller); 2392 2393 updateStreamVolumeAlias(true /*updateVolumes*/, caller); 2394 } 2395 return newModeOwnerPid; 2396 } 2397 2398 /** @see AudioManager#getMode() */ getMode()2399 public int getMode() { 2400 return mMode; 2401 } 2402 2403 //========================================================================================== 2404 // Sound Effects 2405 //========================================================================================== 2406 2407 private static final String TAG_AUDIO_ASSETS = "audio_assets"; 2408 private static final String ATTR_VERSION = "version"; 2409 private static final String TAG_GROUP = "group"; 2410 private static final String ATTR_GROUP_NAME = "name"; 2411 private static final String TAG_ASSET = "asset"; 2412 private static final String ATTR_ASSET_ID = "id"; 2413 private static final String ATTR_ASSET_FILE = "file"; 2414 2415 private static final String ASSET_FILE_VERSION = "1.0"; 2416 private static final String GROUP_TOUCH_SOUNDS = "touch_sounds"; 2417 2418 private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000; 2419 2420 class LoadSoundEffectReply { 2421 public int mStatus = 1; 2422 }; 2423 loadTouchSoundAssetDefaults()2424 private void loadTouchSoundAssetDefaults() { 2425 SOUND_EFFECT_FILES.add("Effect_Tick.ogg"); 2426 for (int i = 0; i < AudioManager.NUM_SOUND_EFFECTS; i++) { 2427 SOUND_EFFECT_FILES_MAP[i][0] = 0; 2428 SOUND_EFFECT_FILES_MAP[i][1] = -1; 2429 } 2430 } 2431 loadTouchSoundAssets()2432 private void loadTouchSoundAssets() { 2433 XmlResourceParser parser = null; 2434 2435 // only load assets once. 2436 if (!SOUND_EFFECT_FILES.isEmpty()) { 2437 return; 2438 } 2439 2440 loadTouchSoundAssetDefaults(); 2441 2442 try { 2443 parser = mContext.getResources().getXml(com.android.internal.R.xml.audio_assets); 2444 2445 XmlUtils.beginDocument(parser, TAG_AUDIO_ASSETS); 2446 String version = parser.getAttributeValue(null, ATTR_VERSION); 2447 boolean inTouchSoundsGroup = false; 2448 2449 if (ASSET_FILE_VERSION.equals(version)) { 2450 while (true) { 2451 XmlUtils.nextElement(parser); 2452 String element = parser.getName(); 2453 if (element == null) { 2454 break; 2455 } 2456 if (element.equals(TAG_GROUP)) { 2457 String name = parser.getAttributeValue(null, ATTR_GROUP_NAME); 2458 if (GROUP_TOUCH_SOUNDS.equals(name)) { 2459 inTouchSoundsGroup = true; 2460 break; 2461 } 2462 } 2463 } 2464 while (inTouchSoundsGroup) { 2465 XmlUtils.nextElement(parser); 2466 String element = parser.getName(); 2467 if (element == null) { 2468 break; 2469 } 2470 if (element.equals(TAG_ASSET)) { 2471 String id = parser.getAttributeValue(null, ATTR_ASSET_ID); 2472 String file = parser.getAttributeValue(null, ATTR_ASSET_FILE); 2473 int fx; 2474 2475 try { 2476 Field field = AudioManager.class.getField(id); 2477 fx = field.getInt(null); 2478 } catch (Exception e) { 2479 Log.w(TAG, "Invalid touch sound ID: "+id); 2480 continue; 2481 } 2482 2483 int i = SOUND_EFFECT_FILES.indexOf(file); 2484 if (i == -1) { 2485 i = SOUND_EFFECT_FILES.size(); 2486 SOUND_EFFECT_FILES.add(file); 2487 } 2488 SOUND_EFFECT_FILES_MAP[fx][0] = i; 2489 } else { 2490 break; 2491 } 2492 } 2493 } 2494 } catch (Resources.NotFoundException e) { 2495 Log.w(TAG, "audio assets file not found", e); 2496 } catch (XmlPullParserException e) { 2497 Log.w(TAG, "XML parser exception reading touch sound assets", e); 2498 } catch (IOException e) { 2499 Log.w(TAG, "I/O exception reading touch sound assets", e); 2500 } finally { 2501 if (parser != null) { 2502 parser.close(); 2503 } 2504 } 2505 } 2506 2507 /** @see AudioManager#playSoundEffect(int) */ playSoundEffect(int effectType)2508 public void playSoundEffect(int effectType) { 2509 playSoundEffectVolume(effectType, -1.0f); 2510 } 2511 2512 /** @see AudioManager#playSoundEffect(int, float) */ playSoundEffectVolume(int effectType, float volume)2513 public void playSoundEffectVolume(int effectType, float volume) { 2514 if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { 2515 Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); 2516 return; 2517 } 2518 2519 sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE, 2520 effectType, (int) (volume * 1000), null, 0); 2521 } 2522 2523 /** 2524 * Loads samples into the soundpool. 2525 * This method must be called at first when sound effects are enabled 2526 */ loadSoundEffects()2527 public boolean loadSoundEffects() { 2528 int attempts = 3; 2529 LoadSoundEffectReply reply = new LoadSoundEffectReply(); 2530 2531 synchronized (reply) { 2532 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0); 2533 while ((reply.mStatus == 1) && (attempts-- > 0)) { 2534 try { 2535 reply.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 2536 } catch (InterruptedException e) { 2537 Log.w(TAG, "loadSoundEffects Interrupted while waiting sound pool loaded."); 2538 } 2539 } 2540 } 2541 return (reply.mStatus == 0); 2542 } 2543 2544 /** 2545 * Unloads samples from the sound pool. 2546 * This method can be called to free some memory when 2547 * sound effects are disabled. 2548 */ unloadSoundEffects()2549 public void unloadSoundEffects() { 2550 sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 2551 } 2552 2553 class SoundPoolListenerThread extends Thread { SoundPoolListenerThread()2554 public SoundPoolListenerThread() { 2555 super("SoundPoolListenerThread"); 2556 } 2557 2558 @Override run()2559 public void run() { 2560 2561 Looper.prepare(); 2562 mSoundPoolLooper = Looper.myLooper(); 2563 2564 synchronized (mSoundEffectsLock) { 2565 if (mSoundPool != null) { 2566 mSoundPoolCallBack = new SoundPoolCallback(); 2567 mSoundPool.setOnLoadCompleteListener(mSoundPoolCallBack); 2568 } 2569 mSoundEffectsLock.notify(); 2570 } 2571 Looper.loop(); 2572 } 2573 } 2574 2575 private final class SoundPoolCallback implements 2576 android.media.SoundPool.OnLoadCompleteListener { 2577 2578 int mStatus = 1; // 1 means neither error nor last sample loaded yet 2579 List<Integer> mSamples = new ArrayList<Integer>(); 2580 status()2581 public int status() { 2582 return mStatus; 2583 } 2584 setSamples(int[] samples)2585 public void setSamples(int[] samples) { 2586 for (int i = 0; i < samples.length; i++) { 2587 // do not wait ack for samples rejected upfront by SoundPool 2588 if (samples[i] > 0) { 2589 mSamples.add(samples[i]); 2590 } 2591 } 2592 } 2593 onLoadComplete(SoundPool soundPool, int sampleId, int status)2594 public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { 2595 synchronized (mSoundEffectsLock) { 2596 int i = mSamples.indexOf(sampleId); 2597 if (i >= 0) { 2598 mSamples.remove(i); 2599 } 2600 if ((status != 0) || mSamples. isEmpty()) { 2601 mStatus = status; 2602 mSoundEffectsLock.notify(); 2603 } 2604 } 2605 } 2606 } 2607 2608 /** @see AudioManager#reloadAudioSettings() */ reloadAudioSettings()2609 public void reloadAudioSettings() { 2610 readAudioSettings(false /*userSwitch*/); 2611 } 2612 readAudioSettings(boolean userSwitch)2613 private void readAudioSettings(boolean userSwitch) { 2614 // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings 2615 readPersistedSettings(); 2616 readUserRestrictions(); 2617 2618 // restore volume settings 2619 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2620 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2621 VolumeStreamState streamState = mStreamStates[streamType]; 2622 2623 if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) { 2624 continue; 2625 } 2626 2627 streamState.readSettings(); 2628 synchronized (VolumeStreamState.class) { 2629 // unmute stream that was muted but is not affect by mute anymore 2630 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && 2631 !isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) { 2632 streamState.mIsMuted = false; 2633 } 2634 } 2635 } 2636 2637 // apply new ringer mode before checking volume for alias streams so that streams 2638 // muted by ringer mode have the correct volume 2639 setRingerModeInt(getRingerModeInternal(), false); 2640 2641 checkAllFixedVolumeDevices(); 2642 checkAllAliasStreamVolumes(); 2643 checkMuteAffectedStreams(); 2644 2645 synchronized (mSafeMediaVolumeState) { 2646 mMusicActiveMs = MathUtils.constrain(Settings.Secure.getIntForUser(mContentResolver, 2647 Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, 0, UserHandle.USER_CURRENT), 2648 0, UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX); 2649 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) { 2650 enforceSafeMediaVolume(TAG); 2651 } 2652 } 2653 } 2654 2655 /** @see AudioManager#setSpeakerphoneOn(boolean) */ setSpeakerphoneOn(boolean on)2656 public void setSpeakerphoneOn(boolean on){ 2657 if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 2658 return; 2659 } 2660 2661 if (on) { 2662 if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { 2663 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, 2664 AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, null, 0); 2665 } 2666 mForcedUseForComm = AudioSystem.FORCE_SPEAKER; 2667 } else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER){ 2668 mForcedUseForComm = AudioSystem.FORCE_NONE; 2669 } 2670 2671 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, 2672 AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0); 2673 } 2674 2675 /** @see AudioManager#isSpeakerphoneOn() */ isSpeakerphoneOn()2676 public boolean isSpeakerphoneOn() { 2677 return (mForcedUseForComm == AudioSystem.FORCE_SPEAKER); 2678 } 2679 2680 /** @see AudioManager#setBluetoothScoOn(boolean) */ setBluetoothScoOn(boolean on)2681 public void setBluetoothScoOn(boolean on) { 2682 if (!checkAudioSettingsPermission("setBluetoothScoOn()")) { 2683 return; 2684 } 2685 setBluetoothScoOnInt(on); 2686 } 2687 setBluetoothScoOnInt(boolean on)2688 public void setBluetoothScoOnInt(boolean on) { 2689 if (on) { 2690 mForcedUseForComm = AudioSystem.FORCE_BT_SCO; 2691 } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { 2692 mForcedUseForComm = AudioSystem.FORCE_NONE; 2693 } 2694 2695 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, 2696 AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0); 2697 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, 2698 AudioSystem.FOR_RECORD, mForcedUseForComm, null, 0); 2699 } 2700 2701 /** @see AudioManager#isBluetoothScoOn() */ isBluetoothScoOn()2702 public boolean isBluetoothScoOn() { 2703 return (mForcedUseForComm == AudioSystem.FORCE_BT_SCO); 2704 } 2705 2706 /** @see AudioManager#setBluetoothA2dpOn(boolean) */ setBluetoothA2dpOn(boolean on)2707 public void setBluetoothA2dpOn(boolean on) { 2708 synchronized (mBluetoothA2dpEnabledLock) { 2709 mBluetoothA2dpEnabled = on; 2710 sendMsg(mAudioHandler, MSG_SET_FORCE_BT_A2DP_USE, SENDMSG_QUEUE, 2711 AudioSystem.FOR_MEDIA, 2712 mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP, 2713 null, 0); 2714 } 2715 } 2716 2717 /** @see AudioManager#isBluetoothA2dpOn() */ isBluetoothA2dpOn()2718 public boolean isBluetoothA2dpOn() { 2719 synchronized (mBluetoothA2dpEnabledLock) { 2720 return mBluetoothA2dpEnabled; 2721 } 2722 } 2723 2724 /** @see AudioManager#startBluetoothSco() */ startBluetoothSco(IBinder cb, int targetSdkVersion)2725 public void startBluetoothSco(IBinder cb, int targetSdkVersion) { 2726 int scoAudioMode = 2727 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? 2728 SCO_MODE_VIRTUAL_CALL : SCO_MODE_UNDEFINED; 2729 startBluetoothScoInt(cb, scoAudioMode); 2730 } 2731 2732 /** @see AudioManager#startBluetoothScoVirtualCall() */ startBluetoothScoVirtualCall(IBinder cb)2733 public void startBluetoothScoVirtualCall(IBinder cb) { 2734 startBluetoothScoInt(cb, SCO_MODE_VIRTUAL_CALL); 2735 } 2736 startBluetoothScoInt(IBinder cb, int scoAudioMode)2737 void startBluetoothScoInt(IBinder cb, int scoAudioMode){ 2738 if (!checkAudioSettingsPermission("startBluetoothSco()") || 2739 !mSystemReady) { 2740 return; 2741 } 2742 ScoClient client = getScoClient(cb, true); 2743 // The calling identity must be cleared before calling ScoClient.incCount(). 2744 // inCount() calls requestScoState() which in turn can call BluetoothHeadset APIs 2745 // and this must be done on behalf of system server to make sure permissions are granted. 2746 // The caller identity must be cleared after getScoClient() because it is needed if a new 2747 // client is created. 2748 final long ident = Binder.clearCallingIdentity(); 2749 client.incCount(scoAudioMode); 2750 Binder.restoreCallingIdentity(ident); 2751 } 2752 2753 /** @see AudioManager#stopBluetoothSco() */ stopBluetoothSco(IBinder cb)2754 public void stopBluetoothSco(IBinder cb){ 2755 if (!checkAudioSettingsPermission("stopBluetoothSco()") || 2756 !mSystemReady) { 2757 return; 2758 } 2759 ScoClient client = getScoClient(cb, false); 2760 // The calling identity must be cleared before calling ScoClient.decCount(). 2761 // decCount() calls requestScoState() which in turn can call BluetoothHeadset APIs 2762 // and this must be done on behalf of system server to make sure permissions are granted. 2763 final long ident = Binder.clearCallingIdentity(); 2764 if (client != null) { 2765 client.decCount(); 2766 } 2767 Binder.restoreCallingIdentity(ident); 2768 } 2769 2770 2771 private class ScoClient implements IBinder.DeathRecipient { 2772 private IBinder mCb; // To be notified of client's death 2773 private int mCreatorPid; 2774 private int mStartcount; // number of SCO connections started by this client 2775 ScoClient(IBinder cb)2776 ScoClient(IBinder cb) { 2777 mCb = cb; 2778 mCreatorPid = Binder.getCallingPid(); 2779 mStartcount = 0; 2780 } 2781 binderDied()2782 public void binderDied() { 2783 synchronized(mScoClients) { 2784 Log.w(TAG, "SCO client died"); 2785 int index = mScoClients.indexOf(this); 2786 if (index < 0) { 2787 Log.w(TAG, "unregistered SCO client died"); 2788 } else { 2789 clearCount(true); 2790 mScoClients.remove(this); 2791 } 2792 } 2793 } 2794 incCount(int scoAudioMode)2795 public void incCount(int scoAudioMode) { 2796 synchronized(mScoClients) { 2797 requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode); 2798 if (mStartcount == 0) { 2799 try { 2800 mCb.linkToDeath(this, 0); 2801 } catch (RemoteException e) { 2802 // client has already died! 2803 Log.w(TAG, "ScoClient incCount() could not link to "+mCb+" binder death"); 2804 } 2805 } 2806 mStartcount++; 2807 } 2808 } 2809 decCount()2810 public void decCount() { 2811 synchronized(mScoClients) { 2812 if (mStartcount == 0) { 2813 Log.w(TAG, "ScoClient.decCount() already 0"); 2814 } else { 2815 mStartcount--; 2816 if (mStartcount == 0) { 2817 try { 2818 mCb.unlinkToDeath(this, 0); 2819 } catch (NoSuchElementException e) { 2820 Log.w(TAG, "decCount() going to 0 but not registered to binder"); 2821 } 2822 } 2823 requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0); 2824 } 2825 } 2826 } 2827 clearCount(boolean stopSco)2828 public void clearCount(boolean stopSco) { 2829 synchronized(mScoClients) { 2830 if (mStartcount != 0) { 2831 try { 2832 mCb.unlinkToDeath(this, 0); 2833 } catch (NoSuchElementException e) { 2834 Log.w(TAG, "clearCount() mStartcount: "+mStartcount+" != 0 but not registered to binder"); 2835 } 2836 } 2837 mStartcount = 0; 2838 if (stopSco) { 2839 requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0); 2840 } 2841 } 2842 } 2843 getCount()2844 public int getCount() { 2845 return mStartcount; 2846 } 2847 getBinder()2848 public IBinder getBinder() { 2849 return mCb; 2850 } 2851 getPid()2852 public int getPid() { 2853 return mCreatorPid; 2854 } 2855 totalCount()2856 public int totalCount() { 2857 synchronized(mScoClients) { 2858 int count = 0; 2859 int size = mScoClients.size(); 2860 for (int i = 0; i < size; i++) { 2861 count += mScoClients.get(i).getCount(); 2862 } 2863 return count; 2864 } 2865 } 2866 requestScoState(int state, int scoAudioMode)2867 private void requestScoState(int state, int scoAudioMode) { 2868 checkScoAudioState(); 2869 if (totalCount() == 0) { 2870 if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) { 2871 // Make sure that the state transitions to CONNECTING even if we cannot initiate 2872 // the connection. 2873 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING); 2874 // Accept SCO audio activation only in NORMAL audio mode or if the mode is 2875 // currently controlled by the same client process. 2876 synchronized(mSetModeDeathHandlers) { 2877 if ((mSetModeDeathHandlers.isEmpty() || 2878 mSetModeDeathHandlers.get(0).getPid() == mCreatorPid) && 2879 (mScoAudioState == SCO_STATE_INACTIVE || 2880 mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) { 2881 if (mScoAudioState == SCO_STATE_INACTIVE) { 2882 mScoAudioMode = scoAudioMode; 2883 if (scoAudioMode == SCO_MODE_UNDEFINED) { 2884 if (mBluetoothHeadsetDevice != null) { 2885 mScoAudioMode = new Integer(Settings.Global.getInt( 2886 mContentResolver, 2887 "bluetooth_sco_channel_"+ 2888 mBluetoothHeadsetDevice.getAddress(), 2889 SCO_MODE_VIRTUAL_CALL)); 2890 if (mScoAudioMode > SCO_MODE_MAX || mScoAudioMode < 0) { 2891 mScoAudioMode = SCO_MODE_VIRTUAL_CALL; 2892 } 2893 } else { 2894 mScoAudioMode = SCO_MODE_RAW; 2895 } 2896 } 2897 if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) { 2898 boolean status = false; 2899 if (mScoAudioMode == SCO_MODE_RAW) { 2900 status = mBluetoothHeadset.connectAudio(); 2901 } else if (mScoAudioMode == SCO_MODE_VIRTUAL_CALL) { 2902 status = mBluetoothHeadset.startScoUsingVirtualVoiceCall( 2903 mBluetoothHeadsetDevice); 2904 } else if (mScoAudioMode == SCO_MODE_VR) { 2905 status = mBluetoothHeadset.startVoiceRecognition( 2906 mBluetoothHeadsetDevice); 2907 } 2908 2909 if (status) { 2910 mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; 2911 } else { 2912 broadcastScoConnectionState( 2913 AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 2914 } 2915 } else if (getBluetoothHeadset()) { 2916 mScoAudioState = SCO_STATE_ACTIVATE_REQ; 2917 } 2918 } else { 2919 mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; 2920 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED); 2921 } 2922 } else { 2923 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 2924 } 2925 } 2926 } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED && 2927 (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL || 2928 mScoAudioState == SCO_STATE_ACTIVATE_REQ)) { 2929 if (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL) { 2930 if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) { 2931 boolean status = false; 2932 if (mScoAudioMode == SCO_MODE_RAW) { 2933 status = mBluetoothHeadset.disconnectAudio(); 2934 } else if (mScoAudioMode == SCO_MODE_VIRTUAL_CALL) { 2935 status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall( 2936 mBluetoothHeadsetDevice); 2937 } else if (mScoAudioMode == SCO_MODE_VR) { 2938 status = mBluetoothHeadset.stopVoiceRecognition( 2939 mBluetoothHeadsetDevice); 2940 } 2941 2942 if (!status) { 2943 mScoAudioState = SCO_STATE_INACTIVE; 2944 broadcastScoConnectionState( 2945 AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 2946 } 2947 } else if (getBluetoothHeadset()) { 2948 mScoAudioState = SCO_STATE_DEACTIVATE_REQ; 2949 } 2950 } else { 2951 mScoAudioState = SCO_STATE_INACTIVE; 2952 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 2953 } 2954 } 2955 } 2956 } 2957 } 2958 checkScoAudioState()2959 private void checkScoAudioState() { 2960 if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null && 2961 mScoAudioState == SCO_STATE_INACTIVE && 2962 mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice) 2963 != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { 2964 mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; 2965 } 2966 } 2967 getScoClient(IBinder cb, boolean create)2968 private ScoClient getScoClient(IBinder cb, boolean create) { 2969 synchronized(mScoClients) { 2970 ScoClient client = null; 2971 int size = mScoClients.size(); 2972 for (int i = 0; i < size; i++) { 2973 client = mScoClients.get(i); 2974 if (client.getBinder() == cb) 2975 return client; 2976 } 2977 if (create) { 2978 client = new ScoClient(cb); 2979 mScoClients.add(client); 2980 } 2981 return client; 2982 } 2983 } 2984 clearAllScoClients(int exceptPid, boolean stopSco)2985 public void clearAllScoClients(int exceptPid, boolean stopSco) { 2986 synchronized(mScoClients) { 2987 ScoClient savedClient = null; 2988 int size = mScoClients.size(); 2989 for (int i = 0; i < size; i++) { 2990 ScoClient cl = mScoClients.get(i); 2991 if (cl.getPid() != exceptPid) { 2992 cl.clearCount(stopSco); 2993 } else { 2994 savedClient = cl; 2995 } 2996 } 2997 mScoClients.clear(); 2998 if (savedClient != null) { 2999 mScoClients.add(savedClient); 3000 } 3001 } 3002 } 3003 getBluetoothHeadset()3004 private boolean getBluetoothHeadset() { 3005 boolean result = false; 3006 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 3007 if (adapter != null) { 3008 result = adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, 3009 BluetoothProfile.HEADSET); 3010 } 3011 // If we could not get a bluetooth headset proxy, send a failure message 3012 // without delay to reset the SCO audio state and clear SCO clients. 3013 // If we could get a proxy, send a delayed failure message that will reset our state 3014 // in case we don't receive onServiceConnected(). 3015 sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED, 3016 SENDMSG_REPLACE, 0, 0, null, result ? BT_HEADSET_CNCT_TIMEOUT_MS : 0); 3017 return result; 3018 } 3019 disconnectBluetoothSco(int exceptPid)3020 private void disconnectBluetoothSco(int exceptPid) { 3021 synchronized(mScoClients) { 3022 checkScoAudioState(); 3023 if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL || 3024 mScoAudioState == SCO_STATE_DEACTIVATE_EXT_REQ) { 3025 if (mBluetoothHeadsetDevice != null) { 3026 if (mBluetoothHeadset != null) { 3027 if (!mBluetoothHeadset.stopVoiceRecognition( 3028 mBluetoothHeadsetDevice)) { 3029 sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED, 3030 SENDMSG_REPLACE, 0, 0, null, 0); 3031 } 3032 } else if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL && 3033 getBluetoothHeadset()) { 3034 mScoAudioState = SCO_STATE_DEACTIVATE_EXT_REQ; 3035 } 3036 } 3037 } else { 3038 clearAllScoClients(exceptPid, true); 3039 } 3040 } 3041 } 3042 resetBluetoothSco()3043 private void resetBluetoothSco() { 3044 synchronized(mScoClients) { 3045 clearAllScoClients(0, false); 3046 mScoAudioState = SCO_STATE_INACTIVE; 3047 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 3048 } 3049 AudioSystem.setParameters("A2dpSuspended=false"); 3050 setBluetoothScoOnInt(false); 3051 } 3052 broadcastScoConnectionState(int state)3053 private void broadcastScoConnectionState(int state) { 3054 sendMsg(mAudioHandler, MSG_BROADCAST_BT_CONNECTION_STATE, 3055 SENDMSG_QUEUE, state, 0, null, 0); 3056 } 3057 onBroadcastScoConnectionState(int state)3058 private void onBroadcastScoConnectionState(int state) { 3059 if (state != mScoConnectionState) { 3060 Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); 3061 newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, state); 3062 newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, 3063 mScoConnectionState); 3064 sendStickyBroadcastToAll(newIntent); 3065 mScoConnectionState = state; 3066 } 3067 } 3068 setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state)3069 void setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state) { 3070 if (btDevice == null) { 3071 return; 3072 } 3073 3074 String address = btDevice.getAddress(); 3075 BluetoothClass btClass = btDevice.getBluetoothClass(); 3076 int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; 3077 int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET; 3078 if (btClass != null) { 3079 switch (btClass.getDeviceClass()) { 3080 case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: 3081 case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: 3082 outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 3083 break; 3084 case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: 3085 outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 3086 break; 3087 } 3088 } 3089 3090 if (!BluetoothAdapter.checkBluetoothAddress(address)) { 3091 address = ""; 3092 } 3093 3094 boolean connected = (state == BluetoothProfile.STATE_CONNECTED); 3095 3096 String btDeviceName = btDevice.getName(); 3097 boolean success = 3098 handleDeviceConnection(connected, outDevice, address, btDeviceName) && 3099 handleDeviceConnection(connected, inDevice, address, btDeviceName); 3100 if (success) { 3101 synchronized (mScoClients) { 3102 if (connected) { 3103 mBluetoothHeadsetDevice = btDevice; 3104 } else { 3105 mBluetoothHeadsetDevice = null; 3106 resetBluetoothSco(); 3107 } 3108 } 3109 } 3110 } 3111 3112 private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = 3113 new BluetoothProfile.ServiceListener() { 3114 public void onServiceConnected(int profile, BluetoothProfile proxy) { 3115 BluetoothDevice btDevice; 3116 List<BluetoothDevice> deviceList; 3117 switch(profile) { 3118 case BluetoothProfile.A2DP: 3119 synchronized (mConnectedDevices) { 3120 synchronized (mA2dpAvrcpLock) { 3121 mA2dp = (BluetoothA2dp) proxy; 3122 deviceList = mA2dp.getConnectedDevices(); 3123 if (deviceList.size() > 0) { 3124 btDevice = deviceList.get(0); 3125 int state = mA2dp.getConnectionState(btDevice); 3126 int delay = checkSendBecomingNoisyIntent( 3127 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 3128 (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0); 3129 queueMsgUnderWakeLock(mAudioHandler, 3130 MSG_SET_A2DP_SINK_CONNECTION_STATE, 3131 state, 3132 0, 3133 btDevice, 3134 delay); 3135 } 3136 } 3137 } 3138 break; 3139 3140 case BluetoothProfile.A2DP_SINK: 3141 deviceList = proxy.getConnectedDevices(); 3142 if (deviceList.size() > 0) { 3143 btDevice = deviceList.get(0); 3144 synchronized (mConnectedDevices) { 3145 int state = proxy.getConnectionState(btDevice); 3146 queueMsgUnderWakeLock(mAudioHandler, 3147 MSG_SET_A2DP_SRC_CONNECTION_STATE, 3148 state, 3149 0, 3150 btDevice, 3151 0 /* delay */); 3152 } 3153 } 3154 break; 3155 3156 case BluetoothProfile.HEADSET: 3157 synchronized (mScoClients) { 3158 // Discard timeout message 3159 mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED); 3160 mBluetoothHeadset = (BluetoothHeadset) proxy; 3161 deviceList = mBluetoothHeadset.getConnectedDevices(); 3162 if (deviceList.size() > 0) { 3163 mBluetoothHeadsetDevice = deviceList.get(0); 3164 } else { 3165 mBluetoothHeadsetDevice = null; 3166 } 3167 // Refresh SCO audio state 3168 checkScoAudioState(); 3169 // Continue pending action if any 3170 if (mScoAudioState == SCO_STATE_ACTIVATE_REQ || 3171 mScoAudioState == SCO_STATE_DEACTIVATE_REQ || 3172 mScoAudioState == SCO_STATE_DEACTIVATE_EXT_REQ) { 3173 boolean status = false; 3174 if (mBluetoothHeadsetDevice != null) { 3175 switch (mScoAudioState) { 3176 case SCO_STATE_ACTIVATE_REQ: 3177 mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; 3178 if (mScoAudioMode == SCO_MODE_RAW) { 3179 status = mBluetoothHeadset.connectAudio(); 3180 } else if (mScoAudioMode == SCO_MODE_VIRTUAL_CALL) { 3181 status = mBluetoothHeadset.startScoUsingVirtualVoiceCall( 3182 mBluetoothHeadsetDevice); 3183 } else if (mScoAudioMode == SCO_MODE_VR) { 3184 status = mBluetoothHeadset.startVoiceRecognition( 3185 mBluetoothHeadsetDevice); 3186 } 3187 break; 3188 case SCO_STATE_DEACTIVATE_REQ: 3189 if (mScoAudioMode == SCO_MODE_RAW) { 3190 status = mBluetoothHeadset.disconnectAudio(); 3191 } else if (mScoAudioMode == SCO_MODE_VIRTUAL_CALL) { 3192 status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall( 3193 mBluetoothHeadsetDevice); 3194 } else if (mScoAudioMode == SCO_MODE_VR) { 3195 status = mBluetoothHeadset.stopVoiceRecognition( 3196 mBluetoothHeadsetDevice); 3197 } 3198 break; 3199 case SCO_STATE_DEACTIVATE_EXT_REQ: 3200 status = mBluetoothHeadset.stopVoiceRecognition( 3201 mBluetoothHeadsetDevice); 3202 } 3203 } 3204 if (!status) { 3205 sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED, 3206 SENDMSG_REPLACE, 0, 0, null, 0); 3207 } 3208 } 3209 } 3210 break; 3211 3212 default: 3213 break; 3214 } 3215 } 3216 public void onServiceDisconnected(int profile) { 3217 3218 switch (profile) { 3219 case BluetoothProfile.A2DP: 3220 disconnectA2dp(); 3221 break; 3222 3223 case BluetoothProfile.A2DP_SINK: 3224 disconnectA2dpSink(); 3225 break; 3226 3227 case BluetoothProfile.HEADSET: 3228 disconnectHeadset(); 3229 break; 3230 3231 default: 3232 break; 3233 } 3234 } 3235 }; 3236 disconnectAllBluetoothProfiles()3237 void disconnectAllBluetoothProfiles() { 3238 disconnectA2dp(); 3239 disconnectA2dpSink(); 3240 disconnectHeadset(); 3241 } 3242 disconnectA2dp()3243 void disconnectA2dp() { 3244 synchronized (mConnectedDevices) { 3245 synchronized (mA2dpAvrcpLock) { 3246 ArraySet<String> toRemove = null; 3247 // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices 3248 for (int i = 0; i < mConnectedDevices.size(); i++) { 3249 DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i); 3250 if (deviceSpec.mDeviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { 3251 toRemove = toRemove != null ? toRemove : new ArraySet<String>(); 3252 toRemove.add(deviceSpec.mDeviceAddress); 3253 } 3254 } 3255 if (toRemove != null) { 3256 int delay = checkSendBecomingNoisyIntent( 3257 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 3258 0); 3259 for (int i = 0; i < toRemove.size(); i++) { 3260 makeA2dpDeviceUnavailableLater(toRemove.valueAt(i), delay); 3261 } 3262 } 3263 } 3264 } 3265 } 3266 disconnectA2dpSink()3267 void disconnectA2dpSink() { 3268 synchronized (mConnectedDevices) { 3269 ArraySet<String> toRemove = null; 3270 // Disconnect ALL DEVICE_IN_BLUETOOTH_A2DP devices 3271 for(int i = 0; i < mConnectedDevices.size(); i++) { 3272 DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i); 3273 if (deviceSpec.mDeviceType == AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) { 3274 toRemove = toRemove != null ? toRemove : new ArraySet<String>(); 3275 toRemove.add(deviceSpec.mDeviceAddress); 3276 } 3277 } 3278 if (toRemove != null) { 3279 for (int i = 0; i < toRemove.size(); i++) { 3280 makeA2dpSrcUnavailable(toRemove.valueAt(i)); 3281 } 3282 } 3283 } 3284 } 3285 disconnectHeadset()3286 void disconnectHeadset() { 3287 synchronized (mScoClients) { 3288 if (mBluetoothHeadsetDevice != null) { 3289 setBtScoDeviceConnectionState(mBluetoothHeadsetDevice, 3290 BluetoothProfile.STATE_DISCONNECTED); 3291 } 3292 mBluetoothHeadset = null; 3293 } 3294 } 3295 onCheckMusicActive(String caller)3296 private void onCheckMusicActive(String caller) { 3297 synchronized (mSafeMediaVolumeState) { 3298 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) { 3299 int device = getDeviceForStream(AudioSystem.STREAM_MUSIC); 3300 3301 if ((device & mSafeMediaVolumeDevices) != 0) { 3302 sendMsg(mAudioHandler, 3303 MSG_CHECK_MUSIC_ACTIVE, 3304 SENDMSG_REPLACE, 3305 0, 3306 0, 3307 caller, 3308 MUSIC_ACTIVE_POLL_PERIOD_MS); 3309 int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device); 3310 if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) && 3311 (index > mSafeMediaVolumeIndex)) { 3312 // Approximate cumulative active music time 3313 mMusicActiveMs += MUSIC_ACTIVE_POLL_PERIOD_MS; 3314 if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) { 3315 setSafeMediaVolumeEnabled(true, caller); 3316 mMusicActiveMs = 0; 3317 } 3318 saveMusicActiveMs(); 3319 } 3320 } 3321 } 3322 } 3323 } 3324 saveMusicActiveMs()3325 private void saveMusicActiveMs() { 3326 mAudioHandler.obtainMessage(MSG_PERSIST_MUSIC_ACTIVE_MS, mMusicActiveMs, 0).sendToTarget(); 3327 } 3328 onConfigureSafeVolume(boolean force, String caller)3329 private void onConfigureSafeVolume(boolean force, String caller) { 3330 synchronized (mSafeMediaVolumeState) { 3331 int mcc = mContext.getResources().getConfiguration().mcc; 3332 if ((mMcc != mcc) || ((mMcc == 0) && force)) { 3333 mSafeMediaVolumeIndex = mContext.getResources().getInteger( 3334 com.android.internal.R.integer.config_safe_media_volume_index) * 10; 3335 boolean safeMediaVolumeEnabled = 3336 SystemProperties.getBoolean("audio.safemedia.force", false) 3337 || mContext.getResources().getBoolean( 3338 com.android.internal.R.bool.config_safe_media_volume_enabled); 3339 3340 boolean safeMediaVolumeBypass = 3341 SystemProperties.getBoolean("audio.safemedia.bypass", false); 3342 3343 // The persisted state is either "disabled" or "active": this is the state applied 3344 // next time we boot and cannot be "inactive" 3345 int persistedState; 3346 if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) { 3347 persistedState = SAFE_MEDIA_VOLUME_ACTIVE; 3348 // The state can already be "inactive" here if the user has forced it before 3349 // the 30 seconds timeout for forced configuration. In this case we don't reset 3350 // it to "active". 3351 if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) { 3352 if (mMusicActiveMs == 0) { 3353 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; 3354 enforceSafeMediaVolume(caller); 3355 } else { 3356 // We have existing playback time recorded, already confirmed. 3357 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE; 3358 } 3359 } 3360 } else { 3361 persistedState = SAFE_MEDIA_VOLUME_DISABLED; 3362 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED; 3363 } 3364 mMcc = mcc; 3365 sendMsg(mAudioHandler, 3366 MSG_PERSIST_SAFE_VOLUME_STATE, 3367 SENDMSG_QUEUE, 3368 persistedState, 3369 0, 3370 null, 3371 0); 3372 } 3373 } 3374 } 3375 3376 /////////////////////////////////////////////////////////////////////////// 3377 // Internal methods 3378 /////////////////////////////////////////////////////////////////////////// 3379 3380 /** 3381 * Checks if the adjustment should change ringer mode instead of just 3382 * adjusting volume. If so, this will set the proper ringer mode and volume 3383 * indices on the stream states. 3384 */ checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)3385 private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, 3386 String caller, int flags) { 3387 final boolean isTv = mPlatformType == AudioSystem.PLATFORM_TELEVISION; 3388 int result = FLAG_ADJUST_VOLUME; 3389 int ringerMode = getRingerModeInternal(); 3390 3391 switch (ringerMode) { 3392 case RINGER_MODE_NORMAL: 3393 if (direction == AudioManager.ADJUST_LOWER) { 3394 if (mHasVibrator) { 3395 // "step" is the delta in internal index units corresponding to a 3396 // change of 1 in UI index units. 3397 // Because of rounding when rescaling from one stream index range to its alias 3398 // index range, we cannot simply test oldIndex == step: 3399 // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1) 3400 if (step <= oldIndex && oldIndex < 2 * step) { 3401 ringerMode = RINGER_MODE_VIBRATE; 3402 mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis(); 3403 } 3404 } else { 3405 if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) { 3406 ringerMode = RINGER_MODE_SILENT; 3407 } 3408 } 3409 } else if (isTv && (direction == AudioManager.ADJUST_TOGGLE_MUTE 3410 || direction == AudioManager.ADJUST_MUTE)) { 3411 if (mHasVibrator) { 3412 ringerMode = RINGER_MODE_VIBRATE; 3413 } else { 3414 ringerMode = RINGER_MODE_SILENT; 3415 } 3416 // Setting the ringer mode will toggle mute 3417 result &= ~FLAG_ADJUST_VOLUME; 3418 } 3419 break; 3420 case RINGER_MODE_VIBRATE: 3421 if (!mHasVibrator) { 3422 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" + 3423 "but no vibrator is present"); 3424 break; 3425 } 3426 if ((direction == AudioManager.ADJUST_LOWER)) { 3427 // This is the case we were muted with the volume turned up 3428 if (isTv && oldIndex >= 2 * step && isMuted) { 3429 ringerMode = RINGER_MODE_NORMAL; 3430 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) { 3431 if (mVolumePolicy.volumeDownToEnterSilent) { 3432 final long diff = SystemClock.uptimeMillis() 3433 - mLoweredFromNormalToVibrateTime; 3434 if (diff > mVolumePolicy.vibrateToSilentDebounce 3435 && mRingerModeDelegate.canVolumeDownEnterSilent()) { 3436 ringerMode = RINGER_MODE_SILENT; 3437 } 3438 } else { 3439 result |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 3440 } 3441 } 3442 } else if (direction == AudioManager.ADJUST_RAISE 3443 || direction == AudioManager.ADJUST_TOGGLE_MUTE 3444 || direction == AudioManager.ADJUST_UNMUTE) { 3445 ringerMode = RINGER_MODE_NORMAL; 3446 } 3447 result &= ~FLAG_ADJUST_VOLUME; 3448 break; 3449 case RINGER_MODE_SILENT: 3450 if (isTv && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) { 3451 // This is the case we were muted with the volume turned up 3452 ringerMode = RINGER_MODE_NORMAL; 3453 } else if (direction == AudioManager.ADJUST_RAISE 3454 || direction == AudioManager.ADJUST_TOGGLE_MUTE 3455 || direction == AudioManager.ADJUST_UNMUTE) { 3456 if (!mVolumePolicy.volumeUpToExitSilent) { 3457 result |= AudioManager.FLAG_SHOW_SILENT_HINT; 3458 } else { 3459 if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) { 3460 ringerMode = RINGER_MODE_VIBRATE; 3461 } else { 3462 // If we don't have a vibrator or they were toggling mute 3463 // go straight back to normal. 3464 ringerMode = RINGER_MODE_NORMAL; 3465 } 3466 } 3467 } 3468 result &= ~FLAG_ADJUST_VOLUME; 3469 break; 3470 default: 3471 Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode); 3472 break; 3473 } 3474 3475 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 3476 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller) 3477 && (flags & AudioManager.FLAG_FROM_KEY) == 0) { 3478 throw new SecurityException("Not allowed to change Do Not Disturb state"); 3479 } 3480 3481 setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/); 3482 3483 mPrevVolDirection = direction; 3484 3485 return result; 3486 } 3487 3488 @Override isStreamAffectedByRingerMode(int streamType)3489 public boolean isStreamAffectedByRingerMode(int streamType) { 3490 return (mRingerModeAffectedStreams & (1 << streamType)) != 0; 3491 } 3492 isStreamMutedByRingerMode(int streamType)3493 private boolean isStreamMutedByRingerMode(int streamType) { 3494 return (mRingerModeMutedStreams & (1 << streamType)) != 0; 3495 } 3496 updateRingerModeAffectedStreams()3497 private boolean updateRingerModeAffectedStreams() { 3498 int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver, 3499 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 3500 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)| 3501 (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)), 3502 UserHandle.USER_CURRENT); 3503 3504 if (mPlatformType == AudioSystem.PLATFORM_TELEVISION) { 3505 ringerModeAffectedStreams = 0; 3506 } else if (mRingerModeDelegate != null) { 3507 ringerModeAffectedStreams = mRingerModeDelegate 3508 .getRingerModeAffectedStreams(ringerModeAffectedStreams); 3509 } 3510 synchronized (mCameraSoundForced) { 3511 if (mCameraSoundForced) { 3512 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 3513 } else { 3514 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 3515 } 3516 } 3517 if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) { 3518 ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 3519 } else { 3520 ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 3521 } 3522 3523 if (ringerModeAffectedStreams != mRingerModeAffectedStreams) { 3524 Settings.System.putIntForUser(mContentResolver, 3525 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 3526 ringerModeAffectedStreams, 3527 UserHandle.USER_CURRENT); 3528 mRingerModeAffectedStreams = ringerModeAffectedStreams; 3529 return true; 3530 } 3531 return false; 3532 } 3533 3534 @Override isStreamAffectedByMute(int streamType)3535 public boolean isStreamAffectedByMute(int streamType) { 3536 return (mMuteAffectedStreams & (1 << streamType)) != 0; 3537 } 3538 ensureValidDirection(int direction)3539 private void ensureValidDirection(int direction) { 3540 switch (direction) { 3541 case AudioManager.ADJUST_LOWER: 3542 case AudioManager.ADJUST_RAISE: 3543 case AudioManager.ADJUST_SAME: 3544 case AudioManager.ADJUST_MUTE: 3545 case AudioManager.ADJUST_UNMUTE: 3546 case AudioManager.ADJUST_TOGGLE_MUTE: 3547 break; 3548 default: 3549 throw new IllegalArgumentException("Bad direction " + direction); 3550 } 3551 } 3552 ensureValidStreamType(int streamType)3553 private void ensureValidStreamType(int streamType) { 3554 if (streamType < 0 || streamType >= mStreamStates.length) { 3555 throw new IllegalArgumentException("Bad stream type " + streamType); 3556 } 3557 } 3558 isMuteAdjust(int adjust)3559 private boolean isMuteAdjust(int adjust) { 3560 return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE 3561 || adjust == AudioManager.ADJUST_TOGGLE_MUTE; 3562 } 3563 isInCommunication()3564 private boolean isInCommunication() { 3565 boolean IsInCall = false; 3566 3567 TelecomManager telecomManager = 3568 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 3569 3570 final long ident = Binder.clearCallingIdentity(); 3571 IsInCall = telecomManager.isInCall(); 3572 Binder.restoreCallingIdentity(ident); 3573 3574 return (IsInCall || getMode() == AudioManager.MODE_IN_COMMUNICATION); 3575 } 3576 3577 /** 3578 * For code clarity for getActiveStreamType(int) 3579 * @param delay_ms max time since last STREAM_MUSIC activity to consider 3580 * @return true if STREAM_MUSIC is active in streams handled by AudioFlinger now or 3581 * in the last "delay_ms" ms. 3582 */ isAfMusicActiveRecently(int delay_ms)3583 private boolean isAfMusicActiveRecently(int delay_ms) { 3584 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, delay_ms) 3585 || AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, delay_ms); 3586 } 3587 getActiveStreamType(int suggestedStreamType)3588 private int getActiveStreamType(int suggestedStreamType) { 3589 switch (mPlatformType) { 3590 case AudioSystem.PLATFORM_VOICE: 3591 if (isInCommunication()) { 3592 if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION) 3593 == AudioSystem.FORCE_BT_SCO) { 3594 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO..."); 3595 return AudioSystem.STREAM_BLUETOOTH_SCO; 3596 } else { 3597 // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL..."); 3598 return AudioSystem.STREAM_VOICE_CALL; 3599 } 3600 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 3601 if (isAfMusicActiveRecently(StreamOverride.sDelayMs)) { 3602 if (DEBUG_VOL) 3603 Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); 3604 return AudioSystem.STREAM_MUSIC; 3605 } else { 3606 if (DEBUG_VOL) 3607 Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING b/c default"); 3608 return AudioSystem.STREAM_RING; 3609 } 3610 } else if (isAfMusicActiveRecently(0)) { 3611 if (DEBUG_VOL) 3612 Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); 3613 return AudioSystem.STREAM_MUSIC; 3614 } 3615 break; 3616 case AudioSystem.PLATFORM_TELEVISION: 3617 if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 3618 // TV always defaults to STREAM_MUSIC 3619 return AudioSystem.STREAM_MUSIC; 3620 } 3621 break; 3622 default: 3623 if (isInCommunication()) { 3624 if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION) 3625 == AudioSystem.FORCE_BT_SCO) { 3626 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO"); 3627 return AudioSystem.STREAM_BLUETOOTH_SCO; 3628 } else { 3629 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL"); 3630 return AudioSystem.STREAM_VOICE_CALL; 3631 } 3632 } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_NOTIFICATION, 3633 StreamOverride.sDelayMs) || 3634 AudioSystem.isStreamActive(AudioSystem.STREAM_RING, 3635 StreamOverride.sDelayMs)) { 3636 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); 3637 return AudioSystem.STREAM_NOTIFICATION; 3638 } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 3639 if (isAfMusicActiveRecently(StreamOverride.sDelayMs)) { 3640 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC"); 3641 return AudioSystem.STREAM_MUSIC; 3642 } else { 3643 if (DEBUG_VOL) Log.v(TAG, 3644 "getActiveStreamType: using STREAM_NOTIFICATION as default"); 3645 return AudioSystem.STREAM_NOTIFICATION; 3646 } 3647 } 3648 break; 3649 } 3650 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type " 3651 + suggestedStreamType); 3652 return suggestedStreamType; 3653 } 3654 broadcastRingerMode(String action, int ringerMode)3655 private void broadcastRingerMode(String action, int ringerMode) { 3656 // Send sticky broadcast 3657 Intent broadcast = new Intent(action); 3658 broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode); 3659 broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 3660 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 3661 sendStickyBroadcastToAll(broadcast); 3662 } 3663 broadcastVibrateSetting(int vibrateType)3664 private void broadcastVibrateSetting(int vibrateType) { 3665 // Send broadcast 3666 if (ActivityManagerNative.isSystemReady()) { 3667 Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); 3668 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType); 3669 broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType)); 3670 sendBroadcastToAll(broadcast); 3671 } 3672 } 3673 3674 // Message helper methods 3675 /** 3676 * Queue a message on the given handler's message queue, after acquiring the service wake lock. 3677 * Note that the wake lock needs to be released after the message has been handled. 3678 */ queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)3679 private void queueMsgUnderWakeLock(Handler handler, int msg, 3680 int arg1, int arg2, Object obj, int delay) { 3681 final long ident = Binder.clearCallingIdentity(); 3682 // Always acquire the wake lock as AudioService because it is released by the 3683 // message handler. 3684 mAudioEventWakeLock.acquire(); 3685 Binder.restoreCallingIdentity(ident); 3686 sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay); 3687 } 3688 sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)3689 private static void sendMsg(Handler handler, int msg, 3690 int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) { 3691 3692 if (existingMsgPolicy == SENDMSG_REPLACE) { 3693 handler.removeMessages(msg); 3694 } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) { 3695 return; 3696 } 3697 synchronized (mLastDeviceConnectMsgTime) { 3698 long time = SystemClock.uptimeMillis() + delay; 3699 handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time); 3700 if (msg == MSG_SET_WIRED_DEVICE_CONNECTION_STATE || 3701 msg == MSG_SET_A2DP_SRC_CONNECTION_STATE || 3702 msg == MSG_SET_A2DP_SINK_CONNECTION_STATE) { 3703 mLastDeviceConnectMsgTime = time; 3704 } 3705 } 3706 } 3707 checkAudioSettingsPermission(String method)3708 boolean checkAudioSettingsPermission(String method) { 3709 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS) 3710 == PackageManager.PERMISSION_GRANTED) { 3711 return true; 3712 } 3713 String msg = "Audio Settings Permission Denial: " + method + " from pid=" 3714 + Binder.getCallingPid() 3715 + ", uid=" + Binder.getCallingUid(); 3716 Log.w(TAG, msg); 3717 return false; 3718 } 3719 getDeviceForStream(int stream)3720 private int getDeviceForStream(int stream) { 3721 int device = getDevicesForStream(stream); 3722 if ((device & (device - 1)) != 0) { 3723 // Multiple device selection is either: 3724 // - speaker + one other device: give priority to speaker in this case. 3725 // - one A2DP device + another device: happens with duplicated output. In this case 3726 // retain the device on the A2DP output as the other must not correspond to an active 3727 // selection if not the speaker. 3728 // - HDMI-CEC system audio mode only output: give priority to available item in order. 3729 if ((device & AudioSystem.DEVICE_OUT_SPEAKER) != 0) { 3730 device = AudioSystem.DEVICE_OUT_SPEAKER; 3731 } else if ((device & AudioSystem.DEVICE_OUT_HDMI_ARC) != 0) { 3732 device = AudioSystem.DEVICE_OUT_HDMI_ARC; 3733 } else if ((device & AudioSystem.DEVICE_OUT_SPDIF) != 0) { 3734 device = AudioSystem.DEVICE_OUT_SPDIF; 3735 } else if ((device & AudioSystem.DEVICE_OUT_AUX_LINE) != 0) { 3736 device = AudioSystem.DEVICE_OUT_AUX_LINE; 3737 } else { 3738 device &= AudioSystem.DEVICE_OUT_ALL_A2DP; 3739 } 3740 } 3741 return device; 3742 } 3743 getDevicesForStream(int stream)3744 private int getDevicesForStream(int stream) { 3745 return getDevicesForStream(stream, true /*checkOthers*/); 3746 } 3747 getDevicesForStream(int stream, boolean checkOthers)3748 private int getDevicesForStream(int stream, boolean checkOthers) { 3749 ensureValidStreamType(stream); 3750 synchronized (VolumeStreamState.class) { 3751 return mStreamStates[stream].observeDevicesForStream_syncVSS(checkOthers); 3752 } 3753 } 3754 observeDevicesForStreams(int skipStream)3755 private void observeDevicesForStreams(int skipStream) { 3756 synchronized (VolumeStreamState.class) { 3757 for (int stream = 0; stream < mStreamStates.length; stream++) { 3758 if (stream != skipStream) { 3759 mStreamStates[stream].observeDevicesForStream_syncVSS(false /*checkOthers*/); 3760 } 3761 } 3762 } 3763 } 3764 3765 /* 3766 * A class just for packaging up a set of connection parameters. 3767 */ 3768 private class WiredDeviceConnectionState { 3769 public final int mType; 3770 public final int mState; 3771 public final String mAddress; 3772 public final String mName; 3773 public final String mCaller; 3774 WiredDeviceConnectionState(int type, int state, String address, String name, String caller)3775 public WiredDeviceConnectionState(int type, int state, String address, String name, 3776 String caller) { 3777 mType = type; 3778 mState = state; 3779 mAddress = address; 3780 mName = name; 3781 mCaller = caller; 3782 } 3783 } 3784 setWiredDeviceConnectionState(int type, int state, String address, String name, String caller)3785 public void setWiredDeviceConnectionState(int type, int state, String address, String name, 3786 String caller) { 3787 synchronized (mConnectedDevices) { 3788 if (DEBUG_DEVICES) { 3789 Slog.i(TAG, "setWiredDeviceConnectionState(" + state + " nm: " + name + " addr:" 3790 + address + ")"); 3791 } 3792 int delay = checkSendBecomingNoisyIntent(type, state); 3793 queueMsgUnderWakeLock(mAudioHandler, 3794 MSG_SET_WIRED_DEVICE_CONNECTION_STATE, 3795 0, 3796 0, 3797 new WiredDeviceConnectionState(type, state, address, name, caller), 3798 delay); 3799 } 3800 } 3801 setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile)3802 public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile) 3803 { 3804 int delay; 3805 if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK) { 3806 throw new IllegalArgumentException("invalid profile " + profile); 3807 } 3808 synchronized (mConnectedDevices) { 3809 if (profile == BluetoothProfile.A2DP) { 3810 delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 3811 (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0); 3812 } else { 3813 delay = 0; 3814 } 3815 queueMsgUnderWakeLock(mAudioHandler, 3816 (profile == BluetoothProfile.A2DP ? 3817 MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE), 3818 state, 3819 0, 3820 device, 3821 delay); 3822 } 3823 return delay; 3824 } 3825 3826 /////////////////////////////////////////////////////////////////////////// 3827 // Inner classes 3828 /////////////////////////////////////////////////////////////////////////// 3829 3830 // NOTE: Locking order for synchronized objects related to volume or ringer mode management: 3831 // 1 mScoclient OR mSafeMediaVolumeState 3832 // 2 mSetModeDeathHandlers 3833 // 3 mSettingsLock 3834 // 4 VolumeStreamState.class 3835 // 5 mCameraSoundForced 3836 public class VolumeStreamState { 3837 private final int mStreamType; 3838 private final int mIndexMin; 3839 private final int mIndexMax; 3840 3841 private boolean mIsMuted; 3842 private String mVolumeIndexSettingName; 3843 private int mObservedDevices; 3844 3845 private final SparseIntArray mIndexMap = new SparseIntArray(8); 3846 private final Intent mVolumeChanged; 3847 private final Intent mStreamDevicesChanged; 3848 VolumeStreamState(String settingName, int streamType)3849 private VolumeStreamState(String settingName, int streamType) { 3850 3851 mVolumeIndexSettingName = settingName; 3852 3853 mStreamType = streamType; 3854 mIndexMin = MIN_STREAM_VOLUME[streamType] * 10; 3855 mIndexMax = MAX_STREAM_VOLUME[streamType] * 10; 3856 AudioSystem.initStreamVolume(streamType, mIndexMin / 10, mIndexMax / 10); 3857 3858 readSettings(); 3859 mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); 3860 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 3861 mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION); 3862 mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 3863 } 3864 observeDevicesForStream_syncVSS(boolean checkOthers)3865 public int observeDevicesForStream_syncVSS(boolean checkOthers) { 3866 final int devices = AudioSystem.getDevicesForStream(mStreamType); 3867 if (devices == mObservedDevices) { 3868 return devices; 3869 } 3870 final int prevDevices = mObservedDevices; 3871 mObservedDevices = devices; 3872 if (checkOthers) { 3873 // one stream's devices have changed, check the others 3874 observeDevicesForStreams(mStreamType); 3875 } 3876 // log base stream changes to the event log 3877 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 3878 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices); 3879 } 3880 sendBroadcastToAll(mStreamDevicesChanged 3881 .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, prevDevices) 3882 .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, devices)); 3883 return devices; 3884 } 3885 getSettingNameForDevice(int device)3886 public String getSettingNameForDevice(int device) { 3887 String name = mVolumeIndexSettingName; 3888 String suffix = AudioSystem.getOutputDeviceName(device); 3889 if (suffix.isEmpty()) { 3890 return name; 3891 } 3892 return name + "_" + suffix; 3893 } 3894 readSettings()3895 public void readSettings() { 3896 synchronized (VolumeStreamState.class) { 3897 // force maximum volume on all streams if fixed volume property is set 3898 if (mUseFixedVolume) { 3899 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax); 3900 return; 3901 } 3902 // do not read system stream volume from settings: this stream is always aliased 3903 // to another stream type and its volume is never persisted. Values in settings can 3904 // only be stale values 3905 if ((mStreamType == AudioSystem.STREAM_SYSTEM) || 3906 (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) { 3907 int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType]; 3908 synchronized (mCameraSoundForced) { 3909 if (mCameraSoundForced) { 3910 index = mIndexMax; 3911 } 3912 } 3913 mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index); 3914 return; 3915 } 3916 3917 int remainingDevices = AudioSystem.DEVICE_OUT_ALL; 3918 3919 for (int i = 0; remainingDevices != 0; i++) { 3920 int device = (1 << i); 3921 if ((device & remainingDevices) == 0) { 3922 continue; 3923 } 3924 remainingDevices &= ~device; 3925 3926 // retrieve current volume for device 3927 String name = getSettingNameForDevice(device); 3928 // if no volume stored for current stream and device, use default volume if default 3929 // device, continue otherwise 3930 int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? 3931 AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1; 3932 int index = Settings.System.getIntForUser( 3933 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); 3934 if (index == -1) { 3935 continue; 3936 } 3937 3938 mIndexMap.put(device, getValidIndex(10 * index)); 3939 } 3940 } 3941 } 3942 getAbsoluteVolumeIndex(int index)3943 private int getAbsoluteVolumeIndex(int index) { 3944 /* Special handling for Bluetooth Absolute Volume scenario 3945 * If we send full audio gain, some accessories are too loud even at its lowest 3946 * volume. We are not able to enumerate all such accessories, so here is the 3947 * workaround from phone side. 3948 * Pre-scale volume at lowest volume steps 1 2 and 3. 3949 * For volume step 0, set audio gain to 0 as some accessories won't mute on their end. 3950 */ 3951 if (index == 0) { 3952 // 0% for volume 0 3953 index = 0; 3954 } else if (index == 1) { 3955 // 50% for volume 1 3956 index = (int)(mIndexMax * 0.5) /10; 3957 } else if (index == 2) { 3958 // 70% for volume 2 3959 index = (int)(mIndexMax * 0.70) /10; 3960 } else if (index == 3) { 3961 // 85% for volume 3 3962 index = (int)(mIndexMax * 0.85) /10; 3963 } else { 3964 // otherwise, full gain 3965 index = (mIndexMax + 5)/10; 3966 } 3967 return index; 3968 } 3969 3970 // must be called while synchronized VolumeStreamState.class applyDeviceVolume_syncVSS(int device)3971 public void applyDeviceVolume_syncVSS(int device) { 3972 int index; 3973 if (mIsMuted) { 3974 index = 0; 3975 } else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && mAvrcpAbsVolSupported) { 3976 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 3977 } else if ((device & mFullVolumeDevices) != 0) { 3978 index = (mIndexMax + 5)/10; 3979 } else { 3980 index = (getIndex(device) + 5)/10; 3981 } 3982 AudioSystem.setStreamVolumeIndex(mStreamType, index, device); 3983 } 3984 applyAllVolumes()3985 public void applyAllVolumes() { 3986 synchronized (VolumeStreamState.class) { 3987 // apply device specific volumes first 3988 int index; 3989 for (int i = 0; i < mIndexMap.size(); i++) { 3990 final int device = mIndexMap.keyAt(i); 3991 if (device != AudioSystem.DEVICE_OUT_DEFAULT) { 3992 if (mIsMuted) { 3993 index = 0; 3994 } else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && 3995 mAvrcpAbsVolSupported) { 3996 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10); 3997 } else if ((device & mFullVolumeDevices) != 0) { 3998 index = (mIndexMax + 5)/10; 3999 } else { 4000 index = (mIndexMap.valueAt(i) + 5)/10; 4001 } 4002 AudioSystem.setStreamVolumeIndex(mStreamType, index, device); 4003 } 4004 } 4005 // apply default volume last: by convention , default device volume will be used 4006 // by audio policy manager if no explicit volume is present for a given device type 4007 if (mIsMuted) { 4008 index = 0; 4009 } else { 4010 index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10; 4011 } 4012 AudioSystem.setStreamVolumeIndex( 4013 mStreamType, index, AudioSystem.DEVICE_OUT_DEFAULT); 4014 } 4015 } 4016 adjustIndex(int deltaIndex, int device, String caller)4017 public boolean adjustIndex(int deltaIndex, int device, String caller) { 4018 return setIndex(getIndex(device) + deltaIndex, device, caller); 4019 } 4020 setIndex(int index, int device, String caller)4021 public boolean setIndex(int index, int device, String caller) { 4022 boolean changed = false; 4023 int oldIndex; 4024 synchronized (VolumeStreamState.class) { 4025 oldIndex = getIndex(device); 4026 index = getValidIndex(index); 4027 synchronized (mCameraSoundForced) { 4028 if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) { 4029 index = mIndexMax; 4030 } 4031 } 4032 mIndexMap.put(device, index); 4033 4034 changed = oldIndex != index; 4035 if (changed) { 4036 // Apply change to all streams using this one as alias 4037 // if changing volume of current device, also change volume of current 4038 // device on aliased stream 4039 boolean currentDevice = (device == getDeviceForStream(mStreamType)); 4040 int numStreamTypes = AudioSystem.getNumStreamTypes(); 4041 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 4042 if (streamType != mStreamType && 4043 mStreamVolumeAlias[streamType] == mStreamType) { 4044 int scaledIndex = rescaleIndex(index, mStreamType, streamType); 4045 mStreamStates[streamType].setIndex(scaledIndex, device, caller); 4046 if (currentDevice) { 4047 mStreamStates[streamType].setIndex(scaledIndex, 4048 getDeviceForStream(streamType), caller); 4049 } 4050 } 4051 } 4052 } 4053 } 4054 if (changed) { 4055 oldIndex = (oldIndex + 5) / 10; 4056 index = (index + 5) / 10; 4057 // log base stream changes to the event log 4058 if (mStreamVolumeAlias[mStreamType] == mStreamType) { 4059 if (caller == null) { 4060 Log.w(TAG, "No caller for volume_changed event", new Throwable()); 4061 } 4062 EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10, 4063 caller); 4064 } 4065 // fire changed intents for all streams 4066 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); 4067 mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); 4068 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, 4069 mStreamVolumeAlias[mStreamType]); 4070 sendBroadcastToAll(mVolumeChanged); 4071 } 4072 return changed; 4073 } 4074 getIndex(int device)4075 public int getIndex(int device) { 4076 synchronized (VolumeStreamState.class) { 4077 int index = mIndexMap.get(device, -1); 4078 if (index == -1) { 4079 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT 4080 index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT); 4081 } 4082 return index; 4083 } 4084 } 4085 getMaxIndex()4086 public int getMaxIndex() { 4087 return mIndexMax; 4088 } 4089 getMinIndex()4090 public int getMinIndex() { 4091 return mIndexMin; 4092 } 4093 setAllIndexes(VolumeStreamState srcStream, String caller)4094 public void setAllIndexes(VolumeStreamState srcStream, String caller) { 4095 synchronized (VolumeStreamState.class) { 4096 int srcStreamType = srcStream.getStreamType(); 4097 // apply default device volume from source stream to all devices first in case 4098 // some devices are present in this stream state but not in source stream state 4099 int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); 4100 index = rescaleIndex(index, srcStreamType, mStreamType); 4101 for (int i = 0; i < mIndexMap.size(); i++) { 4102 mIndexMap.put(mIndexMap.keyAt(i), index); 4103 } 4104 // Now apply actual volume for devices in source stream state 4105 SparseIntArray srcMap = srcStream.mIndexMap; 4106 for (int i = 0; i < srcMap.size(); i++) { 4107 int device = srcMap.keyAt(i); 4108 index = srcMap.valueAt(i); 4109 index = rescaleIndex(index, srcStreamType, mStreamType); 4110 4111 setIndex(index, device, caller); 4112 } 4113 } 4114 } 4115 setAllIndexesToMax()4116 public void setAllIndexesToMax() { 4117 synchronized (VolumeStreamState.class) { 4118 for (int i = 0; i < mIndexMap.size(); i++) { 4119 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax); 4120 } 4121 } 4122 } 4123 mute(boolean state)4124 public void mute(boolean state) { 4125 boolean changed = false; 4126 synchronized (VolumeStreamState.class) { 4127 if (state != mIsMuted) { 4128 changed = true; 4129 mIsMuted = state; 4130 4131 // Set the new mute volume. This propagates the values to 4132 // the audio system, otherwise the volume won't be changed 4133 // at the lower level. 4134 sendMsg(mAudioHandler, 4135 MSG_SET_ALL_VOLUMES, 4136 SENDMSG_QUEUE, 4137 0, 4138 0, 4139 this, 0); 4140 } 4141 } 4142 if (changed) { 4143 // Stream mute changed, fire the intent. 4144 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); 4145 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); 4146 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state); 4147 sendBroadcastToAll(intent); 4148 } 4149 } 4150 getStreamType()4151 public int getStreamType() { 4152 return mStreamType; 4153 } 4154 checkFixedVolumeDevices()4155 public void checkFixedVolumeDevices() { 4156 synchronized (VolumeStreamState.class) { 4157 // ignore settings for fixed volume devices: volume should always be at max or 0 4158 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) { 4159 for (int i = 0; i < mIndexMap.size(); i++) { 4160 int device = mIndexMap.keyAt(i); 4161 int index = mIndexMap.valueAt(i); 4162 if (((device & mFullVolumeDevices) != 0) 4163 || (((device & mFixedVolumeDevices) != 0) && index != 0)) { 4164 mIndexMap.put(device, mIndexMax); 4165 } 4166 applyDeviceVolume_syncVSS(device); 4167 } 4168 } 4169 } 4170 } 4171 getValidIndex(int index)4172 private int getValidIndex(int index) { 4173 if (index < mIndexMin) { 4174 return mIndexMin; 4175 } else if (mUseFixedVolume || index > mIndexMax) { 4176 return mIndexMax; 4177 } 4178 4179 return index; 4180 } 4181 dump(PrintWriter pw)4182 private void dump(PrintWriter pw) { 4183 pw.print(" Muted: "); 4184 pw.println(mIsMuted); 4185 pw.print(" Min: "); 4186 pw.println((mIndexMin + 5) / 10); 4187 pw.print(" Max: "); 4188 pw.println((mIndexMax + 5) / 10); 4189 pw.print(" Current: "); 4190 for (int i = 0; i < mIndexMap.size(); i++) { 4191 if (i > 0) { 4192 pw.print(", "); 4193 } 4194 final int device = mIndexMap.keyAt(i); 4195 pw.print(Integer.toHexString(device)); 4196 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default" 4197 : AudioSystem.getOutputDeviceName(device); 4198 if (!deviceName.isEmpty()) { 4199 pw.print(" ("); 4200 pw.print(deviceName); 4201 pw.print(")"); 4202 } 4203 pw.print(": "); 4204 final int index = (mIndexMap.valueAt(i) + 5) / 10; 4205 pw.print(index); 4206 } 4207 pw.println(); 4208 pw.print(" Devices: "); 4209 final int devices = getDevicesForStream(mStreamType); 4210 int device, i = 0, n = 0; 4211 // iterate all devices from 1 to DEVICE_OUT_DEFAULT exclusive 4212 // (the default device is not returned by getDevicesForStream) 4213 while ((device = 1 << i) != AudioSystem.DEVICE_OUT_DEFAULT) { 4214 if ((devices & device) != 0) { 4215 if (n++ > 0) { 4216 pw.print(", "); 4217 } 4218 pw.print(AudioSystem.getOutputDeviceName(device)); 4219 } 4220 i++; 4221 } 4222 } 4223 } 4224 4225 /** Thread that handles native AudioSystem control. */ 4226 private class AudioSystemThread extends Thread { AudioSystemThread()4227 AudioSystemThread() { 4228 super("AudioService"); 4229 } 4230 4231 @Override run()4232 public void run() { 4233 // Set this thread up so the handler will work on it 4234 Looper.prepare(); 4235 4236 synchronized(AudioService.this) { 4237 mAudioHandler = new AudioHandler(); 4238 4239 // Notify that the handler has been created 4240 AudioService.this.notify(); 4241 } 4242 4243 // Listen for volume change requests that are set by VolumePanel 4244 Looper.loop(); 4245 } 4246 } 4247 4248 /** Handles internal volume messages in separate volume thread. */ 4249 private class AudioHandler extends Handler { 4250 setDeviceVolume(VolumeStreamState streamState, int device)4251 private void setDeviceVolume(VolumeStreamState streamState, int device) { 4252 4253 synchronized (VolumeStreamState.class) { 4254 // Apply volume 4255 streamState.applyDeviceVolume_syncVSS(device); 4256 4257 // Apply change to all streams using this one as alias 4258 int numStreamTypes = AudioSystem.getNumStreamTypes(); 4259 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 4260 if (streamType != streamState.mStreamType && 4261 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 4262 // Make sure volume is also maxed out on A2DP device for aliased stream 4263 // that may have a different device selected 4264 int streamDevice = getDeviceForStream(streamType); 4265 if ((device != streamDevice) && mAvrcpAbsVolSupported && 4266 ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) { 4267 mStreamStates[streamType].applyDeviceVolume_syncVSS(device); 4268 } 4269 mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice); 4270 } 4271 } 4272 } 4273 // Post a persist volume msg 4274 sendMsg(mAudioHandler, 4275 MSG_PERSIST_VOLUME, 4276 SENDMSG_QUEUE, 4277 device, 4278 0, 4279 streamState, 4280 PERSIST_DELAY); 4281 4282 } 4283 setAllVolumes(VolumeStreamState streamState)4284 private void setAllVolumes(VolumeStreamState streamState) { 4285 4286 // Apply volume 4287 streamState.applyAllVolumes(); 4288 4289 // Apply change to all streams using this one as alias 4290 int numStreamTypes = AudioSystem.getNumStreamTypes(); 4291 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 4292 if (streamType != streamState.mStreamType && 4293 mStreamVolumeAlias[streamType] == streamState.mStreamType) { 4294 mStreamStates[streamType].applyAllVolumes(); 4295 } 4296 } 4297 } 4298 persistVolume(VolumeStreamState streamState, int device)4299 private void persistVolume(VolumeStreamState streamState, int device) { 4300 if (mUseFixedVolume) { 4301 return; 4302 } 4303 if (isPlatformTelevision() && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) { 4304 return; 4305 } 4306 System.putIntForUser(mContentResolver, 4307 streamState.getSettingNameForDevice(device), 4308 (streamState.getIndex(device) + 5)/ 10, 4309 UserHandle.USER_CURRENT); 4310 } 4311 persistRingerMode(int ringerMode)4312 private void persistRingerMode(int ringerMode) { 4313 if (mUseFixedVolume) { 4314 return; 4315 } 4316 Settings.Global.putInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode); 4317 } 4318 onLoadSoundEffects()4319 private boolean onLoadSoundEffects() { 4320 int status; 4321 4322 synchronized (mSoundEffectsLock) { 4323 if (!mSystemReady) { 4324 Log.w(TAG, "onLoadSoundEffects() called before boot complete"); 4325 return false; 4326 } 4327 4328 if (mSoundPool != null) { 4329 return true; 4330 } 4331 4332 loadTouchSoundAssets(); 4333 4334 mSoundPool = new SoundPool.Builder() 4335 .setMaxStreams(NUM_SOUNDPOOL_CHANNELS) 4336 .setAudioAttributes(new AudioAttributes.Builder() 4337 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) 4338 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 4339 .build()) 4340 .build(); 4341 mSoundPoolCallBack = null; 4342 mSoundPoolListenerThread = new SoundPoolListenerThread(); 4343 mSoundPoolListenerThread.start(); 4344 int attempts = 3; 4345 while ((mSoundPoolCallBack == null) && (attempts-- > 0)) { 4346 try { 4347 // Wait for mSoundPoolCallBack to be set by the other thread 4348 mSoundEffectsLock.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 4349 } catch (InterruptedException e) { 4350 Log.w(TAG, "Interrupted while waiting sound pool listener thread."); 4351 } 4352 } 4353 4354 if (mSoundPoolCallBack == null) { 4355 Log.w(TAG, "onLoadSoundEffects() SoundPool listener or thread creation error"); 4356 if (mSoundPoolLooper != null) { 4357 mSoundPoolLooper.quit(); 4358 mSoundPoolLooper = null; 4359 } 4360 mSoundPoolListenerThread = null; 4361 mSoundPool.release(); 4362 mSoundPool = null; 4363 return false; 4364 } 4365 /* 4366 * poolId table: The value -1 in this table indicates that corresponding 4367 * file (same index in SOUND_EFFECT_FILES[] has not been loaded. 4368 * Once loaded, the value in poolId is the sample ID and the same 4369 * sample can be reused for another effect using the same file. 4370 */ 4371 int[] poolId = new int[SOUND_EFFECT_FILES.size()]; 4372 for (int fileIdx = 0; fileIdx < SOUND_EFFECT_FILES.size(); fileIdx++) { 4373 poolId[fileIdx] = -1; 4374 } 4375 /* 4376 * Effects whose value in SOUND_EFFECT_FILES_MAP[effect][1] is -1 must be loaded. 4377 * If load succeeds, value in SOUND_EFFECT_FILES_MAP[effect][1] is > 0: 4378 * this indicates we have a valid sample loaded for this effect. 4379 */ 4380 4381 int numSamples = 0; 4382 for (int effect = 0; effect < AudioManager.NUM_SOUND_EFFECTS; effect++) { 4383 // Do not load sample if this effect uses the MediaPlayer 4384 if (SOUND_EFFECT_FILES_MAP[effect][1] == 0) { 4385 continue; 4386 } 4387 if (poolId[SOUND_EFFECT_FILES_MAP[effect][0]] == -1) { 4388 String filePath = Environment.getRootDirectory() 4389 + SOUND_EFFECTS_PATH 4390 + SOUND_EFFECT_FILES.get(SOUND_EFFECT_FILES_MAP[effect][0]); 4391 int sampleId = mSoundPool.load(filePath, 0); 4392 if (sampleId <= 0) { 4393 Log.w(TAG, "Soundpool could not load file: "+filePath); 4394 } else { 4395 SOUND_EFFECT_FILES_MAP[effect][1] = sampleId; 4396 poolId[SOUND_EFFECT_FILES_MAP[effect][0]] = sampleId; 4397 numSamples++; 4398 } 4399 } else { 4400 SOUND_EFFECT_FILES_MAP[effect][1] = 4401 poolId[SOUND_EFFECT_FILES_MAP[effect][0]]; 4402 } 4403 } 4404 // wait for all samples to be loaded 4405 if (numSamples > 0) { 4406 mSoundPoolCallBack.setSamples(poolId); 4407 4408 attempts = 3; 4409 status = 1; 4410 while ((status == 1) && (attempts-- > 0)) { 4411 try { 4412 mSoundEffectsLock.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 4413 status = mSoundPoolCallBack.status(); 4414 } catch (InterruptedException e) { 4415 Log.w(TAG, "Interrupted while waiting sound pool callback."); 4416 } 4417 } 4418 } else { 4419 status = -1; 4420 } 4421 4422 if (mSoundPoolLooper != null) { 4423 mSoundPoolLooper.quit(); 4424 mSoundPoolLooper = null; 4425 } 4426 mSoundPoolListenerThread = null; 4427 if (status != 0) { 4428 Log.w(TAG, 4429 "onLoadSoundEffects(), Error "+status+ " while loading samples"); 4430 for (int effect = 0; effect < AudioManager.NUM_SOUND_EFFECTS; effect++) { 4431 if (SOUND_EFFECT_FILES_MAP[effect][1] > 0) { 4432 SOUND_EFFECT_FILES_MAP[effect][1] = -1; 4433 } 4434 } 4435 4436 mSoundPool.release(); 4437 mSoundPool = null; 4438 } 4439 } 4440 return (status == 0); 4441 } 4442 4443 /** 4444 * Unloads samples from the sound pool. 4445 * This method can be called to free some memory when 4446 * sound effects are disabled. 4447 */ onUnloadSoundEffects()4448 private void onUnloadSoundEffects() { 4449 synchronized (mSoundEffectsLock) { 4450 if (mSoundPool == null) { 4451 return; 4452 } 4453 4454 int[] poolId = new int[SOUND_EFFECT_FILES.size()]; 4455 for (int fileIdx = 0; fileIdx < SOUND_EFFECT_FILES.size(); fileIdx++) { 4456 poolId[fileIdx] = 0; 4457 } 4458 4459 for (int effect = 0; effect < AudioManager.NUM_SOUND_EFFECTS; effect++) { 4460 if (SOUND_EFFECT_FILES_MAP[effect][1] <= 0) { 4461 continue; 4462 } 4463 if (poolId[SOUND_EFFECT_FILES_MAP[effect][0]] == 0) { 4464 mSoundPool.unload(SOUND_EFFECT_FILES_MAP[effect][1]); 4465 SOUND_EFFECT_FILES_MAP[effect][1] = -1; 4466 poolId[SOUND_EFFECT_FILES_MAP[effect][0]] = -1; 4467 } 4468 } 4469 mSoundPool.release(); 4470 mSoundPool = null; 4471 } 4472 } 4473 onPlaySoundEffect(int effectType, int volume)4474 private void onPlaySoundEffect(int effectType, int volume) { 4475 synchronized (mSoundEffectsLock) { 4476 4477 onLoadSoundEffects(); 4478 4479 if (mSoundPool == null) { 4480 return; 4481 } 4482 float volFloat; 4483 // use default if volume is not specified by caller 4484 if (volume < 0) { 4485 volFloat = (float)Math.pow(10, (float)sSoundEffectVolumeDb/20); 4486 } else { 4487 volFloat = volume / 1000.0f; 4488 } 4489 4490 if (SOUND_EFFECT_FILES_MAP[effectType][1] > 0) { 4491 mSoundPool.play(SOUND_EFFECT_FILES_MAP[effectType][1], 4492 volFloat, volFloat, 0, 0, 1.0f); 4493 } else { 4494 MediaPlayer mediaPlayer = new MediaPlayer(); 4495 try { 4496 String filePath = Environment.getRootDirectory() + SOUND_EFFECTS_PATH + 4497 SOUND_EFFECT_FILES.get(SOUND_EFFECT_FILES_MAP[effectType][0]); 4498 mediaPlayer.setDataSource(filePath); 4499 mediaPlayer.setAudioStreamType(AudioSystem.STREAM_SYSTEM); 4500 mediaPlayer.prepare(); 4501 mediaPlayer.setVolume(volFloat); 4502 mediaPlayer.setOnCompletionListener(new OnCompletionListener() { 4503 public void onCompletion(MediaPlayer mp) { 4504 cleanupPlayer(mp); 4505 } 4506 }); 4507 mediaPlayer.setOnErrorListener(new OnErrorListener() { 4508 public boolean onError(MediaPlayer mp, int what, int extra) { 4509 cleanupPlayer(mp); 4510 return true; 4511 } 4512 }); 4513 mediaPlayer.start(); 4514 } catch (IOException ex) { 4515 Log.w(TAG, "MediaPlayer IOException: "+ex); 4516 } catch (IllegalArgumentException ex) { 4517 Log.w(TAG, "MediaPlayer IllegalArgumentException: "+ex); 4518 } catch (IllegalStateException ex) { 4519 Log.w(TAG, "MediaPlayer IllegalStateException: "+ex); 4520 } 4521 } 4522 } 4523 } 4524 cleanupPlayer(MediaPlayer mp)4525 private void cleanupPlayer(MediaPlayer mp) { 4526 if (mp != null) { 4527 try { 4528 mp.stop(); 4529 mp.release(); 4530 } catch (IllegalStateException ex) { 4531 Log.w(TAG, "MediaPlayer IllegalStateException: "+ex); 4532 } 4533 } 4534 } 4535 setForceUse(int usage, int config)4536 private void setForceUse(int usage, int config) { 4537 synchronized (mConnectedDevices) { 4538 setForceUseInt_SyncDevices(usage, config); 4539 } 4540 } 4541 onPersistSafeVolumeState(int state)4542 private void onPersistSafeVolumeState(int state) { 4543 Settings.Global.putInt(mContentResolver, 4544 Settings.Global.AUDIO_SAFE_VOLUME_STATE, 4545 state); 4546 } 4547 4548 @Override handleMessage(Message msg)4549 public void handleMessage(Message msg) { 4550 switch (msg.what) { 4551 4552 case MSG_SET_DEVICE_VOLUME: 4553 setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1); 4554 break; 4555 4556 case MSG_SET_ALL_VOLUMES: 4557 setAllVolumes((VolumeStreamState) msg.obj); 4558 break; 4559 4560 case MSG_PERSIST_VOLUME: 4561 persistVolume((VolumeStreamState) msg.obj, msg.arg1); 4562 break; 4563 4564 case MSG_PERSIST_RINGER_MODE: 4565 // note that the value persisted is the current ringer mode, not the 4566 // value of ringer mode as of the time the request was made to persist 4567 persistRingerMode(getRingerModeInternal()); 4568 break; 4569 4570 case MSG_AUDIO_SERVER_DIED: 4571 onAudioServerDied(); 4572 break; 4573 4574 case MSG_UNLOAD_SOUND_EFFECTS: 4575 onUnloadSoundEffects(); 4576 break; 4577 4578 case MSG_LOAD_SOUND_EFFECTS: 4579 //FIXME: onLoadSoundEffects() should be executed in a separate thread as it 4580 // can take several dozens of milliseconds to complete 4581 boolean loaded = onLoadSoundEffects(); 4582 if (msg.obj != null) { 4583 LoadSoundEffectReply reply = (LoadSoundEffectReply)msg.obj; 4584 synchronized (reply) { 4585 reply.mStatus = loaded ? 0 : -1; 4586 reply.notify(); 4587 } 4588 } 4589 break; 4590 4591 case MSG_PLAY_SOUND_EFFECT: 4592 onPlaySoundEffect(msg.arg1, msg.arg2); 4593 break; 4594 4595 case MSG_BTA2DP_DOCK_TIMEOUT: 4596 // msg.obj == address of BTA2DP device 4597 synchronized (mConnectedDevices) { 4598 makeA2dpDeviceUnavailableNow( (String) msg.obj ); 4599 } 4600 break; 4601 4602 case MSG_SET_FORCE_USE: 4603 case MSG_SET_FORCE_BT_A2DP_USE: 4604 setForceUse(msg.arg1, msg.arg2); 4605 break; 4606 4607 case MSG_BT_HEADSET_CNCT_FAILED: 4608 resetBluetoothSco(); 4609 break; 4610 4611 case MSG_SET_WIRED_DEVICE_CONNECTION_STATE: 4612 { WiredDeviceConnectionState connectState = 4613 (WiredDeviceConnectionState)msg.obj; 4614 onSetWiredDeviceConnectionState(connectState.mType, connectState.mState, 4615 connectState.mAddress, connectState.mName, connectState.mCaller); 4616 mAudioEventWakeLock.release(); 4617 } 4618 break; 4619 4620 case MSG_SET_A2DP_SRC_CONNECTION_STATE: 4621 onSetA2dpSourceConnectionState((BluetoothDevice)msg.obj, msg.arg1); 4622 mAudioEventWakeLock.release(); 4623 break; 4624 4625 case MSG_SET_A2DP_SINK_CONNECTION_STATE: 4626 onSetA2dpSinkConnectionState((BluetoothDevice)msg.obj, msg.arg1); 4627 mAudioEventWakeLock.release(); 4628 break; 4629 4630 case MSG_REPORT_NEW_ROUTES: { 4631 int N = mRoutesObservers.beginBroadcast(); 4632 if (N > 0) { 4633 AudioRoutesInfo routes; 4634 synchronized (mCurAudioRoutes) { 4635 routes = new AudioRoutesInfo(mCurAudioRoutes); 4636 } 4637 while (N > 0) { 4638 N--; 4639 IAudioRoutesObserver obs = mRoutesObservers.getBroadcastItem(N); 4640 try { 4641 obs.dispatchAudioRoutesChanged(routes); 4642 } catch (RemoteException e) { 4643 } 4644 } 4645 } 4646 mRoutesObservers.finishBroadcast(); 4647 observeDevicesForStreams(-1); 4648 break; 4649 } 4650 4651 case MSG_CHECK_MUSIC_ACTIVE: 4652 onCheckMusicActive((String) msg.obj); 4653 break; 4654 4655 case MSG_BROADCAST_AUDIO_BECOMING_NOISY: 4656 onSendBecomingNoisyIntent(); 4657 break; 4658 4659 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED: 4660 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME: 4661 onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED), 4662 (String) msg.obj); 4663 break; 4664 case MSG_PERSIST_SAFE_VOLUME_STATE: 4665 onPersistSafeVolumeState(msg.arg1); 4666 break; 4667 4668 case MSG_BROADCAST_BT_CONNECTION_STATE: 4669 onBroadcastScoConnectionState(msg.arg1); 4670 break; 4671 4672 case MSG_SYSTEM_READY: 4673 onSystemReady(); 4674 break; 4675 4676 case MSG_INDICATE_SYSTEM_READY: 4677 onIndicateSystemReady(); 4678 break; 4679 4680 case MSG_PERSIST_MUSIC_ACTIVE_MS: 4681 final int musicActiveMs = msg.arg1; 4682 Settings.Secure.putIntForUser(mContentResolver, 4683 Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, musicActiveMs, 4684 UserHandle.USER_CURRENT); 4685 break; 4686 4687 case MSG_UNMUTE_STREAM: 4688 onUnmuteStream(msg.arg1, msg.arg2); 4689 break; 4690 4691 case MSG_DYN_POLICY_MIX_STATE_UPDATE: 4692 onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1); 4693 break; 4694 } 4695 } 4696 } 4697 4698 private class SettingsObserver extends ContentObserver { 4699 4700 private int mEncodedSurroundMode; 4701 SettingsObserver()4702 SettingsObserver() { 4703 super(new Handler()); 4704 mContentResolver.registerContentObserver(Settings.System.getUriFor( 4705 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); 4706 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 4707 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); 4708 mContentResolver.registerContentObserver(Settings.System.getUriFor( 4709 Settings.System.MASTER_MONO), false, this); 4710 4711 mEncodedSurroundMode = Settings.Global.getInt( 4712 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 4713 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 4714 mContentResolver.registerContentObserver(Settings.Global.getUriFor( 4715 Settings.Global.ENCODED_SURROUND_OUTPUT), false, this); 4716 } 4717 4718 @Override onChange(boolean selfChange)4719 public void onChange(boolean selfChange) { 4720 super.onChange(selfChange); 4721 // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode. 4722 // However there appear to be some missing locks around mRingerModeMutedStreams 4723 // and mRingerModeAffectedStreams, so will leave this synchronized for now. 4724 // mRingerModeMutedStreams and mMuteAffectedStreams are safe (only accessed once). 4725 synchronized (mSettingsLock) { 4726 if (updateRingerModeAffectedStreams()) { 4727 /* 4728 * Ensure all stream types that should be affected by ringer mode 4729 * are in the proper state. 4730 */ 4731 setRingerModeInt(getRingerModeInternal(), false); 4732 } 4733 readDockAudioSettings(mContentResolver); 4734 updateMasterMono(mContentResolver); 4735 updateEncodedSurroundOutput(); 4736 } 4737 } 4738 updateEncodedSurroundOutput()4739 private void updateEncodedSurroundOutput() { 4740 int newSurroundMode = Settings.Global.getInt( 4741 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, 4742 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 4743 // Did it change? 4744 if (mEncodedSurroundMode != newSurroundMode) { 4745 // Send to AudioPolicyManager 4746 sendEncodedSurroundMode(newSurroundMode); 4747 synchronized(mConnectedDevices) { 4748 // Is HDMI connected? 4749 String key = makeDeviceListKey(AudioSystem.DEVICE_OUT_HDMI, ""); 4750 DeviceListSpec deviceSpec = mConnectedDevices.get(key); 4751 if (deviceSpec != null) { 4752 // Toggle HDMI to retrigger broadcast with proper formats. 4753 setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_HDMI, 4754 AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "", 4755 "android"); // disconnect 4756 setWiredDeviceConnectionState(AudioSystem.DEVICE_OUT_HDMI, 4757 AudioSystem.DEVICE_STATE_AVAILABLE, "", "", 4758 "android"); // reconnect 4759 } 4760 } 4761 mEncodedSurroundMode = newSurroundMode; 4762 } 4763 } 4764 } 4765 4766 // must be called synchronized on mConnectedDevices makeA2dpDeviceAvailable(String address, String name)4767 private void makeA2dpDeviceAvailable(String address, String name) { 4768 // enable A2DP before notifying A2DP connection to avoid unecessary processing in 4769 // audio policy manager 4770 VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC]; 4771 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 4772 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, streamState, 0); 4773 setBluetoothA2dpOnInt(true); 4774 AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 4775 AudioSystem.DEVICE_STATE_AVAILABLE, address, name); 4776 // Reset A2DP suspend state each time a new sink is connected 4777 AudioSystem.setParameters("A2dpSuspended=false"); 4778 mConnectedDevices.put( 4779 makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address), 4780 new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name, 4781 address)); 4782 } 4783 onSendBecomingNoisyIntent()4784 private void onSendBecomingNoisyIntent() { 4785 sendBroadcastToAll(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY)); 4786 } 4787 4788 // must be called synchronized on mConnectedDevices makeA2dpDeviceUnavailableNow(String address)4789 private void makeA2dpDeviceUnavailableNow(String address) { 4790 synchronized (mA2dpAvrcpLock) { 4791 mAvrcpAbsVolSupported = false; 4792 } 4793 AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 4794 AudioSystem.DEVICE_STATE_UNAVAILABLE, address, ""); 4795 mConnectedDevices.remove( 4796 makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address)); 4797 synchronized (mCurAudioRoutes) { 4798 // Remove A2DP routes as well 4799 if (mCurAudioRoutes.bluetoothName != null) { 4800 mCurAudioRoutes.bluetoothName = null; 4801 sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, 4802 SENDMSG_NOOP, 0, 0, null, 0); 4803 } 4804 } 4805 } 4806 4807 // must be called synchronized on mConnectedDevices makeA2dpDeviceUnavailableLater(String address, int delayMs)4808 private void makeA2dpDeviceUnavailableLater(String address, int delayMs) { 4809 // prevent any activity on the A2DP audio output to avoid unwanted 4810 // reconnection of the sink. 4811 AudioSystem.setParameters("A2dpSuspended=true"); 4812 // the device will be made unavailable later, so consider it disconnected right away 4813 mConnectedDevices.remove( 4814 makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address)); 4815 // send the delayed message to make the device unavailable later 4816 Message msg = mAudioHandler.obtainMessage(MSG_BTA2DP_DOCK_TIMEOUT, address); 4817 mAudioHandler.sendMessageDelayed(msg, delayMs); 4818 4819 } 4820 4821 // must be called synchronized on mConnectedDevices makeA2dpSrcAvailable(String address)4822 private void makeA2dpSrcAvailable(String address) { 4823 AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, 4824 AudioSystem.DEVICE_STATE_AVAILABLE, address, ""); 4825 mConnectedDevices.put( 4826 makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address), 4827 new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, "", 4828 address)); 4829 } 4830 4831 // must be called synchronized on mConnectedDevices makeA2dpSrcUnavailable(String address)4832 private void makeA2dpSrcUnavailable(String address) { 4833 AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, 4834 AudioSystem.DEVICE_STATE_UNAVAILABLE, address, ""); 4835 mConnectedDevices.remove( 4836 makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address)); 4837 } 4838 4839 // must be called synchronized on mConnectedDevices cancelA2dpDeviceTimeout()4840 private void cancelA2dpDeviceTimeout() { 4841 mAudioHandler.removeMessages(MSG_BTA2DP_DOCK_TIMEOUT); 4842 } 4843 4844 // must be called synchronized on mConnectedDevices hasScheduledA2dpDockTimeout()4845 private boolean hasScheduledA2dpDockTimeout() { 4846 return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT); 4847 } 4848 onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state)4849 private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state) 4850 { 4851 if (DEBUG_VOL) { 4852 Log.d(TAG, "onSetA2dpSinkConnectionState btDevice="+btDevice+"state="+state); 4853 } 4854 if (btDevice == null) { 4855 return; 4856 } 4857 String address = btDevice.getAddress(); 4858 if (!BluetoothAdapter.checkBluetoothAddress(address)) { 4859 address = ""; 4860 } 4861 4862 synchronized (mConnectedDevices) { 4863 String key = makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 4864 btDevice.getAddress()); 4865 DeviceListSpec deviceSpec = mConnectedDevices.get(key); 4866 boolean isConnected = deviceSpec != null; 4867 4868 if (isConnected && state != BluetoothProfile.STATE_CONNECTED) { 4869 if (btDevice.isBluetoothDock()) { 4870 if (state == BluetoothProfile.STATE_DISCONNECTED) { 4871 // introduction of a delay for transient disconnections of docks when 4872 // power is rapidly turned off/on, this message will be canceled if 4873 // we reconnect the dock under a preset delay 4874 makeA2dpDeviceUnavailableLater(address, BTA2DP_DOCK_TIMEOUT_MILLIS); 4875 // the next time isConnected is evaluated, it will be false for the dock 4876 } 4877 } else { 4878 makeA2dpDeviceUnavailableNow(address); 4879 } 4880 synchronized (mCurAudioRoutes) { 4881 if (mCurAudioRoutes.bluetoothName != null) { 4882 mCurAudioRoutes.bluetoothName = null; 4883 sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, 4884 SENDMSG_NOOP, 0, 0, null, 0); 4885 } 4886 } 4887 } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) { 4888 if (btDevice.isBluetoothDock()) { 4889 // this could be a reconnection after a transient disconnection 4890 cancelA2dpDeviceTimeout(); 4891 mDockAddress = address; 4892 } else { 4893 // this could be a connection of another A2DP device before the timeout of 4894 // a dock: cancel the dock timeout, and make the dock unavailable now 4895 if(hasScheduledA2dpDockTimeout()) { 4896 cancelA2dpDeviceTimeout(); 4897 makeA2dpDeviceUnavailableNow(mDockAddress); 4898 } 4899 } 4900 makeA2dpDeviceAvailable(address, btDevice.getName()); 4901 synchronized (mCurAudioRoutes) { 4902 String name = btDevice.getAliasName(); 4903 if (!TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) { 4904 mCurAudioRoutes.bluetoothName = name; 4905 sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, 4906 SENDMSG_NOOP, 0, 0, null, 0); 4907 } 4908 } 4909 } 4910 } 4911 } 4912 onSetA2dpSourceConnectionState(BluetoothDevice btDevice, int state)4913 private void onSetA2dpSourceConnectionState(BluetoothDevice btDevice, int state) 4914 { 4915 if (DEBUG_VOL) { 4916 Log.d(TAG, "onSetA2dpSourceConnectionState btDevice="+btDevice+" state="+state); 4917 } 4918 if (btDevice == null) { 4919 return; 4920 } 4921 String address = btDevice.getAddress(); 4922 if (!BluetoothAdapter.checkBluetoothAddress(address)) { 4923 address = ""; 4924 } 4925 4926 synchronized (mConnectedDevices) { 4927 String key = makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address); 4928 DeviceListSpec deviceSpec = mConnectedDevices.get(key); 4929 boolean isConnected = deviceSpec != null; 4930 4931 if (isConnected && state != BluetoothProfile.STATE_CONNECTED) { 4932 makeA2dpSrcUnavailable(address); 4933 } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) { 4934 makeA2dpSrcAvailable(address); 4935 } 4936 } 4937 } 4938 avrcpSupportsAbsoluteVolume(String address, boolean support)4939 public void avrcpSupportsAbsoluteVolume(String address, boolean support) { 4940 // address is not used for now, but may be used when multiple a2dp devices are supported 4941 synchronized (mA2dpAvrcpLock) { 4942 mAvrcpAbsVolSupported = support; 4943 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 4944 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, 4945 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 4946 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, 4947 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, 4948 mStreamStates[AudioSystem.STREAM_RING], 0); 4949 } 4950 } 4951 handleDeviceConnection(boolean connect, int device, String address, String deviceName)4952 private boolean handleDeviceConnection(boolean connect, int device, String address, 4953 String deviceName) { 4954 if (DEBUG_DEVICES) { 4955 Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:" + Integer.toHexString(device) 4956 + " address:" + address + " name:" + deviceName + ")"); 4957 } 4958 synchronized (mConnectedDevices) { 4959 String deviceKey = makeDeviceListKey(device, address); 4960 if (DEBUG_DEVICES) { 4961 Slog.i(TAG, "deviceKey:" + deviceKey); 4962 } 4963 DeviceListSpec deviceSpec = mConnectedDevices.get(deviceKey); 4964 boolean isConnected = deviceSpec != null; 4965 if (DEBUG_DEVICES) { 4966 Slog.i(TAG, "deviceSpec:" + deviceSpec + " is(already)Connected:" + isConnected); 4967 } 4968 if (connect && !isConnected) { 4969 final int res = AudioSystem.setDeviceConnectionState(device, 4970 AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName); 4971 if (res != AudioSystem.AUDIO_STATUS_OK) { 4972 Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device) + 4973 " due to command error " + res ); 4974 return false; 4975 } 4976 mConnectedDevices.put(deviceKey, new DeviceListSpec(device, deviceName, address)); 4977 return true; 4978 } else if (!connect && isConnected) { 4979 AudioSystem.setDeviceConnectionState(device, 4980 AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName); 4981 // always remove even if disconnection failed 4982 mConnectedDevices.remove(deviceKey); 4983 return true; 4984 } 4985 } 4986 return false; 4987 } 4988 4989 // Devices which removal triggers intent ACTION_AUDIO_BECOMING_NOISY. The intent is only 4990 // sent if none of these devices is connected. 4991 // Access synchronized on mConnectedDevices 4992 int mBecomingNoisyIntentDevices = 4993 AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE | 4994 AudioSystem.DEVICE_OUT_ALL_A2DP | AudioSystem.DEVICE_OUT_HDMI | 4995 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET | AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET | 4996 AudioSystem.DEVICE_OUT_ALL_USB | AudioSystem.DEVICE_OUT_LINE; 4997 4998 // must be called before removing the device from mConnectedDevices 4999 // Called synchronized on mConnectedDevices checkSendBecomingNoisyIntent(int device, int state)5000 private int checkSendBecomingNoisyIntent(int device, int state) { 5001 int delay = 0; 5002 if ((state == 0) && ((device & mBecomingNoisyIntentDevices) != 0)) { 5003 int devices = 0; 5004 for (int i = 0; i < mConnectedDevices.size(); i++) { 5005 int dev = mConnectedDevices.valueAt(i).mDeviceType; 5006 if (((dev & AudioSystem.DEVICE_BIT_IN) == 0) 5007 && ((dev & mBecomingNoisyIntentDevices) != 0)) { 5008 devices |= dev; 5009 } 5010 } 5011 if (devices == device) { 5012 sendMsg(mAudioHandler, 5013 MSG_BROADCAST_AUDIO_BECOMING_NOISY, 5014 SENDMSG_REPLACE, 5015 0, 5016 0, 5017 null, 5018 0); 5019 delay = 1000; 5020 } 5021 } 5022 5023 if (mAudioHandler.hasMessages(MSG_SET_A2DP_SRC_CONNECTION_STATE) || 5024 mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE) || 5025 mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) { 5026 synchronized (mLastDeviceConnectMsgTime) { 5027 long time = SystemClock.uptimeMillis(); 5028 if (mLastDeviceConnectMsgTime > time) { 5029 delay = (int)(mLastDeviceConnectMsgTime - time) + 30; 5030 } 5031 } 5032 } 5033 return delay; 5034 } 5035 sendDeviceConnectionIntent(int device, int state, String address, String deviceName)5036 private void sendDeviceConnectionIntent(int device, int state, String address, 5037 String deviceName) { 5038 if (DEBUG_DEVICES) { 5039 Slog.i(TAG, "sendDeviceConnectionIntent(dev:0x" + Integer.toHexString(device) + 5040 " state:0x" + Integer.toHexString(state) + " address:" + address + 5041 " name:" + deviceName + ");"); 5042 } 5043 Intent intent = new Intent(); 5044 5045 intent.putExtra(CONNECT_INTENT_KEY_STATE, state); 5046 intent.putExtra(CONNECT_INTENT_KEY_ADDRESS, address); 5047 intent.putExtra(CONNECT_INTENT_KEY_PORT_NAME, deviceName); 5048 5049 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 5050 5051 int connType = 0; 5052 5053 if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) { 5054 connType = AudioRoutesInfo.MAIN_HEADSET; 5055 intent.setAction(Intent.ACTION_HEADSET_PLUG); 5056 intent.putExtra("microphone", 1); 5057 } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE || 5058 device == AudioSystem.DEVICE_OUT_LINE) { 5059 /*do apps care about line-out vs headphones?*/ 5060 connType = AudioRoutesInfo.MAIN_HEADPHONES; 5061 intent.setAction(Intent.ACTION_HEADSET_PLUG); 5062 intent.putExtra("microphone", 0); 5063 } else if (device == AudioSystem.DEVICE_OUT_HDMI || 5064 device == AudioSystem.DEVICE_OUT_HDMI_ARC) { 5065 connType = AudioRoutesInfo.MAIN_HDMI; 5066 configureHdmiPlugIntent(intent, state); 5067 } else if (device == AudioSystem.DEVICE_OUT_USB_DEVICE) { 5068 connType = AudioRoutesInfo.MAIN_USB; 5069 } 5070 5071 synchronized (mCurAudioRoutes) { 5072 if (connType != 0) { 5073 int newConn = mCurAudioRoutes.mainType; 5074 if (state != 0) { 5075 newConn |= connType; 5076 } else { 5077 newConn &= ~connType; 5078 } 5079 if (newConn != mCurAudioRoutes.mainType) { 5080 mCurAudioRoutes.mainType = newConn; 5081 sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, 5082 SENDMSG_NOOP, 0, 0, null, 0); 5083 } 5084 } 5085 } 5086 5087 final long ident = Binder.clearCallingIdentity(); 5088 try { 5089 ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL); 5090 } finally { 5091 Binder.restoreCallingIdentity(ident); 5092 } 5093 } 5094 onSetWiredDeviceConnectionState(int device, int state, String address, String deviceName, String caller)5095 private void onSetWiredDeviceConnectionState(int device, int state, String address, 5096 String deviceName, String caller) { 5097 if (DEBUG_DEVICES) { 5098 Slog.i(TAG, "onSetWiredDeviceConnectionState(dev:" + Integer.toHexString(device) 5099 + " state:" + Integer.toHexString(state) 5100 + " address:" + address 5101 + " deviceName:" + deviceName 5102 + " caller: " + caller + ");"); 5103 } 5104 5105 synchronized (mConnectedDevices) { 5106 if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) || 5107 (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) || 5108 (device == AudioSystem.DEVICE_OUT_LINE))) { 5109 setBluetoothA2dpOnInt(true); 5110 } 5111 boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) || 5112 (((device & AudioSystem.DEVICE_BIT_IN) != 0) && 5113 ((device & ~AudioSystem.DEVICE_IN_ALL_USB) == 0)); 5114 if (!handleDeviceConnection(state == 1, device, address, deviceName)) { 5115 // change of connection state failed, bailout 5116 return; 5117 } 5118 if (state != 0) { 5119 if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) || 5120 (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) || 5121 (device == AudioSystem.DEVICE_OUT_LINE)) { 5122 setBluetoothA2dpOnInt(false); 5123 } 5124 if ((device & mSafeMediaVolumeDevices) != 0) { 5125 sendMsg(mAudioHandler, 5126 MSG_CHECK_MUSIC_ACTIVE, 5127 SENDMSG_REPLACE, 5128 0, 5129 0, 5130 caller, 5131 MUSIC_ACTIVE_POLL_PERIOD_MS); 5132 } 5133 // Television devices without CEC service apply software volume on HDMI output 5134 if (isPlatformTelevision() && ((device & AudioSystem.DEVICE_OUT_HDMI) != 0)) { 5135 mFixedVolumeDevices |= AudioSystem.DEVICE_OUT_HDMI; 5136 checkAllFixedVolumeDevices(); 5137 if (mHdmiManager != null) { 5138 synchronized (mHdmiManager) { 5139 if (mHdmiPlaybackClient != null) { 5140 mHdmiCecSink = false; 5141 mHdmiPlaybackClient.queryDisplayStatus(mHdmiDisplayStatusCallback); 5142 } 5143 } 5144 } 5145 } 5146 } else { 5147 if (isPlatformTelevision() && ((device & AudioSystem.DEVICE_OUT_HDMI) != 0)) { 5148 if (mHdmiManager != null) { 5149 synchronized (mHdmiManager) { 5150 mHdmiCecSink = false; 5151 } 5152 } 5153 } 5154 } 5155 if (!isUsb && device != AudioSystem.DEVICE_IN_WIRED_HEADSET) { 5156 sendDeviceConnectionIntent(device, state, address, deviceName); 5157 } 5158 } 5159 } 5160 configureHdmiPlugIntent(Intent intent, int state)5161 private void configureHdmiPlugIntent(Intent intent, int state) { 5162 intent.setAction(AudioManager.ACTION_HDMI_AUDIO_PLUG); 5163 intent.putExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, state); 5164 if (state == 1) { 5165 ArrayList<AudioPort> ports = new ArrayList<AudioPort>(); 5166 int[] portGeneration = new int[1]; 5167 int status = AudioSystem.listAudioPorts(ports, portGeneration); 5168 if (status == AudioManager.SUCCESS) { 5169 for (AudioPort port : ports) { 5170 if (port instanceof AudioDevicePort) { 5171 final AudioDevicePort devicePort = (AudioDevicePort) port; 5172 if (devicePort.type() == AudioManager.DEVICE_OUT_HDMI || 5173 devicePort.type() == AudioManager.DEVICE_OUT_HDMI_ARC) { 5174 // format the list of supported encodings 5175 int[] formats = AudioFormat.filterPublicFormats(devicePort.formats()); 5176 if (formats.length > 0) { 5177 ArrayList<Integer> encodingList = new ArrayList(1); 5178 for (int format : formats) { 5179 // a format in the list can be 0, skip it 5180 if (format != AudioFormat.ENCODING_INVALID) { 5181 encodingList.add(format); 5182 } 5183 } 5184 int[] encodingArray = new int[encodingList.size()]; 5185 for (int i = 0 ; i < encodingArray.length ; i++) { 5186 encodingArray[i] = encodingList.get(i); 5187 } 5188 intent.putExtra(AudioManager.EXTRA_ENCODINGS, encodingArray); 5189 } 5190 // find the maximum supported number of channels 5191 int maxChannels = 0; 5192 for (int mask : devicePort.channelMasks()) { 5193 int channelCount = AudioFormat.channelCountFromOutChannelMask(mask); 5194 if (channelCount > maxChannels) { 5195 maxChannels = channelCount; 5196 } 5197 } 5198 intent.putExtra(AudioManager.EXTRA_MAX_CHANNEL_COUNT, maxChannels); 5199 } 5200 } 5201 } 5202 } 5203 } 5204 } 5205 5206 /* cache of the address of the last dock the device was connected to */ 5207 private String mDockAddress; 5208 5209 /** 5210 * Receiver for misc intent broadcasts the Phone app cares about. 5211 */ 5212 private class AudioServiceBroadcastReceiver extends BroadcastReceiver { 5213 @Override onReceive(Context context, Intent intent)5214 public void onReceive(Context context, Intent intent) { 5215 String action = intent.getAction(); 5216 int outDevice; 5217 int inDevice; 5218 int state; 5219 5220 if (action.equals(Intent.ACTION_DOCK_EVENT)) { 5221 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 5222 Intent.EXTRA_DOCK_STATE_UNDOCKED); 5223 int config; 5224 switch (dockState) { 5225 case Intent.EXTRA_DOCK_STATE_DESK: 5226 config = AudioSystem.FORCE_BT_DESK_DOCK; 5227 break; 5228 case Intent.EXTRA_DOCK_STATE_CAR: 5229 config = AudioSystem.FORCE_BT_CAR_DOCK; 5230 break; 5231 case Intent.EXTRA_DOCK_STATE_LE_DESK: 5232 config = AudioSystem.FORCE_ANALOG_DOCK; 5233 break; 5234 case Intent.EXTRA_DOCK_STATE_HE_DESK: 5235 config = AudioSystem.FORCE_DIGITAL_DOCK; 5236 break; 5237 case Intent.EXTRA_DOCK_STATE_UNDOCKED: 5238 default: 5239 config = AudioSystem.FORCE_NONE; 5240 } 5241 // Low end docks have a menu to enable or disable audio 5242 // (see mDockAudioMediaEnabled) 5243 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) || 5244 ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) && 5245 (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) { 5246 AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); 5247 } 5248 mDockState = dockState; 5249 } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { 5250 state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 5251 BluetoothProfile.STATE_DISCONNECTED); 5252 BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 5253 5254 setBtScoDeviceConnectionState(btDevice, state); 5255 } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { 5256 boolean broadcast = false; 5257 int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; 5258 synchronized (mScoClients) { 5259 int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); 5260 // broadcast intent if the connection was initated by AudioService 5261 if (!mScoClients.isEmpty() && 5262 (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL || 5263 mScoAudioState == SCO_STATE_ACTIVATE_REQ || 5264 mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) { 5265 broadcast = true; 5266 } 5267 switch (btState) { 5268 case BluetoothHeadset.STATE_AUDIO_CONNECTED: 5269 scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED; 5270 if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL && 5271 mScoAudioState != SCO_STATE_DEACTIVATE_REQ && 5272 mScoAudioState != SCO_STATE_DEACTIVATE_EXT_REQ) { 5273 mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; 5274 } 5275 break; 5276 case BluetoothHeadset.STATE_AUDIO_DISCONNECTED: 5277 scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED; 5278 mScoAudioState = SCO_STATE_INACTIVE; 5279 clearAllScoClients(0, false); 5280 break; 5281 case BluetoothHeadset.STATE_AUDIO_CONNECTING: 5282 if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL && 5283 mScoAudioState != SCO_STATE_DEACTIVATE_REQ && 5284 mScoAudioState != SCO_STATE_DEACTIVATE_EXT_REQ) { 5285 mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; 5286 } 5287 default: 5288 // do not broadcast CONNECTING or invalid state 5289 broadcast = false; 5290 break; 5291 } 5292 } 5293 if (broadcast) { 5294 broadcastScoConnectionState(scoAudioState); 5295 //FIXME: this is to maintain compatibility with deprecated intent 5296 // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate. 5297 Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED); 5298 newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, scoAudioState); 5299 sendStickyBroadcastToAll(newIntent); 5300 } 5301 } else if (action.equals(Intent.ACTION_SCREEN_ON)) { 5302 if (mMonitorRotation) { 5303 RotationHelper.enable(); 5304 } 5305 AudioSystem.setParameters("screen_state=on"); 5306 } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 5307 if (mMonitorRotation) { 5308 //reduce wakeups (save current) by only listening when display is on 5309 RotationHelper.disable(); 5310 } 5311 AudioSystem.setParameters("screen_state=off"); 5312 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 5313 handleConfigurationChanged(context); 5314 } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { 5315 if (mUserSwitchedReceived) { 5316 // attempt to stop music playback for background user except on first user 5317 // switch (i.e. first boot) 5318 sendMsg(mAudioHandler, 5319 MSG_BROADCAST_AUDIO_BECOMING_NOISY, 5320 SENDMSG_REPLACE, 5321 0, 5322 0, 5323 null, 5324 0); 5325 } 5326 mUserSwitchedReceived = true; 5327 // the current audio focus owner is no longer valid 5328 mMediaFocusControl.discardAudioFocusOwner(); 5329 5330 // load volume settings for new user 5331 readAudioSettings(true /*userSwitch*/); 5332 // preserve STREAM_MUSIC volume from one user to the next. 5333 sendMsg(mAudioHandler, 5334 MSG_SET_ALL_VOLUMES, 5335 SENDMSG_QUEUE, 5336 0, 5337 0, 5338 mStreamStates[AudioSystem.STREAM_MUSIC], 0); 5339 } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) { 5340 // Disable audio recording for the background user/profile 5341 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 5342 if (userId >= 0) { 5343 // TODO Kill recording streams instead of killing processes holding permission 5344 UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId); 5345 killBackgroundUserProcessesWithRecordAudioPermission(userInfo); 5346 } 5347 UserManagerService.getInstance().setUserRestriction( 5348 UserManager.DISALLOW_RECORD_AUDIO, true, userId); 5349 } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) { 5350 // Enable audio recording for foreground user/profile 5351 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 5352 UserManagerService.getInstance().setUserRestriction( 5353 UserManager.DISALLOW_RECORD_AUDIO, false, userId); 5354 } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 5355 state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 5356 if (state == BluetoothAdapter.STATE_OFF || 5357 state == BluetoothAdapter.STATE_TURNING_OFF) { 5358 disconnectAllBluetoothProfiles(); 5359 } 5360 } 5361 } 5362 } // end class AudioServiceBroadcastReceiver 5363 5364 private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener { 5365 5366 @Override onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)5367 public void onUserRestrictionsChanged(int userId, Bundle newRestrictions, 5368 Bundle prevRestrictions) { 5369 // Update mic mute state. 5370 { 5371 final boolean wasRestricted = 5372 prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 5373 final boolean isRestricted = 5374 newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE); 5375 if (wasRestricted != isRestricted) { 5376 setMicrophoneMuteNoCallerCheck(isRestricted, userId); 5377 } 5378 } 5379 5380 // Update speaker mute state. 5381 { 5382 final boolean wasRestricted = 5383 prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME); 5384 final boolean isRestricted = 5385 newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME); 5386 if (wasRestricted != isRestricted) { 5387 setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId); 5388 } 5389 } 5390 } 5391 } // end class AudioServiceUserRestrictionsListener 5392 killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)5393 private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) { 5394 PackageManager pm = mContext.getPackageManager(); 5395 // Find the home activity of the user. It should not be killed to avoid expensive restart, 5396 // when the user switches back. For managed profiles, we should kill all recording apps 5397 ComponentName homeActivityName = null; 5398 if (!oldUser.isManagedProfile()) { 5399 homeActivityName = LocalServices.getService(ActivityManagerInternal.class) 5400 .getHomeActivityForUser(oldUser.id); 5401 } 5402 final String[] permissions = { Manifest.permission.RECORD_AUDIO }; 5403 List<PackageInfo> packages; 5404 try { 5405 packages = AppGlobals.getPackageManager() 5406 .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList(); 5407 } catch (RemoteException e) { 5408 throw new AndroidRuntimeException(e); 5409 } 5410 for (int j = packages.size() - 1; j >= 0; j--) { 5411 PackageInfo pkg = packages.get(j); 5412 // Skip system processes 5413 if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { 5414 continue; 5415 } 5416 // Skip packages that have permission to interact across users 5417 if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName) 5418 == PackageManager.PERMISSION_GRANTED) { 5419 continue; 5420 } 5421 if (homeActivityName != null 5422 && pkg.packageName.equals(homeActivityName.getPackageName()) 5423 && pkg.applicationInfo.isSystemApp()) { 5424 continue; 5425 } 5426 try { 5427 final int uid = pkg.applicationInfo.uid; 5428 ActivityManagerNative.getDefault().killUid(UserHandle.getAppId(uid), 5429 UserHandle.getUserId(uid), 5430 "killBackgroundUserProcessesWithAudioRecordPermission"); 5431 } catch (RemoteException e) { 5432 Log.w(TAG, "Error calling killUid", e); 5433 } 5434 } 5435 } 5436 5437 5438 //========================================================================================== 5439 // Audio Focus 5440 //========================================================================================== requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, IAudioPolicyCallback pcb)5441 public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, 5442 IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, 5443 IAudioPolicyCallback pcb) { 5444 // permission checks 5445 if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) { 5446 if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) { 5447 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 5448 android.Manifest.permission.MODIFY_PHONE_STATE)) { 5449 Log.e(TAG, "Invalid permission to (un)lock audio focus", new Exception()); 5450 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 5451 } 5452 } else { 5453 // only a registered audio policy can be used to lock focus 5454 synchronized (mAudioPolicies) { 5455 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 5456 Log.e(TAG, "Invalid unregistered AudioPolicy to (un)lock audio focus"); 5457 return AudioManager.AUDIOFOCUS_REQUEST_FAILED; 5458 } 5459 } 5460 } 5461 } 5462 5463 return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd, 5464 clientId, callingPackageName, flags); 5465 } 5466 abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa)5467 public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa) { 5468 return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa); 5469 } 5470 unregisterAudioFocusClient(String clientId)5471 public void unregisterAudioFocusClient(String clientId) { 5472 mMediaFocusControl.unregisterAudioFocusClient(clientId); 5473 } 5474 getCurrentAudioFocus()5475 public int getCurrentAudioFocus() { 5476 return mMediaFocusControl.getCurrentAudioFocus(); 5477 } 5478 readCameraSoundForced()5479 private boolean readCameraSoundForced() { 5480 return SystemProperties.getBoolean("audio.camerasound.force", false) || 5481 mContext.getResources().getBoolean( 5482 com.android.internal.R.bool.config_camera_sound_forced); 5483 } 5484 5485 //========================================================================================== 5486 // Device orientation 5487 //========================================================================================== 5488 /** 5489 * Handles device configuration changes that may map to a change in the orientation 5490 * or orientation. 5491 * Monitoring orientation and rotation is optional, and is defined by the definition and value 5492 * of the "ro.audio.monitorOrientation" and "ro.audio.monitorRotation" system properties. 5493 */ handleConfigurationChanged(Context context)5494 private void handleConfigurationChanged(Context context) { 5495 try { 5496 // reading new orientation "safely" (i.e. under try catch) in case anything 5497 // goes wrong when obtaining resources and configuration 5498 Configuration config = context.getResources().getConfiguration(); 5499 // TODO merge rotation and orientation 5500 if (mMonitorOrientation) { 5501 int newOrientation = config.orientation; 5502 if (newOrientation != mDeviceOrientation) { 5503 mDeviceOrientation = newOrientation; 5504 setOrientationForAudioSystem(); 5505 } 5506 } 5507 sendMsg(mAudioHandler, 5508 MSG_CONFIGURE_SAFE_MEDIA_VOLUME, 5509 SENDMSG_REPLACE, 5510 0, 5511 0, 5512 TAG, 5513 0); 5514 5515 boolean cameraSoundForced = readCameraSoundForced(); 5516 synchronized (mSettingsLock) { 5517 boolean cameraSoundForcedChanged = false; 5518 synchronized (mCameraSoundForced) { 5519 if (cameraSoundForced != mCameraSoundForced) { 5520 mCameraSoundForced = cameraSoundForced; 5521 cameraSoundForcedChanged = true; 5522 } 5523 } 5524 if (cameraSoundForcedChanged) { 5525 if (!isPlatformTelevision()) { 5526 VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED]; 5527 if (cameraSoundForced) { 5528 s.setAllIndexesToMax(); 5529 mRingerModeAffectedStreams &= 5530 ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 5531 } else { 5532 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG); 5533 mRingerModeAffectedStreams |= 5534 (1 << AudioSystem.STREAM_SYSTEM_ENFORCED); 5535 } 5536 // take new state into account for streams muted by ringer mode 5537 setRingerModeInt(getRingerModeInternal(), false); 5538 } 5539 5540 sendMsg(mAudioHandler, 5541 MSG_SET_FORCE_USE, 5542 SENDMSG_QUEUE, 5543 AudioSystem.FOR_SYSTEM, 5544 cameraSoundForced ? 5545 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 5546 null, 5547 0); 5548 5549 sendMsg(mAudioHandler, 5550 MSG_SET_ALL_VOLUMES, 5551 SENDMSG_QUEUE, 5552 0, 5553 0, 5554 mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0); 5555 } 5556 } 5557 mVolumeController.setLayoutDirection(config.getLayoutDirection()); 5558 } catch (Exception e) { 5559 Log.e(TAG, "Error handling configuration change: ", e); 5560 } 5561 } 5562 5563 //TODO move to an external "orientation helper" class setOrientationForAudioSystem()5564 private void setOrientationForAudioSystem() { 5565 switch (mDeviceOrientation) { 5566 case Configuration.ORIENTATION_LANDSCAPE: 5567 //Log.i(TAG, "orientation is landscape"); 5568 AudioSystem.setParameters("orientation=landscape"); 5569 break; 5570 case Configuration.ORIENTATION_PORTRAIT: 5571 //Log.i(TAG, "orientation is portrait"); 5572 AudioSystem.setParameters("orientation=portrait"); 5573 break; 5574 case Configuration.ORIENTATION_SQUARE: 5575 //Log.i(TAG, "orientation is square"); 5576 AudioSystem.setParameters("orientation=square"); 5577 break; 5578 case Configuration.ORIENTATION_UNDEFINED: 5579 //Log.i(TAG, "orientation is undefined"); 5580 AudioSystem.setParameters("orientation=undefined"); 5581 break; 5582 default: 5583 Log.e(TAG, "Unknown orientation"); 5584 } 5585 } 5586 5587 // Handles request to override default use of A2DP for media. 5588 // Must be called synchronized on mConnectedDevices setBluetoothA2dpOnInt(boolean on)5589 public void setBluetoothA2dpOnInt(boolean on) { 5590 synchronized (mBluetoothA2dpEnabledLock) { 5591 mBluetoothA2dpEnabled = on; 5592 mAudioHandler.removeMessages(MSG_SET_FORCE_BT_A2DP_USE); 5593 setForceUseInt_SyncDevices(AudioSystem.FOR_MEDIA, 5594 mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP); 5595 } 5596 } 5597 5598 // Must be called synchronized on mConnectedDevices setForceUseInt_SyncDevices(int usage, int config)5599 private void setForceUseInt_SyncDevices(int usage, int config) { 5600 switch (usage) { 5601 case AudioSystem.FOR_MEDIA: 5602 if (config == AudioSystem.FORCE_NO_BT_A2DP) { 5603 mBecomingNoisyIntentDevices &= ~AudioSystem.DEVICE_OUT_ALL_A2DP; 5604 } else { // config == AudioSystem.FORCE_NONE 5605 mBecomingNoisyIntentDevices |= AudioSystem.DEVICE_OUT_ALL_A2DP; 5606 } 5607 break; 5608 case AudioSystem.FOR_DOCK: 5609 if (config == AudioSystem.FORCE_ANALOG_DOCK) { 5610 mBecomingNoisyIntentDevices |= AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET; 5611 } else { // config == AudioSystem.FORCE_NONE 5612 mBecomingNoisyIntentDevices &= ~AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET; 5613 } 5614 break; 5615 default: 5616 // usage doesn't affect the broadcast of ACTION_AUDIO_BECOMING_NOISY 5617 } 5618 AudioSystem.setForceUse(usage, config); 5619 } 5620 5621 @Override setRingtonePlayer(IRingtonePlayer player)5622 public void setRingtonePlayer(IRingtonePlayer player) { 5623 mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null); 5624 mRingtonePlayer = player; 5625 } 5626 5627 @Override getRingtonePlayer()5628 public IRingtonePlayer getRingtonePlayer() { 5629 return mRingtonePlayer; 5630 } 5631 5632 @Override startWatchingRoutes(IAudioRoutesObserver observer)5633 public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { 5634 synchronized (mCurAudioRoutes) { 5635 AudioRoutesInfo routes = new AudioRoutesInfo(mCurAudioRoutes); 5636 mRoutesObservers.register(observer); 5637 return routes; 5638 } 5639 } 5640 5641 5642 //========================================================================================== 5643 // Safe media volume management. 5644 // MUSIC stream volume level is limited when headphones are connected according to safety 5645 // regulation. When the user attempts to raise the volume above the limit, a warning is 5646 // displayed and the user has to acknowlegde before the volume is actually changed. 5647 // The volume index corresponding to the limit is stored in config_safe_media_volume_index 5648 // property. Platforms with a different limit must set this property accordingly in their 5649 // overlay. 5650 //========================================================================================== 5651 5652 // mSafeMediaVolumeState indicates whether the media volume is limited over headphones. 5653 // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected 5654 // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or 5655 // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it 5656 // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume() 5657 // (when user opts out). 5658 private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0; 5659 private static final int SAFE_MEDIA_VOLUME_DISABLED = 1; 5660 private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2; // confirmed 5661 private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3; // unconfirmed 5662 private Integer mSafeMediaVolumeState; 5663 5664 private int mMcc = 0; 5665 // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property 5666 private int mSafeMediaVolumeIndex; 5667 // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced, 5668 private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET | 5669 AudioSystem.DEVICE_OUT_WIRED_HEADPHONE; 5670 // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled. 5671 // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled 5672 // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS. 5673 private int mMusicActiveMs; 5674 private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours 5675 private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000; // 1 minute polling interval 5676 private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000; // 30s after boot completed 5677 setSafeMediaVolumeEnabled(boolean on, String caller)5678 private void setSafeMediaVolumeEnabled(boolean on, String caller) { 5679 synchronized (mSafeMediaVolumeState) { 5680 if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) && 5681 (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) { 5682 if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) { 5683 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; 5684 enforceSafeMediaVolume(caller); 5685 } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) { 5686 mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE; 5687 mMusicActiveMs = 1; // nonzero = confirmed 5688 saveMusicActiveMs(); 5689 sendMsg(mAudioHandler, 5690 MSG_CHECK_MUSIC_ACTIVE, 5691 SENDMSG_REPLACE, 5692 0, 5693 0, 5694 caller, 5695 MUSIC_ACTIVE_POLL_PERIOD_MS); 5696 } 5697 } 5698 } 5699 } 5700 enforceSafeMediaVolume(String caller)5701 private void enforceSafeMediaVolume(String caller) { 5702 VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC]; 5703 int devices = mSafeMediaVolumeDevices; 5704 int i = 0; 5705 5706 while (devices != 0) { 5707 int device = 1 << i++; 5708 if ((device & devices) == 0) { 5709 continue; 5710 } 5711 int index = streamState.getIndex(device); 5712 if (index > mSafeMediaVolumeIndex) { 5713 streamState.setIndex(mSafeMediaVolumeIndex, device, caller); 5714 sendMsg(mAudioHandler, 5715 MSG_SET_DEVICE_VOLUME, 5716 SENDMSG_QUEUE, 5717 device, 5718 0, 5719 streamState, 5720 0); 5721 } 5722 devices &= ~device; 5723 } 5724 } 5725 checkSafeMediaVolume(int streamType, int index, int device)5726 private boolean checkSafeMediaVolume(int streamType, int index, int device) { 5727 synchronized (mSafeMediaVolumeState) { 5728 if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) && 5729 (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && 5730 ((device & mSafeMediaVolumeDevices) != 0) && 5731 (index > mSafeMediaVolumeIndex)) { 5732 return false; 5733 } 5734 return true; 5735 } 5736 } 5737 5738 @Override disableSafeMediaVolume(String callingPackage)5739 public void disableSafeMediaVolume(String callingPackage) { 5740 enforceVolumeController("disable the safe media volume"); 5741 synchronized (mSafeMediaVolumeState) { 5742 setSafeMediaVolumeEnabled(false, callingPackage); 5743 if (mPendingVolumeCommand != null) { 5744 onSetStreamVolume(mPendingVolumeCommand.mStreamType, 5745 mPendingVolumeCommand.mIndex, 5746 mPendingVolumeCommand.mFlags, 5747 mPendingVolumeCommand.mDevice, 5748 callingPackage); 5749 mPendingVolumeCommand = null; 5750 } 5751 } 5752 } 5753 5754 //========================================================================================== 5755 // Hdmi Cec system audio mode. 5756 // If Hdmi Cec's system audio mode is on, audio service should send the volume change 5757 // to HdmiControlService so that the audio receiver can handle it. 5758 //========================================================================================== 5759 5760 private class MyDisplayStatusCallback implements HdmiPlaybackClient.DisplayStatusCallback { onComplete(int status)5761 public void onComplete(int status) { 5762 if (mHdmiManager != null) { 5763 synchronized (mHdmiManager) { 5764 mHdmiCecSink = (status != HdmiControlManager.POWER_STATUS_UNKNOWN); 5765 // Television devices without CEC service apply software volume on HDMI output 5766 if (isPlatformTelevision() && !mHdmiCecSink) { 5767 mFixedVolumeDevices &= ~AudioSystem.DEVICE_OUT_HDMI; 5768 } 5769 checkAllFixedVolumeDevices(); 5770 } 5771 } 5772 } 5773 }; 5774 5775 // If HDMI-CEC system audio is supported 5776 private boolean mHdmiSystemAudioSupported = false; 5777 // Set only when device is tv. 5778 private HdmiTvClient mHdmiTvClient; 5779 // true if the device has system feature PackageManager.FEATURE_LEANBACK. 5780 // cached HdmiControlManager interface 5781 private HdmiControlManager mHdmiManager; 5782 // Set only when device is a set-top box. 5783 private HdmiPlaybackClient mHdmiPlaybackClient; 5784 // true if we are a set-top box, an HDMI sink is connected and it supports CEC. 5785 private boolean mHdmiCecSink; 5786 5787 private MyDisplayStatusCallback mHdmiDisplayStatusCallback = new MyDisplayStatusCallback(); 5788 5789 @Override setHdmiSystemAudioSupported(boolean on)5790 public int setHdmiSystemAudioSupported(boolean on) { 5791 int device = AudioSystem.DEVICE_NONE; 5792 if (mHdmiManager != null) { 5793 synchronized (mHdmiManager) { 5794 if (mHdmiTvClient == null) { 5795 Log.w(TAG, "Only Hdmi-Cec enabled TV device supports system audio mode."); 5796 return device; 5797 } 5798 5799 synchronized (mHdmiTvClient) { 5800 if (mHdmiSystemAudioSupported != on) { 5801 mHdmiSystemAudioSupported = on; 5802 AudioSystem.setForceUse(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, 5803 on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : 5804 AudioSystem.FORCE_NONE); 5805 } 5806 device = getDevicesForStream(AudioSystem.STREAM_MUSIC); 5807 } 5808 } 5809 } 5810 return device; 5811 } 5812 5813 @Override isHdmiSystemAudioSupported()5814 public boolean isHdmiSystemAudioSupported() { 5815 return mHdmiSystemAudioSupported; 5816 } 5817 5818 //========================================================================================== 5819 // Accessibility: taking touch exploration into account for selecting the default 5820 // stream override timeout when adjusting volume 5821 //========================================================================================== 5822 private static class StreamOverride 5823 implements AccessibilityManager.TouchExplorationStateChangeListener { 5824 5825 // AudioService.getActiveStreamType() will return: 5826 // - STREAM_NOTIFICATION on tablets during this period after a notification stopped 5827 // - STREAM_MUSIC on phones during this period after music or talkback/voice search prompt 5828 // stopped 5829 private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0; 5830 private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000; 5831 5832 static int sDelayMs; 5833 init(Context ctxt)5834 static void init(Context ctxt) { 5835 AccessibilityManager accessibilityManager = 5836 (AccessibilityManager) ctxt.getSystemService(Context.ACCESSIBILITY_SERVICE); 5837 updateDefaultStreamOverrideDelay( 5838 accessibilityManager.isTouchExplorationEnabled()); 5839 accessibilityManager.addTouchExplorationStateChangeListener( 5840 new StreamOverride()); 5841 } 5842 5843 @Override onTouchExplorationStateChanged(boolean enabled)5844 public void onTouchExplorationStateChanged(boolean enabled) { 5845 updateDefaultStreamOverrideDelay(enabled); 5846 } 5847 updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)5848 private static void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) { 5849 if (touchExploreEnabled) { 5850 sDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS; 5851 } else { 5852 sDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS; 5853 } 5854 if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled 5855 + " stream override delay is now " + sDelayMs + " ms"); 5856 } 5857 } 5858 5859 //========================================================================================== 5860 // Camera shutter sound policy. 5861 // config_camera_sound_forced configuration option in config.xml defines if the camera shutter 5862 // sound is forced (sound even if the device is in silent mode) or not. This option is false by 5863 // default and can be overridden by country specific overlay in values-mccXXX/config.xml. 5864 //========================================================================================== 5865 5866 // cached value of com.android.internal.R.bool.config_camera_sound_forced 5867 private Boolean mCameraSoundForced; 5868 5869 // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound isCameraSoundForced()5870 public boolean isCameraSoundForced() { 5871 synchronized (mCameraSoundForced) { 5872 return mCameraSoundForced; 5873 } 5874 } 5875 5876 private static final String[] RINGER_MODE_NAMES = new String[] { 5877 "SILENT", 5878 "VIBRATE", 5879 "NORMAL" 5880 }; 5881 dumpRingerMode(PrintWriter pw)5882 private void dumpRingerMode(PrintWriter pw) { 5883 pw.println("\nRinger mode: "); 5884 pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]); 5885 pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]); 5886 dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams); 5887 dumpRingerModeStreams(pw, "muted", mRingerModeMutedStreams); 5888 pw.print("- delegate = "); pw.println(mRingerModeDelegate); 5889 } 5890 dumpRingerModeStreams(PrintWriter pw, String type, int streams)5891 private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) { 5892 pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x"); 5893 pw.print(Integer.toHexString(streams)); 5894 if (streams != 0) { 5895 pw.print(" ("); 5896 boolean first = true; 5897 for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) { 5898 final int stream = (1 << i); 5899 if ((streams & stream) != 0) { 5900 if (!first) pw.print(','); 5901 pw.print(AudioSystem.STREAM_NAMES[i]); 5902 streams &= ~stream; 5903 first = false; 5904 } 5905 } 5906 if (streams != 0) { 5907 if (!first) pw.print(','); 5908 pw.print(streams); 5909 } 5910 pw.print(')'); 5911 } 5912 pw.println(); 5913 } 5914 5915 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)5916 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 5917 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); 5918 5919 mMediaFocusControl.dump(pw); 5920 dumpStreamStates(pw); 5921 dumpRingerMode(pw); 5922 pw.println("\nAudio routes:"); 5923 pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mainType)); 5924 pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.bluetoothName); 5925 5926 pw.println("\nOther state:"); 5927 pw.print(" mVolumeController="); pw.println(mVolumeController); 5928 pw.print(" mSafeMediaVolumeState="); 5929 pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState)); 5930 pw.print(" mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex); 5931 pw.print(" mPendingVolumeCommand="); pw.println(mPendingVolumeCommand); 5932 pw.print(" mMusicActiveMs="); pw.println(mMusicActiveMs); 5933 pw.print(" mMcc="); pw.println(mMcc); 5934 pw.print(" mCameraSoundForced="); pw.println(mCameraSoundForced); 5935 pw.print(" mHasVibrator="); pw.println(mHasVibrator); 5936 pw.print(" mControllerService="); pw.println(mControllerService); 5937 pw.print(" mVolumePolicy="); pw.println(mVolumePolicy); 5938 5939 dumpAudioPolicies(pw); 5940 } 5941 safeMediaVolumeStateToString(Integer state)5942 private static String safeMediaVolumeStateToString(Integer state) { 5943 switch(state) { 5944 case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED"; 5945 case SAFE_MEDIA_VOLUME_DISABLED: return "SAFE_MEDIA_VOLUME_DISABLED"; 5946 case SAFE_MEDIA_VOLUME_INACTIVE: return "SAFE_MEDIA_VOLUME_INACTIVE"; 5947 case SAFE_MEDIA_VOLUME_ACTIVE: return "SAFE_MEDIA_VOLUME_ACTIVE"; 5948 } 5949 return null; 5950 } 5951 5952 // Inform AudioFlinger of our device's low RAM attribute readAndSetLowRamDevice()5953 private static void readAndSetLowRamDevice() 5954 { 5955 int status = AudioSystem.setLowRamDevice(ActivityManager.isLowRamDeviceStatic()); 5956 if (status != 0) { 5957 Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status); 5958 } 5959 } 5960 enforceVolumeController(String action)5961 private void enforceVolumeController(String action) { 5962 if (mControllerService.mUid != 0 && Binder.getCallingUid() == mControllerService.mUid) { 5963 return; 5964 } 5965 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE, 5966 "Only SystemUI can " + action); 5967 } 5968 5969 @Override setVolumeController(final IVolumeController controller)5970 public void setVolumeController(final IVolumeController controller) { 5971 enforceVolumeController("set the volume controller"); 5972 5973 // return early if things are not actually changing 5974 if (mVolumeController.isSameBinder(controller)) { 5975 return; 5976 } 5977 5978 // dismiss the old volume controller 5979 mVolumeController.postDismiss(); 5980 if (controller != null) { 5981 // we are about to register a new controller, listen for its death 5982 try { 5983 controller.asBinder().linkToDeath(new DeathRecipient() { 5984 @Override 5985 public void binderDied() { 5986 if (mVolumeController.isSameBinder(controller)) { 5987 Log.w(TAG, "Current remote volume controller died, unregistering"); 5988 setVolumeController(null); 5989 } 5990 } 5991 }, 0); 5992 } catch (RemoteException e) { 5993 // noop 5994 } 5995 } 5996 mVolumeController.setController(controller); 5997 if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController); 5998 } 5999 6000 @Override notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)6001 public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) { 6002 enforceVolumeController("notify about volume controller visibility"); 6003 6004 // return early if the controller is not current 6005 if (!mVolumeController.isSameBinder(controller)) { 6006 return; 6007 } 6008 6009 mVolumeController.setVisible(visible); 6010 if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible); 6011 } 6012 6013 @Override setVolumePolicy(VolumePolicy policy)6014 public void setVolumePolicy(VolumePolicy policy) { 6015 enforceVolumeController("set volume policy"); 6016 if (policy != null && !policy.equals(mVolumePolicy)) { 6017 mVolumePolicy = policy; 6018 if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy); 6019 } 6020 } 6021 6022 public static class VolumeController { 6023 private static final String TAG = "VolumeController"; 6024 6025 private IVolumeController mController; 6026 private boolean mVisible; 6027 private long mNextLongPress; 6028 private int mLongPressTimeout; 6029 setController(IVolumeController controller)6030 public void setController(IVolumeController controller) { 6031 mController = controller; 6032 mVisible = false; 6033 } 6034 loadSettings(ContentResolver cr)6035 public void loadSettings(ContentResolver cr) { 6036 mLongPressTimeout = Settings.Secure.getIntForUser(cr, 6037 Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT); 6038 } 6039 suppressAdjustment(int resolvedStream, int flags, boolean isMute)6040 public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) { 6041 if (isMute) { 6042 return false; 6043 } 6044 boolean suppress = false; 6045 if (resolvedStream == AudioSystem.STREAM_RING && mController != null) { 6046 final long now = SystemClock.uptimeMillis(); 6047 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) { 6048 // ui will become visible 6049 if (mNextLongPress < now) { 6050 mNextLongPress = now + mLongPressTimeout; 6051 } 6052 suppress = true; 6053 } else if (mNextLongPress > 0) { // in a long-press 6054 if (now > mNextLongPress) { 6055 // long press triggered, no more suppression 6056 mNextLongPress = 0; 6057 } else { 6058 // keep suppressing until the long press triggers 6059 suppress = true; 6060 } 6061 } 6062 } 6063 return suppress; 6064 } 6065 setVisible(boolean visible)6066 public void setVisible(boolean visible) { 6067 mVisible = visible; 6068 } 6069 isSameBinder(IVolumeController controller)6070 public boolean isSameBinder(IVolumeController controller) { 6071 return Objects.equals(asBinder(), binder(controller)); 6072 } 6073 asBinder()6074 public IBinder asBinder() { 6075 return binder(mController); 6076 } 6077 binder(IVolumeController controller)6078 private static IBinder binder(IVolumeController controller) { 6079 return controller == null ? null : controller.asBinder(); 6080 } 6081 6082 @Override toString()6083 public String toString() { 6084 return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")"; 6085 } 6086 postDisplaySafeVolumeWarning(int flags)6087 public void postDisplaySafeVolumeWarning(int flags) { 6088 if (mController == null) 6089 return; 6090 try { 6091 mController.displaySafeVolumeWarning(flags); 6092 } catch (RemoteException e) { 6093 Log.w(TAG, "Error calling displaySafeVolumeWarning", e); 6094 } 6095 } 6096 postVolumeChanged(int streamType, int flags)6097 public void postVolumeChanged(int streamType, int flags) { 6098 if (mController == null) 6099 return; 6100 try { 6101 mController.volumeChanged(streamType, flags); 6102 } catch (RemoteException e) { 6103 Log.w(TAG, "Error calling volumeChanged", e); 6104 } 6105 } 6106 postMasterMuteChanged(int flags)6107 public void postMasterMuteChanged(int flags) { 6108 if (mController == null) 6109 return; 6110 try { 6111 mController.masterMuteChanged(flags); 6112 } catch (RemoteException e) { 6113 Log.w(TAG, "Error calling masterMuteChanged", e); 6114 } 6115 } 6116 setLayoutDirection(int layoutDirection)6117 public void setLayoutDirection(int layoutDirection) { 6118 if (mController == null) 6119 return; 6120 try { 6121 mController.setLayoutDirection(layoutDirection); 6122 } catch (RemoteException e) { 6123 Log.w(TAG, "Error calling setLayoutDirection", e); 6124 } 6125 } 6126 postDismiss()6127 public void postDismiss() { 6128 if (mController == null) 6129 return; 6130 try { 6131 mController.dismiss(); 6132 } catch (RemoteException e) { 6133 Log.w(TAG, "Error calling dismiss", e); 6134 } 6135 } 6136 } 6137 6138 /** 6139 * Interface for system components to get some extra functionality through 6140 * LocalServices. 6141 */ 6142 final class AudioServiceInternal extends AudioManagerInternal { 6143 @Override setRingerModeDelegate(RingerModeDelegate delegate)6144 public void setRingerModeDelegate(RingerModeDelegate delegate) { 6145 mRingerModeDelegate = delegate; 6146 if (mRingerModeDelegate != null) { 6147 updateRingerModeAffectedStreams(); 6148 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate"); 6149 } 6150 } 6151 6152 @Override adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, String callingPackage, int uid)6153 public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, 6154 String callingPackage, int uid) { 6155 // direction and stream type swap here because the public 6156 // adjustSuggested has a different order than the other methods. 6157 adjustSuggestedStreamVolume(direction, streamType, flags, callingPackage, 6158 callingPackage, uid); 6159 } 6160 6161 @Override adjustStreamVolumeForUid(int streamType, int direction, int flags, String callingPackage, int uid)6162 public void adjustStreamVolumeForUid(int streamType, int direction, int flags, 6163 String callingPackage, int uid) { 6164 adjustStreamVolume(streamType, direction, flags, callingPackage, 6165 callingPackage, uid); 6166 } 6167 6168 @Override setStreamVolumeForUid(int streamType, int direction, int flags, String callingPackage, int uid)6169 public void setStreamVolumeForUid(int streamType, int direction, int flags, 6170 String callingPackage, int uid) { 6171 setStreamVolume(streamType, direction, flags, callingPackage, callingPackage, uid); 6172 } 6173 6174 @Override getRingerModeInternal()6175 public int getRingerModeInternal() { 6176 return AudioService.this.getRingerModeInternal(); 6177 } 6178 6179 @Override setRingerModeInternal(int ringerMode, String caller)6180 public void setRingerModeInternal(int ringerMode, String caller) { 6181 AudioService.this.setRingerModeInternal(ringerMode, caller); 6182 } 6183 6184 @Override getVolumeControllerUid()6185 public int getVolumeControllerUid() { 6186 return mControllerService.mUid; 6187 } 6188 6189 @Override updateRingerModeAffectedStreamsInternal()6190 public void updateRingerModeAffectedStreamsInternal() { 6191 synchronized (mSettingsLock) { 6192 if (updateRingerModeAffectedStreams()) { 6193 setRingerModeInt(getRingerModeInternal(), false); 6194 } 6195 } 6196 } 6197 } 6198 6199 //========================================================================================== 6200 // Audio policy management 6201 //========================================================================================== registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener)6202 public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, 6203 boolean hasFocusListener) { 6204 AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback); 6205 6206 if (DEBUG_AP) Log.d(TAG, "registerAudioPolicy for " + pcb.asBinder() 6207 + " with config:" + policyConfig); 6208 String regId = null; 6209 // error handling 6210 boolean hasPermissionForPolicy = 6211 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 6212 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 6213 if (!hasPermissionForPolicy) { 6214 Slog.w(TAG, "Can't register audio policy for pid " + Binder.getCallingPid() + " / uid " 6215 + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); 6216 return null; 6217 } 6218 6219 synchronized (mAudioPolicies) { 6220 try { 6221 if (mAudioPolicies.containsKey(pcb.asBinder())) { 6222 Slog.e(TAG, "Cannot re-register policy"); 6223 return null; 6224 } 6225 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener); 6226 pcb.asBinder().linkToDeath(app, 0/*flags*/); 6227 regId = app.getRegistrationId(); 6228 mAudioPolicies.put(pcb.asBinder(), app); 6229 } catch (RemoteException e) { 6230 // audio policy owner has already died! 6231 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb + 6232 " binder death", e); 6233 return null; 6234 } 6235 } 6236 return regId; 6237 } 6238 unregisterAudioPolicyAsync(IAudioPolicyCallback pcb)6239 public void unregisterAudioPolicyAsync(IAudioPolicyCallback pcb) { 6240 if (DEBUG_AP) Log.d(TAG, "unregisterAudioPolicyAsync for " + pcb.asBinder()); 6241 synchronized (mAudioPolicies) { 6242 AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder()); 6243 if (app == null) { 6244 Slog.w(TAG, "Trying to unregister unknown audio policy for pid " 6245 + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()); 6246 return; 6247 } else { 6248 pcb.asBinder().unlinkToDeath(app, 0/*flags*/); 6249 } 6250 app.release(); 6251 } 6252 // TODO implement clearing mix attribute matching info in native audio policy 6253 } 6254 setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)6255 public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { 6256 if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior 6257 + " policy " + pcb.asBinder()); 6258 // error handling 6259 boolean hasPermissionForPolicy = 6260 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission( 6261 android.Manifest.permission.MODIFY_AUDIO_ROUTING)); 6262 if (!hasPermissionForPolicy) { 6263 Slog.w(TAG, "Cannot change audio policy ducking handling for pid " + 6264 + Binder.getCallingPid() + " / uid " 6265 + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING"); 6266 return AudioManager.ERROR; 6267 } 6268 6269 synchronized (mAudioPolicies) { 6270 if (!mAudioPolicies.containsKey(pcb.asBinder())) { 6271 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy"); 6272 return AudioManager.ERROR; 6273 } 6274 final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder()); 6275 if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 6276 // is there already one policy managing ducking? 6277 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 6278 if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 6279 Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled"); 6280 return AudioManager.ERROR; 6281 } 6282 } 6283 } 6284 app.mFocusDuckBehavior = duckingBehavior; 6285 mMediaFocusControl.setDuckingInExtPolicyAvailable( 6286 duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY); 6287 } 6288 return AudioManager.SUCCESS; 6289 } 6290 dumpAudioPolicies(PrintWriter pw)6291 private void dumpAudioPolicies(PrintWriter pw) { 6292 pw.println("\nAudio policies:"); 6293 synchronized (mAudioPolicies) { 6294 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 6295 pw.println(policy.toLogFriendlyString()); 6296 } 6297 } 6298 } 6299 6300 //====================== 6301 // Audio policy callbacks from AudioSystem for dynamic policies 6302 //====================== 6303 private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback = 6304 new AudioSystem.DynamicPolicyCallback() { 6305 public void onDynamicPolicyMixStateUpdate(String regId, int state) { 6306 if (!TextUtils.isEmpty(regId)) { 6307 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE, 6308 state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/); 6309 } 6310 } 6311 }; 6312 onDynPolicyMixStateUpdate(String regId, int state)6313 private void onDynPolicyMixStateUpdate(String regId, int state) { 6314 if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")"); 6315 synchronized (mAudioPolicies) { 6316 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 6317 for (AudioMix mix : policy.getMixes()) { 6318 if (mix.getRegistration().equals(regId)) { 6319 try { 6320 policy.mPolicyCallback.notifyMixStateUpdate(regId, state); 6321 } catch (RemoteException e) { 6322 Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback " 6323 + policy.mPolicyCallback.asBinder(), e); 6324 } 6325 return; 6326 } 6327 } 6328 } 6329 } 6330 } 6331 6332 //====================== 6333 // Audio policy callbacks from AudioSystem for recording configuration updates 6334 //====================== 6335 private final RecordingActivityMonitor mRecordMonitor = new RecordingActivityMonitor(); 6336 registerRecordingCallback(IRecordingConfigDispatcher rcdb)6337 public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) { 6338 mRecordMonitor.registerRecordingCallback(rcdb); 6339 } 6340 unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)6341 public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) { 6342 mRecordMonitor.unregisterRecordingCallback(rcdb); 6343 } 6344 getActiveRecordingConfigurations()6345 public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() { 6346 return mRecordMonitor.getActiveRecordingConfigurations(); 6347 } 6348 6349 //====================== 6350 // Audio policy proxy 6351 //====================== 6352 /** 6353 * This internal class inherits from AudioPolicyConfig, each instance contains all the 6354 * mixes of an AudioPolicy and their configurations. 6355 */ 6356 public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient { 6357 private static final String TAG = "AudioPolicyProxy"; 6358 IAudioPolicyCallback mPolicyCallback; 6359 boolean mHasFocusListener; 6360 /** 6361 * Audio focus ducking behavior for an audio policy. 6362 * This variable reflects the value that was successfully set in 6363 * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This 6364 * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy 6365 * is handling ducking for audio focus. 6366 */ 6367 int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT; 6368 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener)6369 AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, 6370 boolean hasFocusListener) { 6371 super(config); 6372 setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++)); 6373 mPolicyCallback = token; 6374 mHasFocusListener = hasFocusListener; 6375 if (mHasFocusListener) { 6376 mMediaFocusControl.addFocusFollower(mPolicyCallback); 6377 } 6378 connectMixes(); 6379 } 6380 binderDied()6381 public void binderDied() { 6382 synchronized (mAudioPolicies) { 6383 Log.i(TAG, "audio policy " + mPolicyCallback + " died"); 6384 release(); 6385 mAudioPolicies.remove(mPolicyCallback.asBinder()); 6386 } 6387 } 6388 getRegistrationId()6389 String getRegistrationId() { 6390 return getRegistration(); 6391 } 6392 release()6393 void release() { 6394 if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { 6395 mMediaFocusControl.setDuckingInExtPolicyAvailable(false); 6396 } 6397 if (mHasFocusListener) { 6398 mMediaFocusControl.removeFocusFollower(mPolicyCallback); 6399 } 6400 AudioSystem.registerPolicyMixes(mMixes, false); 6401 } 6402 connectMixes()6403 void connectMixes() { 6404 AudioSystem.registerPolicyMixes(mMixes, true); 6405 } 6406 }; 6407 6408 private HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = 6409 new HashMap<IBinder, AudioPolicyProxy>(); 6410 private int mAudioPolicyCounter = 0; // always accessed synchronized on mAudioPolicies 6411 6412 private class ControllerService extends ContentObserver { 6413 private int mUid; 6414 private ComponentName mComponent; 6415 ControllerService()6416 public ControllerService() { 6417 super(null); 6418 } 6419 6420 @Override toString()6421 public String toString() { 6422 return String.format("{mUid=%d,mComponent=%s}", mUid, mComponent); 6423 } 6424 init()6425 public void init() { 6426 onChange(true); 6427 mContentResolver.registerContentObserver(Settings.Secure.getUriFor( 6428 Settings.Secure.VOLUME_CONTROLLER_SERVICE_COMPONENT), false, this); 6429 } 6430 6431 @Override onChange(boolean selfChange)6432 public void onChange(boolean selfChange) { 6433 mUid = 0; 6434 mComponent = null; 6435 final String setting = Settings.Secure.getString(mContentResolver, 6436 Settings.Secure.VOLUME_CONTROLLER_SERVICE_COMPONENT); 6437 if (setting == null) return; 6438 try { 6439 mComponent = ComponentName.unflattenFromString(setting); 6440 if (mComponent == null) return; 6441 mUid = mContext.getPackageManager() 6442 .getApplicationInfo(mComponent.getPackageName(), 0).uid; 6443 } catch (Exception e) { 6444 Log.w(TAG, "Error loading controller service", e); 6445 } 6446 if (DEBUG_VOL) Log.d(TAG, "Reloaded controller service: " + this); 6447 } 6448 } 6449 } 6450