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