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