1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.audio; 18 19 import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK; 20 import static android.media.AudioManager.RINGER_MODE_NORMAL; 21 import static android.media.AudioManager.RINGER_MODE_SILENT; 22 import static android.media.AudioManager.RINGER_MODE_VIBRATE; 23 import static android.os.Process.FIRST_APPLICATION_UID; 24 25 import android.Manifest; 26 import android.app.ActivityManager; 27 import android.app.ActivityManagerInternal; 28 import android.app.ActivityManagerNative; 29 import android.app.AppGlobals; 30 import android.app.AppOpsManager; 31 import android.app.NotificationManager; 32 import android.bluetooth.BluetoothA2dp; 33 import android.bluetooth.BluetoothAdapter; 34 import android.bluetooth.BluetoothClass; 35 import android.bluetooth.BluetoothDevice; 36 import android.bluetooth.BluetoothHeadset; 37 import android.bluetooth.BluetoothProfile; 38 import android.content.BroadcastReceiver; 39 import android.content.ComponentName; 40 import android.content.ContentResolver; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.IntentFilter; 44 import android.content.pm.ApplicationInfo; 45 import android.content.pm.PackageInfo; 46 import android.content.pm.PackageManager; 47 import android.content.pm.UserInfo; 48 import android.content.res.Configuration; 49 import android.content.res.Resources; 50 import android.content.res.XmlResourceParser; 51 import android.database.ContentObserver; 52 import android.hardware.hdmi.HdmiControlManager; 53 import android.hardware.hdmi.HdmiPlaybackClient; 54 import android.hardware.hdmi.HdmiTvClient; 55 import android.hardware.usb.UsbManager; 56 import android.media.AudioAttributes; 57 import android.media.AudioDevicePort; 58 import android.media.AudioSystem; 59 import android.media.AudioFormat; 60 import android.media.AudioManager; 61 import android.media.AudioManagerInternal; 62 import android.media.AudioPort; 63 import android.media.AudioRecordingConfiguration; 64 import android.media.AudioRoutesInfo; 65 import android.media.IAudioFocusDispatcher; 66 import android.media.IAudioRoutesObserver; 67 import android.media.IAudioService; 68 import android.media.IRecordingConfigDispatcher; 69 import android.media.IRingtonePlayer; 70 import android.media.IVolumeController; 71 import android.media.MediaPlayer; 72 import android.media.SoundPool; 73 import android.media.VolumePolicy; 74 import android.media.MediaPlayer.OnCompletionListener; 75 import android.media.MediaPlayer.OnErrorListener; 76 import android.media.audiopolicy.AudioMix; 77 import android.media.audiopolicy.AudioPolicy; 78 import android.media.audiopolicy.AudioPolicyConfig; 79 import android.media.audiopolicy.IAudioPolicyCallback; 80 import android.os.Binder; 81 import android.os.Build; 82 import android.os.Bundle; 83 import android.os.Environment; 84 import android.os.Handler; 85 import android.os.IBinder; 86 import android.os.Looper; 87 import android.os.Message; 88 import android.os.PowerManager; 89 import android.os.RemoteCallbackList; 90 import android.os.RemoteException; 91 import android.os.SystemClock; 92 import android.os.SystemProperties; 93 import android.os.UserHandle; 94 import android.os.UserManager; 95 import android.os.UserManagerInternal; 96 import android.os.UserManagerInternal.UserRestrictionsListener; 97 import android.os.Vibrator; 98 import android.provider.Settings; 99 import android.provider.Settings.System; 100 import android.telecom.TelecomManager; 101 import android.text.TextUtils; 102 import android.util.AndroidRuntimeException; 103 import android.util.ArrayMap; 104 import android.util.ArraySet; 105 import android.util.Log; 106 import android.util.MathUtils; 107 import android.util.Slog; 108 import android.util.SparseIntArray; 109 import android.view.KeyEvent; 110 import android.view.accessibility.AccessibilityManager; 111 112 import com.android.internal.util.XmlUtils; 113 import com.android.server.EventLogTags; 114 import com.android.server.LocalServices; 115 import com.android.server.SystemService; 116 import com.android.server.pm.UserManagerService; 117 118 import org.xmlpull.v1.XmlPullParserException; 119 120 import java.io.FileDescriptor; 121 import java.io.IOException; 122 import java.io.PrintWriter; 123 import java.lang.reflect.Field; 124 import java.util.ArrayList; 125 import java.util.HashMap; 126 import java.util.Iterator; 127 import java.util.List; 128 import java.util.NoSuchElementException; 129 import java.util.Objects; 130 131 /** 132 * The implementation of the volume manager service. 133 * <p> 134 * This implementation focuses on delivering a responsive UI. Most methods are 135 * asynchronous to external calls. For example, the task of setting a volume 136 * will update our internal state, but in a separate thread will set the system 137 * volume and later persist to the database. Similarly, setting the ringer mode 138 * will update the state and broadcast a change and in a separate thread later 139 * persist the ringer mode. 140 * 141 * @hide 142 */ 143 public class AudioService extends IAudioService.Stub { 144 145 private static final String TAG = "AudioService"; 146 147 /** Debug audio mode */ 148 protected static final boolean DEBUG_MODE = Log.isLoggable(TAG + ".MOD", Log.DEBUG); 149 150 /** Debug audio policy feature */ 151 protected static final boolean DEBUG_AP = Log.isLoggable(TAG + ".AP", Log.DEBUG); 152 153 /** Debug volumes */ 154 protected static final boolean DEBUG_VOL = Log.isLoggable(TAG + ".VOL", Log.DEBUG); 155 156 /** debug calls to devices APIs */ 157 protected static final boolean DEBUG_DEVICES = Log.isLoggable(TAG + ".DEVICES", Log.DEBUG); 158 159 /** How long to delay before persisting a change in volume/ringer mode. */ 160 private static final int PERSIST_DELAY = 500; 161 162 /** How long to delay after a volume down event before unmuting a stream */ 163 private static final int UNMUTE_STREAM_DELAY = 350; 164 165 /** 166 * Only used in the result from {@link #checkForRingerModeChange(int, int, int)} 167 */ 168 private static final int FLAG_ADJUST_VOLUME = 1; 169 170 private final Context mContext; 171 private final ContentResolver mContentResolver; 172 private final AppOpsManager mAppOps; 173 174 // the platform type affects volume and silent mode behavior 175 private final int mPlatformType; 176 177 private boolean isPlatformVoice() { 178 return mPlatformType == AudioSystem.PLATFORM_VOICE; 179 } 180 181 private boolean isPlatformTelevision() { 182 return mPlatformType == AudioSystem.PLATFORM_TELEVISION; 183 } 184 185 /** The controller for the volume UI. */ 186 private final VolumeController mVolumeController = new VolumeController(); 187 private final ControllerService mControllerService = new ControllerService(); 188 189 // sendMsg() flags 190 /** If the msg is already queued, replace it with this one. */ 191 private static final int SENDMSG_REPLACE = 0; 192 /** If the msg is already queued, ignore this one and leave the old. */ 193 private static final int SENDMSG_NOOP = 1; 194 /** If the msg is already queued, queue this one and leave the old. */ 195 private static final int SENDMSG_QUEUE = 2; 196 197 // AudioHandler messages 198 private static final int MSG_SET_DEVICE_VOLUME = 0; 199 private static final int MSG_PERSIST_VOLUME = 1; 200 private static final int MSG_PERSIST_RINGER_MODE = 3; 201 private static final int MSG_AUDIO_SERVER_DIED = 4; 202 private static final int MSG_PLAY_SOUND_EFFECT = 5; 203 private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6; 204 private static final int MSG_LOAD_SOUND_EFFECTS = 7; 205 private static final int MSG_SET_FORCE_USE = 8; 206 private static final int MSG_BT_HEADSET_CNCT_FAILED = 9; 207 private static final int MSG_SET_ALL_VOLUMES = 10; 208 private static final int MSG_REPORT_NEW_ROUTES = 12; 209 private static final int MSG_SET_FORCE_BT_A2DP_USE = 13; 210 private static final int MSG_CHECK_MUSIC_ACTIVE = 14; 211 private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 15; 212 private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 16; 213 private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 17; 214 private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 18; 215 private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 19; 216 private static final int MSG_UNLOAD_SOUND_EFFECTS = 20; 217 private static final int MSG_SYSTEM_READY = 21; 218 private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 22; 219 private static final int MSG_UNMUTE_STREAM = 24; 220 private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 25; 221 private static final int MSG_INDICATE_SYSTEM_READY = 26; 222 // start of messages handled under wakelock 223 // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), 224 // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) 225 private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 100; 226 private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101; 227 private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102; 228 // end of messages handled under wakelock 229 230 private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000; 231 // Timeout for connection to bluetooth headset service 232 private static final int BT_HEADSET_CNCT_TIMEOUT_MS = 3000; 233 234 // retry delay in case of failure to indicate system ready to AudioFlinger 235 private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; 236 237 /** @see AudioSystemThread */ 238 private AudioSystemThread mAudioSystemThread; 239 /** @see AudioHandler */ 240 private AudioHandler mAudioHandler; 241 /** @see VolumeStreamState */ 242 private VolumeStreamState[] mStreamStates; 243 private SettingsObserver mSettingsObserver; 244 245 private int mMode = AudioSystem.MODE_NORMAL; 246 // protects mRingerMode 247 private final Object mSettingsLock = new Object(); 248 249 private SoundPool mSoundPool; 250 private final Object mSoundEffectsLock = new Object(); 251 private static final int NUM_SOUNDPOOL_CHANNELS = 4; 252 253 /* Sound effect file names */ 254 private static final String SOUND_EFFECTS_PATH = "/media/audio/ui/"; 255 private static final List<String> SOUND_EFFECT_FILES = new ArrayList<String>(); 256 257 /* Sound effect file name mapping sound effect id (AudioManager.FX_xxx) to 258 * file index in SOUND_EFFECT_FILES[] (first column) and indicating if effect 259 * uses soundpool (second column) */ 260 private final int[][] SOUND_EFFECT_FILES_MAP = new int[AudioManager.NUM_SOUND_EFFECTS][2]; 261 262 /** Maximum volume index values for audio streams */ 263 private static int[] MAX_STREAM_VOLUME = new int[] { 264 5, // STREAM_VOICE_CALL 265 7, // STREAM_SYSTEM 266 7, // STREAM_RING 267 15, // STREAM_MUSIC 268 7, // STREAM_ALARM 269 7, // STREAM_NOTIFICATION 270 15, // STREAM_BLUETOOTH_SCO 271 7, // STREAM_SYSTEM_ENFORCED 272 15, // STREAM_DTMF 273 15 // STREAM_TTS 274 }; 275 276 /** Minimum volume index values for audio streams */ 277 private static int[] MIN_STREAM_VOLUME = new int[] { 278 1, // STREAM_VOICE_CALL 279 0, // STREAM_SYSTEM 280 0, // STREAM_RING 281 0, // STREAM_MUSIC 282 0, // STREAM_ALARM 283 0, // STREAM_NOTIFICATION 284 0, // STREAM_BLUETOOTH_SCO 285 0, // STREAM_SYSTEM_ENFORCED 286 0, // STREAM_DTMF 287 0 // STREAM_TTS 288 }; 289 290 /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings 291 * of another stream: This avoids multiplying the volume settings for hidden 292 * stream types that follow other stream behavior for volume settings 293 * NOTE: do not create loops in aliases! 294 * Some streams alias to different streams according to device category (phone or tablet) or 295 * use case (in call vs off call...). See updateStreamVolumeAlias() for more details. 296 * mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device 297 * (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and 298 * STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/ 299 private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] { 300 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 301 AudioSystem.STREAM_RING, // STREAM_SYSTEM 302 AudioSystem.STREAM_RING, // STREAM_RING 303 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 304 AudioSystem.STREAM_ALARM, // STREAM_ALARM 305 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 306 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 307 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 308 AudioSystem.STREAM_RING, // STREAM_DTMF 309 AudioSystem.STREAM_MUSIC // STREAM_TTS 310 }; 311 private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { 312 AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL 313 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM 314 AudioSystem.STREAM_MUSIC, // STREAM_RING 315 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 316 AudioSystem.STREAM_MUSIC, // STREAM_ALARM 317 AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION 318 AudioSystem.STREAM_MUSIC, // STREAM_BLUETOOTH_SCO 319 AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED 320 AudioSystem.STREAM_MUSIC, // STREAM_DTMF 321 AudioSystem.STREAM_MUSIC // STREAM_TTS 322 }; 323 private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { 324 AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL 325 AudioSystem.STREAM_RING, // STREAM_SYSTEM 326 AudioSystem.STREAM_RING, // STREAM_RING 327 AudioSystem.STREAM_MUSIC, // STREAM_MUSIC 328 AudioSystem.STREAM_ALARM, // STREAM_ALARM 329 AudioSystem.STREAM_RING, // STREAM_NOTIFICATION 330 AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO 331 AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED 332 AudioSystem.STREAM_RING, // STREAM_DTMF 333 AudioSystem.STREAM_MUSIC // STREAM_TTS 334 }; 335 private int[] mStreamVolumeAlias; 336 337 /** 338 * Map AudioSystem.STREAM_* constants to app ops. This should be used 339 * after mapping through mStreamVolumeAlias. 340 */ 341 private static final int[] STREAM_VOLUME_OPS = new int[] { 342 AppOpsManager.OP_AUDIO_VOICE_VOLUME, // STREAM_VOICE_CALL 343 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM 344 AppOpsManager.OP_AUDIO_RING_VOLUME, // STREAM_RING 345 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_MUSIC 346 AppOpsManager.OP_AUDIO_ALARM_VOLUME, // STREAM_ALARM 347 AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME, // STREAM_NOTIFICATION 348 AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME, // STREAM_BLUETOOTH_SCO 349 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED 350 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF 351 AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS 352 }; 353 354 private final boolean mUseFixedVolume; 355 356 private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() { 357 public void onError(int error) { 358 switch (error) { 359 case AudioSystem.AUDIO_STATUS_SERVER_DIED: 360 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, 361 SENDMSG_NOOP, 0, 0, null, 0); 362 break; 363 default: 364 break; 365 } 366 } 367 }; 368 369 /** 370 * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL}, 371 * {@link AudioManager#RINGER_MODE_SILENT}, or 372 * {@link AudioManager#RINGER_MODE_VIBRATE}. 373 */ 374 // protected by mSettingsLock 375 private int mRingerMode; // internal ringer mode, affects muting of underlying streams 376 private int mRingerModeExternal = -1; // reported ringer mode to outside clients (AudioManager) 377 378 /** @see System#MODE_RINGER_STREAMS_AFFECTED */ 379 private int mRingerModeAffectedStreams = 0; 380 381 // Streams currently muted by ringer mode 382 private int mRingerModeMutedStreams; 383 384 /** Streams that can be muted. Do not resolve to aliases when checking. 385 * @see System#MUTE_STREAMS_AFFECTED */ 386 private int mMuteAffectedStreams; 387 388 /** 389 * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated. 390 * mVibrateSetting is just maintained during deprecation period but vibration policy is 391 * now only controlled by mHasVibrator and mRingerMode 392 */ 393 private int mVibrateSetting; 394 395 // Is there a vibrator 396 private final boolean mHasVibrator; 397 398 // Broadcast receiver for device connections intent broadcasts 399 private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver(); 400 401 /** Interface for UserManagerService. */ 402 private final UserManagerInternal mUserManagerInternal; 403 404 private final UserRestrictionsListener mUserRestrictionsListener = 405 new AudioServiceUserRestrictionsListener(); 406 407 // Devices currently connected 408 // Use makeDeviceListKey() to make a unique key for this list. 409 private class DeviceListSpec { 410 int mDeviceType; 411 String mDeviceName; 412 String mDeviceAddress; 413 414 public DeviceListSpec(int deviceType, String deviceName, String deviceAddress) { 415 mDeviceType = deviceType; 416 mDeviceName = deviceName; 417 mDeviceAddress = deviceAddress; 418 } 419 420 public String toString() { 421 return "[type:0x" + Integer.toHexString(mDeviceType) + " name:" + mDeviceName 422 + " address:" + mDeviceAddress + "]"; 423 } 424 } 425 426 // Generate a unique key for the mConnectedDevices List by composing the device "type" 427 // and the "address" associated with a specific instance of that device type 428 private String makeDeviceListKey(int device, String deviceAddress) { 429 return "0x" + Integer.toHexString(device) + ":" + deviceAddress; 430 } 431 432 private final ArrayMap<String, DeviceListSpec> mConnectedDevices = new ArrayMap<>(); 433 434 // Forced device usage for communications 435 private int mForcedUseForComm; 436 437 // List of binder death handlers for setMode() client processes. 438 // The last process to have called setMode() is at the top of the list. 439 private final ArrayList <SetModeDeathHandler> mSetModeDeathHandlers = new ArrayList <SetModeDeathHandler>(); 440 441 // List of clients having issued a SCO start request 442 private final ArrayList <ScoClient> mScoClients = new ArrayList <ScoClient>(); 443 444 // BluetoothHeadset API to control SCO connection 445 private BluetoothHeadset mBluetoothHeadset; 446 447 // Bluetooth headset device 448 private BluetoothDevice mBluetoothHeadsetDevice; 449 450 // Indicate if SCO audio connection is currently active and if the initiator is 451 // audio service (internal) or bluetooth headset (external) 452 private int mScoAudioState; 453 // SCO audio state is not active 454 private static final int SCO_STATE_INACTIVE = 0; 455 // SCO audio activation request waiting for headset service to connect 456 private static final int SCO_STATE_ACTIVATE_REQ = 1; 457 // SCO audio state is active or starting due to a request from AudioManager API 458 private static final int SCO_STATE_ACTIVE_INTERNAL = 3; 459 // SCO audio deactivation request waiting for headset service to connect 460 private static final int SCO_STATE_DEACTIVATE_REQ = 5; 461 462 // SCO audio state is active due to an action in BT handsfree (either voice recognition or 463 // in call audio) 464 private static final int SCO_STATE_ACTIVE_EXTERNAL = 2; 465 // Deactivation request for all SCO connections (initiated by audio mode change) 466 // waiting for headset service to connect 467 private static final int SCO_STATE_DEACTIVATE_EXT_REQ = 4; 468 469 // Indicates the mode used for SCO audio connection. The mode is virtual call if the request 470 // originated from an app targeting an API version before JB MR2 and raw audio after that. 471 private int mScoAudioMode; 472 // SCO audio mode is undefined 473 private static final int SCO_MODE_UNDEFINED = -1; 474 // SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall()) 475 private static final int SCO_MODE_VIRTUAL_CALL = 0; 476 // SCO audio mode is raw audio (BluetoothHeadset.connectAudio()) 477 private static final int SCO_MODE_RAW = 1; 478 // SCO audio mode is Voice Recognition (BluetoothHeadset.startVoiceRecognition()) 479 private static final int SCO_MODE_VR = 2; 480 481 private static final int SCO_MODE_MAX = 2; 482 483 // Current connection state indicated by bluetooth headset 484 private int mScoConnectionState; 485 486 // true if boot sequence has been completed 487 private boolean mSystemReady; 488 // true if Intent.ACTION_USER_SWITCHED has ever been received 489 private boolean mUserSwitchedReceived; 490 // listener for SoundPool sample load completion indication 491 private SoundPoolCallback mSoundPoolCallBack; 492 // thread for SoundPool listener 493 private SoundPoolListenerThread mSoundPoolListenerThread; 494 // message looper for SoundPool listener 495 private Looper mSoundPoolLooper = null; 496 // volume applied to sound played with playSoundEffect() 497 private static int sSoundEffectVolumeDb; 498 // previous volume adjustment direction received by checkForRingerModeChange() 499 private int mPrevVolDirection = AudioManager.ADJUST_SAME; 500 // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume 501 // is controlled by Vol keys. 502 private int mVolumeControlStream = -1; 503 private final Object mForceControlStreamLock = new Object(); 504 // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system 505 // server process so in theory it is not necessary to monitor the client death. 506 // However it is good to be ready for future evolutions. 507 private ForceControlStreamClient mForceControlStreamClient = null; 508 // Used to play ringtones outside system_server 509 private volatile IRingtonePlayer mRingtonePlayer; 510 511 private int mDeviceOrientation = Configuration.ORIENTATION_UNDEFINED; 512 513 // Request to override default use of A2DP for media. 514 private boolean mBluetoothA2dpEnabled; 515 private final Object mBluetoothA2dpEnabledLock = new Object(); 516 517 // Monitoring of audio routes. Protected by mCurAudioRoutes. 518 final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo(); 519 final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers 520 = new RemoteCallbackList<IAudioRoutesObserver>(); 521 522 // Devices for which the volume is fixed and VolumePanel slider should be disabled 523 int mFixedVolumeDevices = AudioSystem.DEVICE_OUT_HDMI | 524 AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET | 525 AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET | 526 AudioSystem.DEVICE_OUT_HDMI_ARC | 527 AudioSystem.DEVICE_OUT_SPDIF | 528 AudioSystem.DEVICE_OUT_AUX_LINE; 529 int mFullVolumeDevices = 0; 530 531 // TODO merge orientation and rotation 532 private final boolean mMonitorOrientation; 533 private final boolean mMonitorRotation; 534 535 private boolean mDockAudioMediaEnabled = true; 536 537 private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; 538 539 // Used when safe volume warning message display is requested by setStreamVolume(). In this 540 // case, the new requested volume, stream type and device are stored in mPendingVolumeCommand 541 // and used later when/if disableSafeMediaVolume() is called. 542 private StreamVolumeCommand mPendingVolumeCommand; 543 544 private PowerManager.WakeLock mAudioEventWakeLock; 545 546 private final MediaFocusControl mMediaFocusControl; 547 548 // Reference to BluetoothA2dp to query for AbsoluteVolume. 549 private BluetoothA2dp mA2dp; 550 // lock always taken synchronized on mConnectedDevices 551 private final Object mA2dpAvrcpLock = new Object(); 552 // If absolute volume is supported in AVRCP device 553 private boolean mAvrcpAbsVolSupported = false; 554 555 private static Long mLastDeviceConnectMsgTime = new Long(0); 556 557 private NotificationManager mNm; 558 private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; 559 private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT; 560 private long mLoweredFromNormalToVibrateTime; 561 562 // Intent "extra" data keys. 563 public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName"; 564 public static final String CONNECT_INTENT_KEY_STATE = "state"; 565 public static final String CONNECT_INTENT_KEY_ADDRESS = "address"; 566 public static final String CONNECT_INTENT_KEY_HAS_PLAYBACK = "hasPlayback"; 567 public static final String CONNECT_INTENT_KEY_HAS_CAPTURE = "hasCapture"; 568 public static final String CONNECT_INTENT_KEY_HAS_MIDI = "hasMIDI"; 569 public static final String CONNECT_INTENT_KEY_DEVICE_CLASS = "class"; 570 571 // Defines the format for the connection "address" for ALSA devices 572 public static String makeAlsaAddressString(int card, int device) { 573 return "card=" + card + ";device=" + device + ";"; 574 } 575 576 public static final class Lifecycle extends SystemService { 577 private AudioService mService; 578 579 public Lifecycle(Context context) { 580 super(context); 581 mService = new AudioService(context); 582 } 583 584 @Override 585 public void onStart() { 586 publishBinderService(Context.AUDIO_SERVICE, mService); 587 } 588 589 @Override 590 public void onBootPhase(int phase) { 591 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 592 mService.systemReady(); 593 } 594 } 595 } 596 597 /////////////////////////////////////////////////////////////////////////// 598 // Construction 599 /////////////////////////////////////////////////////////////////////////// 600 601 /** @hide */ 602 public AudioService(Context context) { 603 mContext = context; 604 mContentResolver = context.getContentResolver(); 605 mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 606 607 mPlatformType = AudioSystem.getPlatformType(context); 608 609 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 610 611 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 612 mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); 613 614 Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 615 mHasVibrator = vibrator == null ? false : vibrator.hasVibrator(); 616 617 // Initialize volume 618 int maxVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", 619 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]); 620 if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { 621 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxVolume; 622 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = (maxVolume * 3) / 4; 623 } 624 maxVolume = SystemProperties.getInt("ro.config.media_vol_steps", 625 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]); 626 if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { 627 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume; 628 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = (maxVolume * 3) / 4; 629 } 630 631 sSoundEffectVolumeDb = context.getResources().getInteger( 632 com.android.internal.R.integer.config_soundEffectVolumeDb); 633 634 mForcedUseForComm = AudioSystem.FORCE_NONE; 635 636 createAudioSystemThread(); 637 638 AudioSystem.setErrorCallback(mAudioSystemCallback); 639 640 boolean cameraSoundForced = readCameraSoundForced(); 641 mCameraSoundForced = new Boolean(cameraSoundForced); 642 sendMsg(mAudioHandler, 643 MSG_SET_FORCE_USE, 644 SENDMSG_QUEUE, 645 AudioSystem.FOR_SYSTEM, 646 cameraSoundForced ? 647 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE, 648 null, 649 0); 650 651 mSafeMediaVolumeState = new Integer(Settings.Global.getInt(mContentResolver, 652 Settings.Global.AUDIO_SAFE_VOLUME_STATE, 653 SAFE_MEDIA_VOLUME_NOT_CONFIGURED)); 654 // The default safe volume index read here will be replaced by the actual value when 655 // the mcc is read by onConfigureSafeVolume() 656 mSafeMediaVolumeIndex = mContext.getResources().getInteger( 657 com.android.internal.R.integer.config_safe_media_volume_index) * 10; 658 659 mUseFixedVolume = mContext.getResources().getBoolean( 660 com.android.internal.R.bool.config_useFixedVolume); 661 662 // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[] 663 // array initialized by updateStreamVolumeAlias() 664 updateStreamVolumeAlias(false /*updateVolumes*/, TAG); 665 readPersistedSettings(); 666 readUserRestrictions(); 667 mSettingsObserver = new SettingsObserver(); 668 createStreamStates(); 669 670 mMediaFocusControl = new MediaFocusControl(mContext); 671 672 readAndSetLowRamDevice(); 673 674 // Call setRingerModeInt() to apply correct mute 675 // state on streams affected by ringer mode. 676 mRingerModeMutedStreams = 0; 677 setRingerModeInt(getRingerModeInternal(), false); 678 679 // Register for device connection intent broadcasts. 680 IntentFilter intentFilter = 681 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 682 intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); 683 intentFilter.addAction(Intent.ACTION_DOCK_EVENT); 684 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 685 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 686 intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 687 intentFilter.addAction(Intent.ACTION_USER_BACKGROUND); 688 intentFilter.addAction(Intent.ACTION_USER_FOREGROUND); 689 intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 690 intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 691 692 intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 693 // TODO merge orientation and rotation 694 mMonitorOrientation = SystemProperties.getBoolean("ro.audio.monitorOrientation", false); 695 if (mMonitorOrientation) { 696 Log.v(TAG, "monitoring device orientation"); 697 // initialize orientation in AudioSystem 698 setOrientationForAudioSystem(); 699 } 700 mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); 701 if (mMonitorRotation) { 702 RotationHelper.init(mContext, mAudioHandler); 703 } 704 705 context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null); 706 707 LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); 708 709 mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); 710 711 mRecordMonitor.initMonitor(); 712 } 713 714 public void systemReady() { 715 sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 716 0, 0, null, 0); 717 } 718 719 public void onSystemReady() { 720 mSystemReady = true; 721 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 722 0, 0, null, 0); 723 724 mScoConnectionState = AudioManager.SCO_AUDIO_STATE_ERROR; 725 resetBluetoothSco(); 726 getBluetoothHeadset(); 727 //FIXME: this is to maintain compatibility with deprecated intent 728 // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate. 729 Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED); 730 newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 731 AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 732 sendStickyBroadcastToAll(newIntent); 733 734 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 735 if (adapter != null) { 736 adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, 737 BluetoothProfile.A2DP); 738 } 739 740 mHdmiManager = 741 (HdmiControlManager) mContext.getSystemService(Context.HDMI_CONTROL_SERVICE); 742 if (mHdmiManager != null) { 743 synchronized (mHdmiManager) { 744 mHdmiTvClient = mHdmiManager.getTvClient(); 745 if (mHdmiTvClient != null) { 746 mFixedVolumeDevices &= ~AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER; 747 } 748 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient(); 749 mHdmiCecSink = false; 750 } 751 } 752 753 mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 754 755 sendMsg(mAudioHandler, 756 MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED, 757 SENDMSG_REPLACE, 758 0, 759 0, 760 TAG, 761 SAFE_VOLUME_CONFIGURE_TIMEOUT_MS); 762 763 StreamOverride.init(mContext); 764 mControllerService.init(); 765 onIndicateSystemReady(); 766 } 767 768 void onIndicateSystemReady() { 769 if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { 770 return; 771 } 772 sendMsg(mAudioHandler, 773 MSG_INDICATE_SYSTEM_READY, 774 SENDMSG_REPLACE, 775 0, 776 0, 777 null, 778 INDICATE_SYSTEM_READY_RETRY_DELAY_MS); 779 } 780 781 public void onAudioServerDied() { 782 if (!mSystemReady || 783 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { 784 Log.e(TAG, "Audioserver died."); 785 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0, 786 null, 500); 787 return; 788 } 789 Log.e(TAG, "Audioserver started."); 790 791 // indicate to audio HAL that we start the reconfiguration phase after a media 792 // server crash 793 // Note that we only execute this when the media server 794 // process restarts after a crash, not the first time it is started. 795 AudioSystem.setParameters("restarting=true"); 796 797 readAndSetLowRamDevice(); 798 799 // Restore device connection states 800 synchronized (mConnectedDevices) { 801 for (int i = 0; i < mConnectedDevices.size(); i++) { 802 DeviceListSpec spec = mConnectedDevices.valueAt(i); 803 AudioSystem.setDeviceConnectionState( 804 spec.mDeviceType, 805 AudioSystem.DEVICE_STATE_AVAILABLE, 806 spec.mDeviceAddress, 807 spec.mDeviceName); 808 } 809 } 810 // Restore call state 811 AudioSystem.setPhoneState(mMode); 812 813 // Restore forced usage for communcations and record 814 AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm); 815 AudioSystem.setForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm); 816 AudioSystem.setForceUse(AudioSystem.FOR_SYSTEM, mCameraSoundForced ? 817 AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE); 818 819 // Restore stream volumes 820 int numStreamTypes = AudioSystem.getNumStreamTypes(); 821 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 822 VolumeStreamState streamState = mStreamStates[streamType]; 823 AudioSystem.initStreamVolume( 824 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10); 825 826 streamState.applyAllVolumes(); 827 } 828 829 // Restore mono mode 830 updateMasterMono(mContentResolver); 831 832 // Restore ringer mode 833 setRingerModeInt(getRingerModeInternal(), false); 834 835 // Reset device orientation (if monitored for this device) 836 if (mMonitorOrientation) { 837 setOrientationForAudioSystem(); 838 } 839 if (mMonitorRotation) { 840 RotationHelper.updateOrientation(); 841 } 842 843 synchronized (mBluetoothA2dpEnabledLock) { 844 AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, 845 mBluetoothA2dpEnabled ? 846 AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP); 847 } 848 849 synchronized (mSettingsLock) { 850 AudioSystem.setForceUse(AudioSystem.FOR_DOCK, 851 mDockAudioMediaEnabled ? 852 AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE); 853 sendEncodedSurroundMode(mContentResolver); 854 } 855 if (mHdmiManager != null) { 856 synchronized (mHdmiManager) { 857 if (mHdmiTvClient != null) { 858 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); 859 } 860 } 861 } 862 863 synchronized (mAudioPolicies) { 864 for (AudioPolicyProxy policy : mAudioPolicies.values()) { 865 policy.connectMixes(); 866 } 867 } 868 869 onIndicateSystemReady(); 870 // indicate the end of reconfiguration phase to audio HAL 871 AudioSystem.setParameters("restarting=false"); 872 } 873 874 private void createAudioSystemThread() { 875 mAudioSystemThread = new AudioSystemThread(); 876 mAudioSystemThread.start(); 877 waitForAudioHandlerCreation(); 878 } 879 880 /** Waits for the volume handler to be created by the other thread. */ 881 private void waitForAudioHandlerCreation() { 882 synchronized(this) { 883 while (mAudioHandler == null) { 884 try { 885 // Wait for mAudioHandler to be set by the other thread 886 wait(); 887 } catch (InterruptedException e) { 888 Log.e(TAG, "Interrupted while waiting on volume handler."); 889 } 890 } 891 } 892 } 893 894 private void checkAllAliasStreamVolumes() { 895 synchronized (VolumeStreamState.class) { 896 int numStreamTypes = AudioSystem.getNumStreamTypes(); 897 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 898 if (streamType != mStreamVolumeAlias[streamType]) { 899 mStreamStates[streamType]. 900 setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], 901 TAG); 902 } 903 // apply stream volume 904 if (!mStreamStates[streamType].mIsMuted) { 905 mStreamStates[streamType].applyAllVolumes(); 906 } 907 } 908 } 909 } 910 911 private void checkAllFixedVolumeDevices() 912 { 913 int numStreamTypes = AudioSystem.getNumStreamTypes(); 914 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 915 mStreamStates[streamType].checkFixedVolumeDevices(); 916 } 917 } 918 919 private void checkAllFixedVolumeDevices(int streamType) { 920 mStreamStates[streamType].checkFixedVolumeDevices(); 921 } 922 923 private void checkMuteAffectedStreams() { 924 // any stream with a min level > 0 is not muteable by definition 925 for (int i = 0; i < mStreamStates.length; i++) { 926 final VolumeStreamState vss = mStreamStates[i]; 927 if (vss.mIndexMin > 0) { 928 mMuteAffectedStreams &= ~(1 << vss.mStreamType); 929 } 930 } 931 } 932 933 private void createStreamStates() { 934 int numStreamTypes = AudioSystem.getNumStreamTypes(); 935 VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes]; 936 937 for (int i = 0; i < numStreamTypes; i++) { 938 streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[mStreamVolumeAlias[i]], i); 939 } 940 941 checkAllFixedVolumeDevices(); 942 checkAllAliasStreamVolumes(); 943 checkMuteAffectedStreams(); 944 } 945 946 private void dumpStreamStates(PrintWriter pw) { 947 pw.println("\nStream volumes (device: index)"); 948 int numStreamTypes = AudioSystem.getNumStreamTypes(); 949 for (int i = 0; i < numStreamTypes; i++) { 950 pw.println("- " + AudioSystem.STREAM_NAMES[i] + ":"); 951 mStreamStates[i].dump(pw); 952 pw.println(""); 953 } 954 pw.print("\n- mute affected streams = 0x"); 955 pw.println(Integer.toHexString(mMuteAffectedStreams)); 956 } 957 958 private void updateStreamVolumeAlias(boolean updateVolumes, String caller) { 959 int dtmfStreamAlias; 960 961 switch (mPlatformType) { 962 case AudioSystem.PLATFORM_VOICE: 963 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE; 964 dtmfStreamAlias = AudioSystem.STREAM_RING; 965 break; 966 case AudioSystem.PLATFORM_TELEVISION: 967 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION; 968 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 969 break; 970 default: 971 mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT; 972 dtmfStreamAlias = AudioSystem.STREAM_MUSIC; 973 } 974 975 if (isPlatformTelevision()) { 976 mRingerModeAffectedStreams = 0; 977 } else { 978 if (isInCommunication()) { 979 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL; 980 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF); 981 } else { 982 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF); 983 } 984 } 985 986 mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; 987 if (updateVolumes) { 988 mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias], 989 caller); 990 // apply stream mute states according to new value of mRingerModeAffectedStreams 991 setRingerModeInt(getRingerModeInternal(), false); 992 sendMsg(mAudioHandler, 993 MSG_SET_ALL_VOLUMES, 994 SENDMSG_QUEUE, 995 0, 996 0, 997 mStreamStates[AudioSystem.STREAM_DTMF], 0); 998 } 999 } 1000 1001 private void readDockAudioSettings(ContentResolver cr) 1002 { 1003 mDockAudioMediaEnabled = Settings.Global.getInt( 1004 cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1; 1005 1006 sendMsg(mAudioHandler, 1007 MSG_SET_FORCE_USE, 1008 SENDMSG_QUEUE, 1009 AudioSystem.FOR_DOCK, 1010 mDockAudioMediaEnabled ? 1011 AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE, 1012 null, 1013 0); 1014 } 1015 1016 1017 private void updateMasterMono(ContentResolver cr) 1018 { 1019 final boolean masterMono = System.getIntForUser( 1020 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1; 1021 if (DEBUG_VOL) { 1022 Log.d(TAG, String.format("Master mono %b", masterMono)); 1023 } 1024 AudioSystem.setMasterMono(masterMono); 1025 } 1026 1027 private void sendEncodedSurroundMode(ContentResolver cr) 1028 { 1029 int encodedSurroundMode = Settings.Global.getInt( 1030 cr, Settings.Global.ENCODED_SURROUND_OUTPUT, 1031 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO); 1032 sendEncodedSurroundMode(encodedSurroundMode); 1033 } 1034 1035 private void sendEncodedSurroundMode(int encodedSurroundMode) 1036 { 1037 // initialize to guaranteed bad value 1038 int forceSetting = AudioSystem.NUM_FORCE_CONFIG; 1039 switch (encodedSurroundMode) { 1040 case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO: 1041 forceSetting = AudioSystem.FORCE_NONE; 1042 break; 1043 case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER: 1044 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER; 1045 break; 1046 case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS: 1047 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS; 1048 break; 1049 default: 1050 Log.e(TAG, "updateSurroundSoundSettings: illegal value " 1051 + encodedSurroundMode); 1052 break; 1053 } 1054 if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) { 1055 sendMsg(mAudioHandler, 1056 MSG_SET_FORCE_USE, 1057 SENDMSG_QUEUE, 1058 AudioSystem.FOR_ENCODED_SURROUND, 1059 forceSetting, 1060 null, 1061 0); 1062 } 1063 } 1064 1065 private void readPersistedSettings() { 1066 final ContentResolver cr = mContentResolver; 1067 1068 int ringerModeFromSettings = 1069 Settings.Global.getInt( 1070 cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); 1071 int ringerMode = ringerModeFromSettings; 1072 // sanity check in case the settings are restored from a device with incompatible 1073 // ringer modes 1074 if (!isValidRingerMode(ringerMode)) { 1075 ringerMode = AudioManager.RINGER_MODE_NORMAL; 1076 } 1077 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 1078 ringerMode = AudioManager.RINGER_MODE_SILENT; 1079 } 1080 if (ringerMode != ringerModeFromSettings) { 1081 Settings.Global.putInt(cr, Settings.Global.MODE_RINGER, ringerMode); 1082 } 1083 if (mUseFixedVolume || isPlatformTelevision()) { 1084 ringerMode = AudioManager.RINGER_MODE_NORMAL; 1085 } 1086 synchronized(mSettingsLock) { 1087 mRingerMode = ringerMode; 1088 if (mRingerModeExternal == -1) { 1089 mRingerModeExternal = mRingerMode; 1090 } 1091 1092 // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting 1093 // are still needed while setVibrateSetting() and getVibrateSetting() are being 1094 // deprecated. 1095 mVibrateSetting = AudioSystem.getValueForVibrateSetting(0, 1096 AudioManager.VIBRATE_TYPE_NOTIFICATION, 1097 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 1098 : AudioManager.VIBRATE_SETTING_OFF); 1099 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, 1100 AudioManager.VIBRATE_TYPE_RINGER, 1101 mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT 1102 : AudioManager.VIBRATE_SETTING_OFF); 1103 1104 updateRingerModeAffectedStreams(); 1105 readDockAudioSettings(cr); 1106 sendEncodedSurroundMode(cr); 1107 } 1108 1109 mMuteAffectedStreams = System.getIntForUser(cr, 1110 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, 1111 UserHandle.USER_CURRENT); 1112 1113 updateMasterMono(cr); 1114 1115 // Each stream will read its own persisted settings 1116 1117 // Broadcast the sticky intents 1118 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal); 1119 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode); 1120 1121 // Broadcast vibrate settings 1122 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); 1123 broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION); 1124 1125 // Load settings for the volume controller 1126 mVolumeController.loadSettings(cr); 1127 } 1128 1129 private void readUserRestrictions() { 1130 final int currentUser = getCurrentUserId(); 1131 1132 // Check the current user restriction. 1133 boolean masterMute = 1134 mUserManagerInternal.getUserRestriction(currentUser, 1135 UserManager.DISALLLOW_UNMUTE_DEVICE) 1136 || mUserManagerInternal.getUserRestriction(currentUser, 1137 UserManager.DISALLOW_ADJUST_VOLUME); 1138 if (mUseFixedVolume) { 1139 masterMute = false; 1140 AudioSystem.setMasterVolume(1.0f); 1141 } 1142 if (DEBUG_VOL) { 1143 Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser)); 1144 } 1145 setSystemAudioMute(masterMute); 1146 AudioSystem.setMasterMute(masterMute); 1147 broadcastMasterMuteStatus(masterMute); 1148 1149 boolean microphoneMute = mUserManagerInternal.getUserRestriction( 1150 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE); 1151 if (DEBUG_VOL) { 1152 Log.d(TAG, String.format("Mic mute %s, user=%d", microphoneMute, currentUser)); 1153 } 1154 AudioSystem.muteMicrophone(microphoneMute); 1155 } 1156 1157 private int rescaleIndex(int index, int srcStream, int dstStream) { 1158 return (index * mStreamStates[dstStream].getMaxIndex() + mStreamStates[srcStream].getMaxIndex() / 2) / mStreamStates[srcStream].getMaxIndex(); 1159 } 1160 1161 /////////////////////////////////////////////////////////////////////////// 1162 // IPC methods 1163 /////////////////////////////////////////////////////////////////////////// 1164 /** @see AudioManager#adjustVolume(int, int) */ 1165 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 1166 String callingPackage, String caller) { 1167 adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage, 1168 caller, Binder.getCallingUid()); 1169 } 1170 1171 private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, 1172 String callingPackage, String caller, int uid) { 1173 if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType 1174 + ", flags=" + flags + ", caller=" + caller); 1175 int streamType; 1176 boolean isMute = isMuteAdjust(direction); 1177 if (mVolumeControlStream != -1) { 1178 streamType = mVolumeControlStream; 1179 } else { 1180 streamType = getActiveStreamType(suggestedStreamType); 1181 } 1182 ensureValidStreamType(streamType); 1183 final int resolvedStream = mStreamVolumeAlias[streamType]; 1184 1185 // Play sounds on STREAM_RING only. 1186 if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && 1187 resolvedStream != AudioSystem.STREAM_RING) { 1188 flags &= ~AudioManager.FLAG_PLAY_SOUND; 1189 } 1190 1191 // For notifications/ring, show the ui before making any adjustments 1192 // Don't suppress mute/unmute requests 1193 if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) { 1194 direction = 0; 1195 flags &= ~AudioManager.FLAG_PLAY_SOUND; 1196 flags &= ~AudioManager.FLAG_VIBRATE; 1197 if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); 1198 } 1199 1200 adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid); 1201 } 1202 1203 /** @see AudioManager#adjustStreamVolume(int, int, int) */ 1204 public void adjustStreamVolume(int streamType, int direction, int flags, 1205 String callingPackage) { 1206 adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage, 1207 Binder.getCallingUid()); 1208 } 1209 1210 private void adjustStreamVolume(int streamType, int direction, int flags, 1211 String callingPackage, String caller, int uid) { 1212 if (mUseFixedVolume) { 1213 return; 1214 } 1215 if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction 1216 + ", flags=" + flags + ", caller=" + caller); 1217 1218 ensureValidDirection(direction); 1219 ensureValidStreamType(streamType); 1220 1221 boolean isMuteAdjust = isMuteAdjust(direction); 1222 1223 if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { 1224 return; 1225 } 1226 1227 // use stream type alias here so that streams with same alias have the same behavior, 1228 // including with regard to silent mode control (e.g the use of STREAM_RING below and in 1229 // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION) 1230 int streamTypeAlias = mStreamVolumeAlias[streamType]; 1231 1232 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 1233 1234 final int device = getDeviceForStream(streamTypeAlias); 1235 1236 int aliasIndex = streamState.getIndex(device); 1237 boolean adjustVolume = true; 1238 int step; 1239 1240 // skip a2dp absolute volume control request when the device 1241 // is not an a2dp device 1242 if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 && 1243 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 1244 return; 1245 } 1246 1247 // If we are being called by the system (e.g. hardware keys) check for current user 1248 // so we handle user restrictions correctly. 1249 if (uid == android.os.Process.SYSTEM_UID) { 1250 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 1251 } 1252 if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) 1253 != AppOpsManager.MODE_ALLOWED) { 1254 return; 1255 } 1256 1257 // reset any pending volume command 1258 synchronized (mSafeMediaVolumeState) { 1259 mPendingVolumeCommand = null; 1260 } 1261 1262 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 1263 if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && 1264 ((device & mFixedVolumeDevices) != 0)) { 1265 flags |= AudioManager.FLAG_FIXED_VOLUME; 1266 1267 // Always toggle between max safe volume and 0 for fixed volume devices where safe 1268 // volume is enforced, and max and 0 for the others. 1269 // This is simulated by stepping by the full allowed volume range 1270 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && 1271 (device & mSafeMediaVolumeDevices) != 0) { 1272 step = mSafeMediaVolumeIndex; 1273 } else { 1274 step = streamState.getMaxIndex(); 1275 } 1276 if (aliasIndex != 0) { 1277 aliasIndex = step; 1278 } 1279 } else { 1280 // convert one UI step (+/-1) into a number of internal units on the stream alias 1281 step = rescaleIndex(10, streamType, streamTypeAlias); 1282 } 1283 1284 // If either the client forces allowing ringer modes for this adjustment, 1285 // or the stream type is one that is affected by ringer modes 1286 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 1287 (streamTypeAlias == getUiSoundsStreamType())) { 1288 int ringerMode = getRingerModeInternal(); 1289 // do not vibrate if already in vibrate mode 1290 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { 1291 flags &= ~AudioManager.FLAG_VIBRATE; 1292 } 1293 // Check if the ringer mode handles this adjustment. If it does we don't 1294 // need to adjust the volume further. 1295 final int result = checkForRingerModeChange(aliasIndex, direction, step, 1296 streamState.mIsMuted, callingPackage, flags); 1297 adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0; 1298 // If suppressing a volume adjustment in silent mode, display the UI hint 1299 if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) { 1300 flags |= AudioManager.FLAG_SHOW_SILENT_HINT; 1301 } 1302 // If suppressing a volume down adjustment in vibrate mode, display the UI hint 1303 if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) { 1304 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT; 1305 } 1306 } 1307 // If the ringermode is suppressing media, prevent changes 1308 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 1309 adjustVolume = false; 1310 } 1311 int oldIndex = mStreamStates[streamType].getIndex(device); 1312 1313 if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) { 1314 mAudioHandler.removeMessages(MSG_UNMUTE_STREAM); 1315 1316 // Check if volume update should be send to AVRCP 1317 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && 1318 (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && 1319 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 1320 synchronized (mA2dpAvrcpLock) { 1321 if (mA2dp != null && mAvrcpAbsVolSupported) { 1322 mA2dp.adjustAvrcpAbsoluteVolume(direction); 1323 } 1324 } 1325 } 1326 1327 if (isMuteAdjust) { 1328 boolean state; 1329 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) { 1330 state = !streamState.mIsMuted; 1331 } else { 1332 state = direction == AudioManager.ADJUST_MUTE; 1333 } 1334 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 1335 setSystemAudioMute(state); 1336 } 1337 for (int stream = 0; stream < mStreamStates.length; stream++) { 1338 if (streamTypeAlias == mStreamVolumeAlias[stream]) { 1339 if (!(readCameraSoundForced() 1340 && (mStreamStates[stream].getStreamType() 1341 == AudioSystem.STREAM_SYSTEM_ENFORCED))) { 1342 mStreamStates[stream].mute(state); 1343 } 1344 } 1345 } 1346 } else if ((direction == AudioManager.ADJUST_RAISE) && 1347 !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { 1348 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex); 1349 mVolumeController.postDisplaySafeVolumeWarning(flags); 1350 } else if (streamState.adjustIndex(direction * step, device, caller) 1351 || streamState.mIsMuted) { 1352 // Post message to set system volume (it in turn will post a 1353 // message to persist). 1354 if (streamState.mIsMuted) { 1355 // Unmute the stream if it was previously muted 1356 if (direction == AudioManager.ADJUST_RAISE) { 1357 // unmute immediately for volume up 1358 streamState.mute(false); 1359 } else if (direction == AudioManager.ADJUST_LOWER) { 1360 if (mPlatformType == AudioSystem.PLATFORM_TELEVISION) { 1361 sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE, 1362 streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY); 1363 } 1364 } 1365 } 1366 sendMsg(mAudioHandler, 1367 MSG_SET_DEVICE_VOLUME, 1368 SENDMSG_QUEUE, 1369 device, 1370 0, 1371 streamState, 1372 0); 1373 } 1374 1375 // Check if volume update should be sent to Hdmi system audio. 1376 int newIndex = mStreamStates[streamType].getIndex(device); 1377 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 1378 setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags); 1379 } 1380 if (mHdmiManager != null) { 1381 synchronized (mHdmiManager) { 1382 // mHdmiCecSink true => mHdmiPlaybackClient != null 1383 if (mHdmiCecSink && 1384 streamTypeAlias == AudioSystem.STREAM_MUSIC && 1385 oldIndex != newIndex) { 1386 synchronized (mHdmiPlaybackClient) { 1387 int keyCode = (direction == -1) ? KeyEvent.KEYCODE_VOLUME_DOWN : 1388 KeyEvent.KEYCODE_VOLUME_UP; 1389 final long ident = Binder.clearCallingIdentity(); 1390 try { 1391 mHdmiPlaybackClient.sendKeyEvent(keyCode, true); 1392 mHdmiPlaybackClient.sendKeyEvent(keyCode, false); 1393 } finally { 1394 Binder.restoreCallingIdentity(ident); 1395 } 1396 } 1397 } 1398 } 1399 } 1400 } 1401 int index = mStreamStates[streamType].getIndex(device); 1402 sendVolumeUpdate(streamType, oldIndex, index, flags); 1403 } 1404 1405 // Called after a delay when volume down is pressed while muted 1406 private void onUnmuteStream(int stream, int flags) { 1407 VolumeStreamState streamState = mStreamStates[stream]; 1408 streamState.mute(false); 1409 1410 final int device = getDeviceForStream(stream); 1411 final int index = mStreamStates[stream].getIndex(device); 1412 sendVolumeUpdate(stream, index, index, flags); 1413 } 1414 1415 private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) { 1416 if (mHdmiManager == null 1417 || mHdmiTvClient == null 1418 || oldVolume == newVolume 1419 || (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0) return; 1420 1421 // Sets the audio volume of AVR when we are in system audio mode. The new volume info 1422 // is tranformed to HDMI-CEC commands and passed through CEC bus. 1423 synchronized (mHdmiManager) { 1424 if (!mHdmiSystemAudioSupported) return; 1425 synchronized (mHdmiTvClient) { 1426 final long token = Binder.clearCallingIdentity(); 1427 try { 1428 mHdmiTvClient.setSystemAudioVolume(oldVolume, newVolume, maxVolume); 1429 } finally { 1430 Binder.restoreCallingIdentity(token); 1431 } 1432 } 1433 } 1434 } 1435 1436 // StreamVolumeCommand contains the information needed to defer the process of 1437 // setStreamVolume() in case the user has to acknowledge the safe volume warning message. 1438 class StreamVolumeCommand { 1439 public final int mStreamType; 1440 public final int mIndex; 1441 public final int mFlags; 1442 public final int mDevice; 1443 1444 StreamVolumeCommand(int streamType, int index, int flags, int device) { 1445 mStreamType = streamType; 1446 mIndex = index; 1447 mFlags = flags; 1448 mDevice = device; 1449 } 1450 1451 @Override 1452 public String toString() { 1453 return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=") 1454 .append(mIndex).append(",flags=").append(mFlags).append(",device=") 1455 .append(mDevice).append('}').toString(); 1456 } 1457 }; 1458 1459 private int getNewRingerMode(int stream, int index, int flags) { 1460 // setting volume on ui sounds stream type also controls silent mode 1461 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 1462 (stream == getUiSoundsStreamType())) { 1463 int newRingerMode; 1464 if (index == 0) { 1465 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE 1466 : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT 1467 : AudioManager.RINGER_MODE_NORMAL; 1468 } else { 1469 newRingerMode = AudioManager.RINGER_MODE_NORMAL; 1470 } 1471 return newRingerMode; 1472 } 1473 return getRingerModeExternal(); 1474 } 1475 1476 private boolean isAndroidNPlus(String caller) { 1477 try { 1478 final ApplicationInfo applicationInfo = 1479 mContext.getPackageManager().getApplicationInfoAsUser( 1480 caller, 0, UserHandle.getUserId(Binder.getCallingUid())); 1481 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { 1482 return true; 1483 } 1484 return false; 1485 } catch (PackageManager.NameNotFoundException e) { 1486 return true; 1487 } 1488 } 1489 1490 private boolean wouldToggleZenMode(int newMode) { 1491 if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT 1492 && newMode != AudioManager.RINGER_MODE_SILENT) { 1493 return true; 1494 } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT 1495 && newMode == AudioManager.RINGER_MODE_SILENT) { 1496 return true; 1497 } 1498 return false; 1499 } 1500 1501 private void onSetStreamVolume(int streamType, int index, int flags, int device, 1502 String caller) { 1503 final int stream = mStreamVolumeAlias[streamType]; 1504 setStreamVolumeInt(stream, index, device, false, caller); 1505 // setting volume on ui sounds stream type also controls silent mode 1506 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 1507 (stream == getUiSoundsStreamType())) { 1508 setRingerMode(getNewRingerMode(stream, index, flags), 1509 TAG + ".onSetStreamVolume", false /*external*/); 1510 } 1511 // setting non-zero volume for a muted stream unmutes the stream and vice versa 1512 mStreamStates[stream].mute(index == 0); 1513 } 1514 1515 /** @see AudioManager#setStreamVolume(int, int, int) */ 1516 public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { 1517 setStreamVolume(streamType, index, flags, callingPackage, callingPackage, 1518 Binder.getCallingUid()); 1519 } 1520 1521 private void setStreamVolume(int streamType, int index, int flags, String callingPackage, 1522 String caller, int uid) { 1523 if (mUseFixedVolume) { 1524 return; 1525 } 1526 1527 ensureValidStreamType(streamType); 1528 int streamTypeAlias = mStreamVolumeAlias[streamType]; 1529 VolumeStreamState streamState = mStreamStates[streamTypeAlias]; 1530 1531 final int device = getDeviceForStream(streamType); 1532 int oldIndex; 1533 1534 // skip a2dp absolute volume control request when the device 1535 // is not an a2dp device 1536 if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 && 1537 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { 1538 return; 1539 } 1540 // If we are being called by the system (e.g. hardware keys) check for current user 1541 // so we handle user restrictions correctly. 1542 if (uid == android.os.Process.SYSTEM_UID) { 1543 uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid)); 1544 } 1545 if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) 1546 != AppOpsManager.MODE_ALLOWED) { 1547 return; 1548 } 1549 1550 if (isAndroidNPlus(callingPackage) 1551 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags)) 1552 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) { 1553 throw new SecurityException("Not allowed to change Do Not Disturb state"); 1554 } 1555 1556 if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) { 1557 return; 1558 } 1559 1560 synchronized (mSafeMediaVolumeState) { 1561 // reset any pending volume command 1562 mPendingVolumeCommand = null; 1563 1564 oldIndex = streamState.getIndex(device); 1565 1566 index = rescaleIndex(index * 10, streamType, streamTypeAlias); 1567 1568 if (streamTypeAlias == AudioSystem.STREAM_MUSIC && 1569 (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && 1570 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { 1571 synchronized (mA2dpAvrcpLock) { 1572 if (mA2dp != null && mAvrcpAbsVolSupported) { 1573 mA2dp.setAvrcpAbsoluteVolume(index / 10); 1574 } 1575 } 1576 } 1577 1578 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) { 1579 setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags); 1580 } 1581 1582 flags &= ~AudioManager.FLAG_FIXED_VOLUME; 1583 if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && 1584 ((device & mFixedVolumeDevices) != 0)) { 1585 flags |= AudioManager.FLAG_FIXED_VOLUME; 1586 1587 // volume is either 0 or max allowed for fixed volume devices 1588 if (index != 0) { 1589 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE && 1590 (device & mSafeMediaVolumeDevices) != 0) { 1591 index = mSafeMediaVolumeIndex; 1592 } else { 1593 index = streamState.getMaxIndex(); 1594 } 1595 } 1596 } 1597 1598 if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { 1599 mVolumeController.postDisplaySafeVolumeWarning(flags); 1600 mPendingVolumeCommand = new StreamVolumeCommand( 1601 streamType, index, flags, device); 1602 } else { 1603 onSetStreamVolume(streamType, index, flags, device, caller); 1604 index = mStreamStates[streamType].getIndex(device); 1605 } 1606 } 1607 sendVolumeUpdate(streamType, oldIndex, index, flags); 1608 } 1609 1610 // No ringer affected streams can be changed in total silence mode except those that 1611 // will cause the device to exit total silence mode. 1612 private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) { 1613 if (mNm.getZenMode() == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS 1614 && isStreamMutedByRingerMode(streamTypeAlias)) { 1615 if (!(((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || 1616 (streamTypeAlias == getUiSoundsStreamType()))) { 1617 return false; 1618 } 1619 } 1620 return true; 1621 } 1622 1623 /** @see AudioManager#forceVolumeControlStream(int) */ 1624 public void forceVolumeControlStream(int streamType, IBinder cb) { 1625 synchronized(mForceControlStreamLock) { 1626 mVolumeControlStream = streamType; 1627 if (mVolumeControlStream == -1) { 1628 if (mForceControlStreamClient != null) { 1629 mForceControlStreamClient.release(); 1630 mForceControlStreamClient = null; 1631 } 1632 } else { 1633 mForceControlStreamClient = new ForceControlStreamClient(cb); 1634 } 1635 } 1636 } 1637 1638 private class ForceControlStreamClient implements IBinder.DeathRecipient { 1639 private IBinder mCb; // To be notified of client's death 1640 1641 ForceControlStreamClient(IBinder cb) { 1642 if (cb != null) { 1643 try { 1644 cb.linkToDeath(this, 0); 1645 } catch (RemoteException e) { 1646 // Client has died! 1647 Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death"); 1648 cb = null; 1649 } 1650 } 1651 mCb = cb; 1652 } 1653 1654 public void binderDied() { 1655 synchronized(mForceControlStreamLock) { 1656 Log.w(TAG, "SCO client died"); 1657 if (mForceControlStreamClient != this) { 1658 Log.w(TAG, "unregistered control stream client died"); 1659 } else { 1660 mForceControlStreamClient = null; 1661 mVolumeControlStream = -1; 1662 } 1663 } 1664 } 1665 1666 public void release() { 1667 if (mCb != null) { 1668 mCb.unlinkToDeath(this, 0); 1669 mCb = null; 1670 } 1671 } 1672 } 1673 1674 private void sendBroadcastToAll(Intent intent) { 1675 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1676 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1677 final long ident = Binder.clearCallingIdentity(); 1678 try { 1679 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 1680 } finally { 1681 Binder.restoreCallingIdentity(ident); 1682 } 1683 } 1684 1685 private void sendStickyBroadcastToAll(Intent intent) { 1686 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1687 final long ident = Binder.clearCallingIdentity(); 1688 try { 1689 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1690 } finally { 1691 Binder.restoreCallingIdentity(ident); 1692 } 1693 } 1694 1695 private int getCurrentUserId() { 1696 final long ident = Binder.clearCallingIdentity(); 1697 try { 1698 UserInfo currentUser = ActivityManagerNative.getDefault().getCurrentUser(); 1699 return currentUser.id; 1700 } catch (RemoteException e) { 1701 // Activity manager not running, nothing we can do assume user 0. 1702 } finally { 1703 Binder.restoreCallingIdentity(ident); 1704 } 1705 return UserHandle.USER_SYSTEM; 1706 } 1707 1708 // UI update and Broadcast Intent 1709 private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) { 1710 streamType = mStreamVolumeAlias[streamType]; 1711 1712 if (streamType == AudioSystem.STREAM_MUSIC) { 1713 flags = updateFlagsForSystemAudio(flags); 1714 } 1715 mVolumeController.postVolumeChanged(streamType, flags); 1716 } 1717 1718 // If Hdmi-CEC system audio mode is on, we show volume bar only when TV 1719 // receives volume notification from Audio Receiver. 1720 private int updateFlagsForSystemAudio(int flags) { 1721 if (mHdmiTvClient != null) { 1722 synchronized (mHdmiTvClient) { 1723 if (mHdmiSystemAudioSupported && 1724 ((flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0)) { 1725 flags &= ~AudioManager.FLAG_SHOW_UI; 1726 } 1727 } 1728 } 1729 return flags; 1730 } 1731 1732 // UI update and Broadcast Intent 1733 private void sendMasterMuteUpdate(boolean muted, int flags) { 1734 mVolumeController.postMasterMuteChanged(updateFlagsForSystemAudio(flags)); 1735 broadcastMasterMuteStatus(muted); 1736 } 1737 1738 private void broadcastMasterMuteStatus(boolean muted) { 1739 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); 1740 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted); 1741 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 1742 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 1743 sendStickyBroadcastToAll(intent); 1744 } 1745 1746 /** 1747 * Sets the stream state's index, and posts a message to set system volume. 1748 * This will not call out to the UI. Assumes a valid stream type. 1749 * 1750 * @param streamType Type of the stream 1751 * @param index Desired volume index of the stream 1752 * @param device the device whose volume must be changed 1753 * @param force If true, set the volume even if the desired volume is same 1754 * as the current volume. 1755 */ 1756 private void setStreamVolumeInt(int streamType, 1757 int index, 1758 int device, 1759 boolean force, 1760 String caller) { 1761 VolumeStreamState streamState = mStreamStates[streamType]; 1762 1763 if (streamState.setIndex(index, device, caller) || force) { 1764 // Post message to set system volume (it in turn will post a message 1765 // to persist). 1766 sendMsg(mAudioHandler, 1767 MSG_SET_DEVICE_VOLUME, 1768 SENDMSG_QUEUE, 1769 device, 1770 0, 1771 streamState, 1772 0); 1773 } 1774 } 1775 1776 private void setSystemAudioMute(boolean state) { 1777 if (mHdmiManager == null || mHdmiTvClient == null) return; 1778 synchronized (mHdmiManager) { 1779 if (!mHdmiSystemAudioSupported) return; 1780 synchronized (mHdmiTvClient) { 1781 final long token = Binder.clearCallingIdentity(); 1782 try { 1783 mHdmiTvClient.setSystemAudioMute(state); 1784 } finally { 1785 Binder.restoreCallingIdentity(token); 1786 } 1787 } 1788 } 1789 } 1790 1791 /** get stream mute state. */ 1792 public boolean isStreamMute(int streamType) { 1793 if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { 1794 streamType = getActiveStreamType(streamType); 1795 } 1796 synchronized (VolumeStreamState.class) { 1797 return mStreamStates[streamType].mIsMuted; 1798 } 1799 } 1800 1801 private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient { 1802 private IBinder mICallback; // To be notified of client's death 1803 1804 RmtSbmxFullVolDeathHandler(IBinder cb) { 1805 mICallback = cb; 1806 try { 1807 cb.linkToDeath(this, 0/*flags*/); 1808 } catch (RemoteException e) { 1809 Log.e(TAG, "can't link to death", e); 1810 } 1811 } 1812 1813 boolean isHandlerFor(IBinder cb) { 1814 return mICallback.equals(cb); 1815 } 1816 1817 void forget() { 1818 try { 1819 mICallback.unlinkToDeath(this, 0/*flags*/); 1820 } catch (NoSuchElementException e) { 1821 Log.e(TAG, "error unlinking to death", e); 1822 } 1823 } 1824 1825 public void binderDied() { 1826 Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback); 1827 forceRemoteSubmixFullVolume(false, mICallback); 1828 } 1829 } 1830 1831 /** 1832 * call must be synchronized on mRmtSbmxFullVolDeathHandlers 1833 * @return true if there is a registered death handler, false otherwise */ 1834 private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 1835 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 1836 while (it.hasNext()) { 1837 final RmtSbmxFullVolDeathHandler handler = it.next(); 1838 if (handler.isHandlerFor(cb)) { 1839 handler.forget(); 1840 mRmtSbmxFullVolDeathHandlers.remove(handler); 1841 return true; 1842 } 1843 } 1844 return false; 1845 } 1846 1847 /** call synchronized on mRmtSbmxFullVolDeathHandlers */ 1848 private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) { 1849 Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator(); 1850 while (it.hasNext()) { 1851 if (it.next().isHandlerFor(cb)) { 1852 return true; 1853 } 1854 } 1855 return false; 1856 } 1857 1858 private int mRmtSbmxFullVolRefCount = 0; 1859 private ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers = 1860 new ArrayList<RmtSbmxFullVolDeathHandler>(); 1861 1862 public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) { 1863 if (cb == null) { 1864 return; 1865 } 1866 if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission( 1867 android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) { 1868 Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT"); 1869 return; 1870 } 1871 synchronized(mRmtSbmxFullVolDeathHandlers) { 1872 boolean applyRequired = false; 1873 if (startForcing) { 1874 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) { 1875 mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb)); 1876 if (mRmtSbmxFullVolRefCount == 0) { 1877 mFullVolumeDevices |= AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 1878 mFixedVolumeDevices |= AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 1879 applyRequired = true; 1880 } 1881 mRmtSbmxFullVolRefCount++; 1882 } 1883 } else { 1884 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) { 1885 mRmtSbmxFullVolRefCount--; 1886 if (mRmtSbmxFullVolRefCount == 0) { 1887 mFullVolumeDevices &= ~AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 1888 mFixedVolumeDevices &= ~AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 1889 applyRequired = true; 1890 } 1891 } 1892 } 1893 if (applyRequired) { 1894 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX 1895 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC); 1896 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes(); 1897 } 1898 } 1899 } 1900 1901 private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, 1902 int userId) { 1903 // If we are being called by the system check for user we are going to change 1904 // so we handle user restrictions correctly. 1905 if (uid == android.os.Process.SYSTEM_UID) { 1906 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 1907 } 1908 // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting. 1909 if (!mute && mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage) 1910 != AppOpsManager.MODE_ALLOWED) { 1911 return; 1912 } 1913 if (userId != UserHandle.getCallingUserId() && 1914 mContext.checkCallingOrSelfPermission( 1915 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 1916 != PackageManager.PERMISSION_GRANTED) { 1917 return; 1918 } 1919 setMasterMuteInternalNoCallerCheck(mute, flags, userId); 1920 } 1921 1922 private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) { 1923 if (DEBUG_VOL) { 1924 Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId)); 1925 } 1926 if (mUseFixedVolume) { 1927 return; // If using fixed volume, we don't mute. 1928 } 1929 if (getCurrentUserId() == userId) { 1930 if (mute != AudioSystem.getMasterMute()) { 1931 setSystemAudioMute(mute); 1932 AudioSystem.setMasterMute(mute); 1933 sendMasterMuteUpdate(mute, flags); 1934 1935 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION); 1936 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, mute); 1937 sendBroadcastToAll(intent); 1938 } 1939 } 1940 } 1941 1942 /** get master mute state. */ 1943 public boolean isMasterMute() { 1944 return AudioSystem.getMasterMute(); 1945 } 1946 1947 public void setMasterMute(boolean mute, int flags, String callingPackage, int userId) { 1948 setMasterMuteInternal(mute, flags, callingPackage, Binder.getCallingUid(), 1949 userId); 1950 } 1951 1952 /** @see AudioManager#getStreamVolume(int) */ 1953 public int getStreamVolume(int streamType) { 1954 ensureValidStreamType(streamType); 1955 int device = getDeviceForStream(streamType); 1956 synchronized (VolumeStreamState.class) { 1957 int index = mStreamStates[streamType].getIndex(device); 1958 1959 // by convention getStreamVolume() returns 0 when a stream is muted. 1960 if (mStreamStates[streamType].mIsMuted) { 1961 index = 0; 1962 } 1963 if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) && 1964 (device & mFixedVolumeDevices) != 0) { 1965 index = mStreamStates[streamType].getMaxIndex(); 1966 } 1967 return (index + 5) / 10; 1968 } 1969 } 1970 1971 /** @see AudioManager#getStreamMaxVolume(int) */ 1972 public int getStreamMaxVolume(int streamType) { 1973 ensureValidStreamType(streamType); 1974 return (mStreamStates[streamType].getMaxIndex() + 5) / 10; 1975 } 1976 1977 /** @see AudioManager#getStreamMinVolume(int) */ 1978 public int getStreamMinVolume(int streamType) { 1979 ensureValidStreamType(streamType); 1980 return (mStreamStates[streamType].getMinIndex() + 5) / 10; 1981 } 1982 1983 /** Get last audible volume before stream was muted. */ 1984 public int getLastAudibleStreamVolume(int streamType) { 1985 ensureValidStreamType(streamType); 1986 int device = getDeviceForStream(streamType); 1987 return (mStreamStates[streamType].getIndex(device) + 5) / 10; 1988 } 1989 1990 /** @see AudioManager#getUiSoundsStreamType() */ 1991 public int getUiSoundsStreamType() { 1992 return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM]; 1993 } 1994 1995 /** @see AudioManager#setMicrophoneMute(boolean) */ 1996 @Override 1997 public void setMicrophoneMute(boolean on, String callingPackage, int userId) { 1998 // If we are being called by the system check for user we are going to change 1999 // so we handle user restrictions correctly. 2000 int uid = Binder.getCallingUid(); 2001 if (uid == android.os.Process.SYSTEM_UID) { 2002 uid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 2003 } 2004 // If OP_MUTE_MICROPHONE is set, disallow unmuting. 2005 if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage) 2006 != AppOpsManager.MODE_ALLOWED) { 2007 return; 2008 } 2009 if (!checkAudioSettingsPermission("setMicrophoneMute()")) { 2010 return; 2011 } 2012 if (userId != UserHandle.getCallingUserId() && 2013 mContext.checkCallingOrSelfPermission( 2014 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 2015 != PackageManager.PERMISSION_GRANTED) { 2016 return; 2017 } 2018 setMicrophoneMuteNoCallerCheck(on, userId); 2019 } 2020 2021 private void setMicrophoneMuteNoCallerCheck(boolean on, int userId) { 2022 if (DEBUG_VOL) { 2023 Log.d(TAG, String.format("Mic mute %s, user=%d", on, userId)); 2024 } 2025 // If mute is for current user actually mute, else just persist the setting 2026 // which will be loaded on user switch. 2027 if (getCurrentUserId() == userId) { 2028 AudioSystem.muteMicrophone(on); 2029 } 2030 // Post a persist microphone msg. 2031 } 2032 2033 @Override 2034 public int getRingerModeExternal() { 2035 synchronized(mSettingsLock) { 2036 return mRingerModeExternal; 2037 } 2038 } 2039 2040 @Override 2041 public int getRingerModeInternal() { 2042 synchronized(mSettingsLock) { 2043 return mRingerMode; 2044 } 2045 } 2046 2047 private void ensureValidRingerMode(int ringerMode) { 2048 if (!isValidRingerMode(ringerMode)) { 2049 throw new IllegalArgumentException("Bad ringer mode " + ringerMode); 2050 } 2051 } 2052 2053 /** @see AudioManager#isValidRingerMode(int) */ 2054 public boolean isValidRingerMode(int ringerMode) { 2055 return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; 2056 } 2057 2058 public void setRingerModeExternal(int ringerMode, String caller) { 2059 if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode) 2060 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) { 2061 throw new SecurityException("Not allowed to change Do Not Disturb state"); 2062 } 2063 2064 setRingerMode(ringerMode, caller, true /*external*/); 2065 } 2066 2067 public void setRingerModeInternal(int ringerMode, String caller) { 2068 enforceVolumeController("setRingerModeInternal"); 2069 setRingerMode(ringerMode, caller, false /*external*/); 2070 } 2071 2072 private void setRingerMode(int ringerMode, String caller, boolean external) { 2073 if (mUseFixedVolume || isPlatformTelevision()) { 2074 return; 2075 } 2076 if (caller == null || caller.length() == 0) { 2077 throw new IllegalArgumentException("Bad caller: " + caller); 2078 } 2079 ensureValidRingerMode(ringerMode); 2080 if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { 2081 ringerMode = AudioManager.RINGER_MODE_SILENT; 2082 } 2083 final long identity = Binder.clearCallingIdentity(); 2084 try { 2085 synchronized (mSettingsLock) { 2086 final int ringerModeInternal = getRingerModeInternal(); 2087 final int ringerModeExternal = getRingerModeExternal(); 2088 if (external) { 2089 setRingerModeExt(ringerMode); 2090 if (mRingerModeDelegate != null) { 2091 ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal, 2092 ringerMode, caller, ringerModeInternal, mVolumePolicy); 2093 } 2094 if (ringerMode != ringerModeInternal) { 2095 setRingerModeInt(ringerMode, true /*persist*/); 2096 } 2097 } else /*internal*/ { 2098 if (ringerMode != ringerModeInternal) { 2099 setRingerModeInt(ringerMode, true /*persist*/); 2100 } 2101 if (mRingerModeDelegate != null) { 2102 ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal, 2103 ringerMode, caller, ringerModeExternal, mVolumePolicy); 2104 } 2105 setRingerModeExt(ringerMode); 2106 } 2107 } 2108 } finally { 2109 Binder.restoreCallingIdentity(identity); 2110 } 2111 } 2112 2113 private void setRingerModeExt(int ringerMode) { 2114 synchronized(mSettingsLock) { 2115 if (ringerMode == mRingerModeExternal) return; 2116 mRingerModeExternal = ringerMode; 2117 } 2118 // Send sticky broadcast 2119 broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode); 2120 } 2121 2122 private void muteRingerModeStreams() { 2123 // Mute stream if not previously muted by ringer mode and ringer mode 2124 // is not RINGER_MODE_NORMAL and stream is affected by ringer mode. 2125 // Unmute stream if previously muted by ringer mode and ringer mode 2126 // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. 2127 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2128 final boolean ringerModeMute = mRingerMode == AudioManager.RINGER_MODE_VIBRATE 2129 || mRingerMode == AudioManager.RINGER_MODE_SILENT; 2130 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { 2131 final boolean isMuted = isStreamMutedByRingerMode(streamType); 2132 final boolean shouldMute = ringerModeMute && isStreamAffectedByRingerMode(streamType); 2133 if (isMuted == shouldMute) continue; 2134 if (!shouldMute) { 2135 // unmute 2136 // ring and notifications volume should never be 0 when not silenced 2137 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) { 2138 synchronized (VolumeStreamState.class) { 2139 final VolumeStreamState vss = mStreamStates[streamType]; 2140 for (int i = 0; i < vss.mIndexMap.size(); i++) { 2141 int device = vss.mIndexMap.keyAt(i); 2142 int value = vss.mIndexMap.valueAt(i); 2143 if (value == 0) { 2144 vss.setIndex(10, device, TAG); 2145 } 2146 } 2147 // Persist volume for stream ring when it is changed here 2148 final int device = getDeviceForStream(streamType); 2149 sendMsg(mAudioHandler, 2150 MSG_PERSIST_VOLUME, 2151 SENDMSG_QUEUE, 2152 device, 2153 0, 2154 mStreamStates[streamType], 2155 PERSIST_DELAY); 2156 } 2157 } 2158 mStreamStates[streamType].mute(false); 2159 mRingerModeMutedStreams &= ~(1 << streamType); 2160 } else { 2161 // mute 2162 mStreamStates[streamType].mute(true); 2163 mRingerModeMutedStreams |= (1 << streamType); 2164 } 2165 } 2166 } 2167 2168 private void setRingerModeInt(int ringerMode, boolean persist) { 2169 final boolean change; 2170 synchronized(mSettingsLock) { 2171 change = mRingerMode != ringerMode; 2172 mRingerMode = ringerMode; 2173 } 2174 2175 muteRingerModeStreams(); 2176 2177 // Post a persist ringer mode msg 2178 if (persist) { 2179 sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, 2180 SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY); 2181 } 2182 if (change) { 2183 // Send sticky broadcast 2184 broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode); 2185 } 2186 } 2187 2188 /** @see AudioManager#shouldVibrate(int) */ 2189 public boolean shouldVibrate(int vibrateType) { 2190 if (!mHasVibrator) return false; 2191 2192 switch (getVibrateSetting(vibrateType)) { 2193 2194 case AudioManager.VIBRATE_SETTING_ON: 2195 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT; 2196 2197 case AudioManager.VIBRATE_SETTING_ONLY_SILENT: 2198 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE; 2199 2200 case AudioManager.VIBRATE_SETTING_OFF: 2201 // return false, even for incoming calls 2202 return false; 2203 2204 default: 2205 return false; 2206 } 2207 } 2208 2209 /** @see AudioManager#getVibrateSetting(int) */ 2210 public int getVibrateSetting(int vibrateType) { 2211 if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF; 2212 return (mVibrateSetting >> (vibrateType * 2)) & 3; 2213 } 2214 2215 /** @see AudioManager#setVibrateSetting(int, int) */ 2216 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 2217 2218 if (!mHasVibrator) return; 2219 2220 mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType, 2221 vibrateSetting); 2222 2223 // Broadcast change 2224 broadcastVibrateSetting(vibrateType); 2225 2226 } 2227 2228 private class SetModeDeathHandler implements IBinder.DeathRecipient { 2229 private IBinder mCb; // To be notified of client's death 2230 private int mPid; 2231 private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client 2232 2233 SetModeDeathHandler(IBinder cb, int pid) { 2234 mCb = cb; 2235 mPid = pid; 2236 } 2237 2238 public void binderDied() { 2239 int newModeOwnerPid = 0; 2240 synchronized(mSetModeDeathHandlers) { 2241 Log.w(TAG, "setMode() client died"); 2242 int index = mSetModeDeathHandlers.indexOf(this); 2243 if (index < 0) { 2244 Log.w(TAG, "unregistered setMode() client died"); 2245 } else { 2246 newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, TAG); 2247 } 2248 } 2249 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all 2250 // SCO connections not started by the application changing the mode 2251 if (newModeOwnerPid != 0) { 2252 final long ident = Binder.clearCallingIdentity(); 2253 disconnectBluetoothSco(newModeOwnerPid); 2254 Binder.restoreCallingIdentity(ident); 2255 } 2256 } 2257 2258 public int getPid() { 2259 return mPid; 2260 } 2261 2262 public void setMode(int mode) { 2263 mMode = mode; 2264 } 2265 2266 public int getMode() { 2267 return mMode; 2268 } 2269 2270 public IBinder getBinder() { 2271 return mCb; 2272 } 2273 } 2274 2275 /** @see AudioManager#setMode(int) */ 2276 public void setMode(int mode, IBinder cb, String callingPackage) { 2277 if (DEBUG_MODE) { Log.v(TAG, "setMode(mode=" + mode + ", callingPackage=" + callingPackage + ")"); } 2278 if (!checkAudioSettingsPermission("setMode()")) { 2279 return; 2280 } 2281 2282 if ( (mode == AudioSystem.MODE_IN_CALL) && 2283 (mContext.checkCallingOrSelfPermission( 2284 android.Manifest.permission.MODIFY_PHONE_STATE) 2285 != PackageManager.PERMISSION_GRANTED)) { 2286 Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(MODE_IN_CALL) from pid=" 2287 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 2288 return; 2289 } 2290 2291 if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { 2292 return; 2293 } 2294 2295 int newModeOwnerPid = 0; 2296 synchronized(mSetModeDeathHandlers) { 2297 if (mode == AudioSystem.MODE_CURRENT) { 2298 mode = mMode; 2299 } 2300 newModeOwnerPid = setModeInt(mode, cb, Binder.getCallingPid(), callingPackage); 2301 } 2302 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all 2303 // SCO connections not started by the application changing the mode 2304 if (newModeOwnerPid != 0) { 2305 disconnectBluetoothSco(newModeOwnerPid); 2306 } 2307 } 2308 2309 // must be called synchronized on mSetModeDeathHandlers 2310 // setModeInt() returns a valid PID if the audio mode was successfully set to 2311 // any mode other than NORMAL. 2312 private int setModeInt(int mode, IBinder cb, int pid, String caller) { 2313 if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", caller=" 2314 + caller + ")"); } 2315 int newModeOwnerPid = 0; 2316 if (cb == null) { 2317 Log.e(TAG, "setModeInt() called with null binder"); 2318 return newModeOwnerPid; 2319 } 2320 2321 SetModeDeathHandler hdlr = null; 2322 Iterator iter = mSetModeDeathHandlers.iterator(); 2323 while (iter.hasNext()) { 2324 SetModeDeathHandler h = (SetModeDeathHandler)iter.next(); 2325 if (h.getPid() == pid) { 2326 hdlr = h; 2327 // Remove from client list so that it is re-inserted at top of list 2328 iter.remove(); 2329 hdlr.getBinder().unlinkToDeath(hdlr, 0); 2330 break; 2331 } 2332 } 2333 int status = AudioSystem.AUDIO_STATUS_OK; 2334 do { 2335 if (mode == AudioSystem.MODE_NORMAL) { 2336 // get new mode from client at top the list if any 2337 if (!mSetModeDeathHandlers.isEmpty()) { 2338 hdlr = mSetModeDeathHandlers.get(0); 2339 cb = hdlr.getBinder(); 2340 mode = hdlr.getMode(); 2341 if (DEBUG_MODE) { 2342 Log.w(TAG, " using mode=" + mode + " instead due to death hdlr at pid=" 2343 + hdlr.mPid); 2344 } 2345 } 2346 } else { 2347 if (hdlr == null) { 2348 hdlr = new SetModeDeathHandler(cb, pid); 2349 } 2350 // Register for client death notification 2351 try { 2352 cb.linkToDeath(hdlr, 0); 2353 } catch (RemoteException e) { 2354 // Client has died! 2355 Log.w(TAG, "setMode() could not link to "+cb+" binder death"); 2356 } 2357 2358 // Last client to call setMode() is always at top of client list 2359 // as required by SetModeDeathHandler.binderDied() 2360 mSetModeDeathHandlers.add(0, hdlr); 2361 hdlr.setMode(mode); 2362 } 2363 2364 if (mode != mMode) { 2365 status = AudioSystem.setPhoneState(mode); 2366 if (status == AudioSystem.AUDIO_STATUS_OK) { 2367 if (DEBUG_MODE) { Log.v(TAG, " mode successfully set to " + mode); } 2368 mMode = mode; 2369 } else { 2370 if (hdlr != null) { 2371 mSetModeDeathHandlers.remove(hdlr); 2372 cb.unlinkToDeath(hdlr, 0); 2373 } 2374 // force reading new top of mSetModeDeathHandlers stack 2375 if (DEBUG_MODE) { Log.w(TAG, " mode set to MODE_NORMAL after phoneState pb"); } 2376 mode = AudioSystem.MODE_NORMAL; 2377 } 2378 } else { 2379 status = AudioSystem.AUDIO_STATUS_OK; 2380 } 2381 } while (status != AudioSystem.AUDIO_STATUS_OK && !mSetModeDeathHandlers.isEmpty()); 2382 2383 if (status == AudioSystem.AUDIO_STATUS_OK) { 2384 if (mode != AudioSystem.MODE_NORMAL) { 2385 if (mSetModeDeathHandlers.isEmpty()) { 2386 Log.e(TAG, "setMode() different from MODE_NORMAL with empty mode client stack"); 2387 } else { 2388 newModeOwnerPid = mSetModeDeathHandlers.get(0).getPid(); 2389 } 2390 } 2391 int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); 2392 int device = getDeviceForStream(streamType); 2393 int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device); 2394 setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, caller); 2395 2396 updateStreamVolumeAlias(true /*updateVolumes*/, caller); 2397 } 2398 return newModeOwnerPid; 2399 } 2400 2401 /** @see AudioManager#getMode() */ 2402 public int getMode() { 2403 return mMode; 2404 } 2405 2406 //========================================================================================== 2407 // Sound Effects 2408 //========================================================================================== 2409 2410 private static final String TAG_AUDIO_ASSETS = "audio_assets"; 2411 private static final String ATTR_VERSION = "version"; 2412 private static final String TAG_GROUP = "group"; 2413 private static final String ATTR_GROUP_NAME = "name"; 2414 private static final String TAG_ASSET = "asset"; 2415 private static final String ATTR_ASSET_ID = "id"; 2416 private static final String ATTR_ASSET_FILE = "file"; 2417 2418 private static final String ASSET_FILE_VERSION = "1.0"; 2419 private static final String GROUP_TOUCH_SOUNDS = "touch_sounds"; 2420 2421 private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000; 2422 2423 class LoadSoundEffectReply { 2424 public int mStatus = 1; 2425 }; 2426 2427 private void loadTouchSoundAssetDefaults() { 2428 SOUND_EFFECT_FILES.add("Effect_Tick.ogg"); 2429 for (int i = 0; i < AudioManager.NUM_SOUND_EFFECTS; i++) { 2430 SOUND_EFFECT_FILES_MAP[i][0] = 0; 2431 SOUND_EFFECT_FILES_MAP[i][1] = -1; 2432 } 2433 } 2434 2435 private void loadTouchSoundAssets() { 2436 XmlResourceParser parser = null; 2437 2438 // only load assets once. 2439 if (!SOUND_EFFECT_FILES.isEmpty()) { 2440 return; 2441 } 2442 2443 loadTouchSoundAssetDefaults(); 2444 2445 try { 2446 parser = mContext.getResources().getXml(com.android.internal.R.xml.audio_assets); 2447 2448 XmlUtils.beginDocument(parser, TAG_AUDIO_ASSETS); 2449 String version = parser.getAttributeValue(null, ATTR_VERSION); 2450 boolean inTouchSoundsGroup = false; 2451 2452 if (ASSET_FILE_VERSION.equals(version)) { 2453 while (true) { 2454 XmlUtils.nextElement(parser); 2455 String element = parser.getName(); 2456 if (element == null) { 2457 break; 2458 } 2459 if (element.equals(TAG_GROUP)) { 2460 String name = parser.getAttributeValue(null, ATTR_GROUP_NAME); 2461 if (GROUP_TOUCH_SOUNDS.equals(name)) { 2462 inTouchSoundsGroup = true; 2463 break; 2464 } 2465 } 2466 } 2467 while (inTouchSoundsGroup) { 2468 XmlUtils.nextElement(parser); 2469 String element = parser.getName(); 2470 if (element == null) { 2471 break; 2472 } 2473 if (element.equals(TAG_ASSET)) { 2474 String id = parser.getAttributeValue(null, ATTR_ASSET_ID); 2475 String file = parser.getAttributeValue(null, ATTR_ASSET_FILE); 2476 int fx; 2477 2478 try { 2479 Field field = AudioManager.class.getField(id); 2480 fx = field.getInt(null); 2481 } catch (Exception e) { 2482 Log.w(TAG, "Invalid touch sound ID: "+id); 2483 continue; 2484 } 2485 2486 int i = SOUND_EFFECT_FILES.indexOf(file); 2487 if (i == -1) { 2488 i = SOUND_EFFECT_FILES.size(); 2489 SOUND_EFFECT_FILES.add(file); 2490 } 2491 SOUND_EFFECT_FILES_MAP[fx][0] = i; 2492 } else { 2493 break; 2494 } 2495 } 2496 } 2497 } catch (Resources.NotFoundException e) { 2498 Log.w(TAG, "audio assets file not found", e); 2499 } catch (XmlPullParserException e) { 2500 Log.w(TAG, "XML parser exception reading touch sound assets", e); 2501 } catch (IOException e) { 2502 Log.w(TAG, "I/O exception reading touch sound assets", e); 2503 } finally { 2504 if (parser != null) { 2505 parser.close(); 2506 } 2507 } 2508 } 2509 2510 /** @see AudioManager#playSoundEffect(int) */ 2511 public void playSoundEffect(int effectType) { 2512 playSoundEffectVolume(effectType, -1.0f); 2513 } 2514 2515 /** @see AudioManager#playSoundEffect(int, float) */ 2516 public void playSoundEffectVolume(int effectType, float volume) { 2517 if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) { 2518 Log.w(TAG, "AudioService effectType value " + effectType + " out of range"); 2519 return; 2520 } 2521 2522 sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE, 2523 effectType, (int) (volume * 1000), null, 0); 2524 } 2525 2526 /** 2527 * Loads samples into the soundpool. 2528 * This method must be called at first when sound effects are enabled 2529 */ 2530 public boolean loadSoundEffects() { 2531 int attempts = 3; 2532 LoadSoundEffectReply reply = new LoadSoundEffectReply(); 2533 2534 synchronized (reply) { 2535 sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0); 2536 while ((reply.mStatus == 1) && (attempts-- > 0)) { 2537 try { 2538 reply.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS); 2539 } catch (InterruptedException e) { 2540 Log.w(TAG, "loadSoundEffects Interrupted while waiting sound pool loaded."); 2541 } 2542 } 2543 } 2544 return (reply.mStatus == 0); 2545 } 2546 2547 /** 2548 * Unloads samples from the sound pool. 2549 * This method can be called to free some memory when 2550 * sound effects are disabled. 2551 */ 2552 public void unloadSoundEffects() { 2553 sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0); 2554 } 2555 2556 class SoundPoolListenerThread extends Thread { 2557 public SoundPoolListenerThread() { 2558 super("SoundPoolListenerThread"); 2559 } 2560 2561 @Override 2562 public void run() { 2563 2564 Looper.prepare(); 2565 mSoundPoolLooper = Looper.myLooper(); 2566 2567 synchronized (mSoundEffectsLock) { 2568 if (mSoundPool != null) { 2569 mSoundPoolCallBack = new SoundPoolCallback(); 2570 mSoundPool.setOnLoadCompleteListener(mSoundPoolCallBack); 2571 } 2572 mSoundEffectsLock.notify(); 2573 } 2574 Looper.loop(); 2575 } 2576 } 2577 2578 private final class SoundPoolCallback implements 2579 android.media.SoundPool.OnLoadCompleteListener { 2580 2581 int mStatus = 1; // 1 means neither error nor last sample loaded yet 2582 List<Integer> mSamples = new ArrayList<Integer>(); 2583 2584 public int status() { 2585 return mStatus; 2586 } 2587 2588 public void setSamples(int[] samples) { 2589 for (int i = 0; i < samples.length; i++) { 2590 // do not wait ack for samples rejected upfront by SoundPool 2591 if (samples[i] > 0) { 2592 mSamples.add(samples[i]); 2593 } 2594 } 2595 } 2596 2597 public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { 2598 synchronized (mSoundEffectsLock) { 2599 int i = mSamples.indexOf(sampleId); 2600 if (i >= 0) { 2601 mSamples.remove(i); 2602 } 2603 if ((status != 0) || mSamples. isEmpty()) { 2604 mStatus = status; 2605 mSoundEffectsLock.notify(); 2606 } 2607 } 2608 } 2609 } 2610 2611 /** @see AudioManager#reloadAudioSettings() */ 2612 public void reloadAudioSettings() { 2613 readAudioSettings(false /*userSwitch*/); 2614 } 2615 2616 private void readAudioSettings(boolean userSwitch) { 2617 // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings 2618 readPersistedSettings(); 2619 readUserRestrictions(); 2620 2621 // restore volume settings 2622 int numStreamTypes = AudioSystem.getNumStreamTypes(); 2623 for (int streamType = 0; streamType < numStreamTypes; streamType++) { 2624 VolumeStreamState streamState = mStreamStates[streamType]; 2625 2626 if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) { 2627 continue; 2628 } 2629 2630 streamState.readSettings(); 2631 synchronized (VolumeStreamState.class) { 2632 // unmute stream that was muted but is not affect by mute anymore 2633 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) && 2634 !isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) { 2635 streamState.mIsMuted = false; 2636 } 2637 } 2638 } 2639 2640 // apply new ringer mode before checking volume for alias streams so that streams 2641 // muted by ringer mode have the correct volume 2642 setRingerModeInt(getRingerModeInternal(), false); 2643 2644 checkAllFixedVolumeDevices(); 2645 checkAllAliasStreamVolumes(); 2646 checkMuteAffectedStreams(); 2647 2648 synchronized (mSafeMediaVolumeState) { 2649 mMusicActiveMs = MathUtils.constrain(Settings.Secure.getIntForUser(mContentResolver, 2650 Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, 0, UserHandle.USER_CURRENT), 2651 0, UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX); 2652 if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) { 2653 enforceSafeMediaVolume(TAG); 2654 } 2655 } 2656 } 2657 2658 /** @see AudioManager#setSpeakerphoneOn(boolean) */ 2659 public void setSpeakerphoneOn(boolean on){ 2660 if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { 2661 return; 2662 } 2663 2664 if (on) { 2665 if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { 2666 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, 2667 AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, null, 0); 2668 } 2669 mForcedUseForComm = AudioSystem.FORCE_SPEAKER; 2670 } else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER){ 2671 mForcedUseForComm = AudioSystem.FORCE_NONE; 2672 } 2673 2674 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, 2675 AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0); 2676 } 2677 2678 /** @see AudioManager#isSpeakerphoneOn() */ 2679 public boolean isSpeakerphoneOn() { 2680 return (mForcedUseForComm == AudioSystem.FORCE_SPEAKER); 2681 } 2682 2683 /** @see AudioManager#setBluetoothScoOn(boolean) */ 2684 public void setBluetoothScoOn(boolean on) { 2685 if (!checkAudioSettingsPermission("setBluetoothScoOn()")) { 2686 return; 2687 } 2688 setBluetoothScoOnInt(on); 2689 } 2690 2691 public void setBluetoothScoOnInt(boolean on) { 2692 if (on) { 2693 mForcedUseForComm = AudioSystem.FORCE_BT_SCO; 2694 } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { 2695 mForcedUseForComm = AudioSystem.FORCE_NONE; 2696 } 2697 2698 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, 2699 AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0); 2700 sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, 2701 AudioSystem.FOR_RECORD, mForcedUseForComm, null, 0); 2702 } 2703 2704 /** @see AudioManager#isBluetoothScoOn() */ 2705 public boolean isBluetoothScoOn() { 2706 return (mForcedUseForComm == AudioSystem.FORCE_BT_SCO); 2707 } 2708 2709 /** @see AudioManager#setBluetoothA2dpOn(boolean) */ 2710 public void setBluetoothA2dpOn(boolean on) { 2711 synchronized (mBluetoothA2dpEnabledLock) { 2712 mBluetoothA2dpEnabled = on; 2713 sendMsg(mAudioHandler, MSG_SET_FORCE_BT_A2DP_USE, SENDMSG_QUEUE, 2714 AudioSystem.FOR_MEDIA, 2715 mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP, 2716 null, 0); 2717 } 2718 } 2719 2720 /** @see AudioManager#isBluetoothA2dpOn() */ 2721 public boolean isBluetoothA2dpOn() { 2722 synchronized (mBluetoothA2dpEnabledLock) { 2723 return mBluetoothA2dpEnabled; 2724 } 2725 } 2726 2727 /** @see AudioManager#startBluetoothSco() */ 2728 public void startBluetoothSco(IBinder cb, int targetSdkVersion) { 2729 int scoAudioMode = 2730 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? 2731 SCO_MODE_VIRTUAL_CALL : SCO_MODE_UNDEFINED; 2732 startBluetoothScoInt(cb, scoAudioMode); 2733 } 2734 2735 /** @see AudioManager#startBluetoothScoVirtualCall() */ 2736 public void startBluetoothScoVirtualCall(IBinder cb) { 2737 startBluetoothScoInt(cb, SCO_MODE_VIRTUAL_CALL); 2738 } 2739 2740 void startBluetoothScoInt(IBinder cb, int scoAudioMode){ 2741 if (!checkAudioSettingsPermission("startBluetoothSco()") || 2742 !mSystemReady) { 2743 return; 2744 } 2745 ScoClient client = getScoClient(cb, true); 2746 // The calling identity must be cleared before calling ScoClient.incCount(). 2747 // inCount() calls requestScoState() which in turn can call BluetoothHeadset APIs 2748 // and this must be done on behalf of system server to make sure permissions are granted. 2749 // The caller identity must be cleared after getScoClient() because it is needed if a new 2750 // client is created. 2751 final long ident = Binder.clearCallingIdentity(); 2752 client.incCount(scoAudioMode); 2753 Binder.restoreCallingIdentity(ident); 2754 } 2755 2756 /** @see AudioManager#stopBluetoothSco() */ 2757 public void stopBluetoothSco(IBinder cb){ 2758 if (!checkAudioSettingsPermission("stopBluetoothSco()") || 2759 !mSystemReady) { 2760 return; 2761 } 2762 ScoClient client = getScoClient(cb, false); 2763 // The calling identity must be cleared before calling ScoClient.decCount(). 2764 // decCount() calls requestScoState() which in turn can call BluetoothHeadset APIs 2765 // and this must be done on behalf of system server to make sure permissions are granted. 2766 final long ident = Binder.clearCallingIdentity(); 2767 if (client != null) { 2768 client.decCount(); 2769 } 2770 Binder.restoreCallingIdentity(ident); 2771 } 2772 2773 2774 private class ScoClient implements IBinder.DeathRecipient { 2775 private IBinder mCb; // To be notified of client's death 2776 private int mCreatorPid; 2777 private int mStartcount; // number of SCO connections started by this client 2778 2779 ScoClient(IBinder cb) { 2780 mCb = cb; 2781 mCreatorPid = Binder.getCallingPid(); 2782 mStartcount = 0; 2783 } 2784 2785 public void binderDied() { 2786 synchronized(mScoClients) { 2787 Log.w(TAG, "SCO client died"); 2788 int index = mScoClients.indexOf(this); 2789 if (index < 0) { 2790 Log.w(TAG, "unregistered SCO client died"); 2791 } else { 2792 clearCount(true); 2793 mScoClients.remove(this); 2794 } 2795 } 2796 } 2797 2798 public void incCount(int scoAudioMode) { 2799 synchronized(mScoClients) { 2800 requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode); 2801 if (mStartcount == 0) { 2802 try { 2803 mCb.linkToDeath(this, 0); 2804 } catch (RemoteException e) { 2805 // client has already died! 2806 Log.w(TAG, "ScoClient incCount() could not link to "+mCb+" binder death"); 2807 } 2808 } 2809 mStartcount++; 2810 } 2811 } 2812 2813 public void decCount() { 2814 synchronized(mScoClients) { 2815 if (mStartcount == 0) { 2816 Log.w(TAG, "ScoClient.decCount() already 0"); 2817 } else { 2818 mStartcount--; 2819 if (mStartcount == 0) { 2820 try { 2821 mCb.unlinkToDeath(this, 0); 2822 } catch (NoSuchElementException e) { 2823 Log.w(TAG, "decCount() going to 0 but not registered to binder"); 2824 } 2825 } 2826 requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0); 2827 } 2828 } 2829 } 2830 2831 public void clearCount(boolean stopSco) { 2832 synchronized(mScoClients) { 2833 if (mStartcount != 0) { 2834 try { 2835 mCb.unlinkToDeath(this, 0); 2836 } catch (NoSuchElementException e) { 2837 Log.w(TAG, "clearCount() mStartcount: "+mStartcount+" != 0 but not registered to binder"); 2838 } 2839 } 2840 mStartcount = 0; 2841 if (stopSco) { 2842 requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0); 2843 } 2844 } 2845 } 2846 2847 public int getCount() { 2848 return mStartcount; 2849 } 2850 2851 public IBinder getBinder() { 2852 return mCb; 2853 } 2854 2855 public int getPid() { 2856 return mCreatorPid; 2857 } 2858 2859 public int totalCount() { 2860 synchronized(mScoClients) { 2861 int count = 0; 2862 int size = mScoClients.size(); 2863 for (int i = 0; i < size; i++) { 2864 count += mScoClients.get(i).getCount(); 2865 } 2866 return count; 2867 } 2868 } 2869 2870 private void requestScoState(int state, int scoAudioMode) { 2871 checkScoAudioState(); 2872 if (totalCount() == 0) { 2873 if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) { 2874 // Make sure that the state transitions to CONNECTING even if we cannot initiate 2875 // the connection. 2876 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING); 2877 // Accept SCO audio activation only in NORMAL audio mode or if the mode is 2878 // currently controlled by the same client process. 2879 synchronized(mSetModeDeathHandlers) { 2880 if ((mSetModeDeathHandlers.isEmpty() || 2881 mSetModeDeathHandlers.get(0).getPid() == mCreatorPid) && 2882 (mScoAudioState == SCO_STATE_INACTIVE || 2883 mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) { 2884 if (mScoAudioState == SCO_STATE_INACTIVE) { 2885 mScoAudioMode = scoAudioMode; 2886 if (scoAudioMode == SCO_MODE_UNDEFINED) { 2887 if (mBluetoothHeadsetDevice != null) { 2888 mScoAudioMode = new Integer(Settings.Global.getInt( 2889 mContentResolver, 2890 "bluetooth_sco_channel_"+ 2891 mBluetoothHeadsetDevice.getAddress(), 2892 SCO_MODE_VIRTUAL_CALL)); 2893 if (mScoAudioMode > SCO_MODE_MAX || mScoAudioMode < 0) { 2894 mScoAudioMode = SCO_MODE_VIRTUAL_CALL; 2895 } 2896 } else { 2897 mScoAudioMode = SCO_MODE_RAW; 2898 } 2899 } 2900 if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) { 2901 boolean status = false; 2902 if (mScoAudioMode == SCO_MODE_RAW) { 2903 status = mBluetoothHeadset.connectAudio(); 2904 } else if (mScoAudioMode == SCO_MODE_VIRTUAL_CALL) { 2905 status = mBluetoothHeadset.startScoUsingVirtualVoiceCall( 2906 mBluetoothHeadsetDevice); 2907 } else if (mScoAudioMode == SCO_MODE_VR) { 2908 status = mBluetoothHeadset.startVoiceRecognition( 2909 mBluetoothHeadsetDevice); 2910 } 2911 2912 if (status) { 2913 mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; 2914 } else { 2915 broadcastScoConnectionState( 2916 AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 2917 } 2918 } else if (getBluetoothHeadset()) { 2919 mScoAudioState = SCO_STATE_ACTIVATE_REQ; 2920 } 2921 } else { 2922 mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; 2923 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED); 2924 } 2925 } else { 2926 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 2927 } 2928 } 2929 } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED && 2930 (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL || 2931 mScoAudioState == SCO_STATE_ACTIVATE_REQ)) { 2932 if (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL) { 2933 if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) { 2934 boolean status = false; 2935 if (mScoAudioMode == SCO_MODE_RAW) { 2936 status = mBluetoothHeadset.disconnectAudio(); 2937 } else if (mScoAudioMode == SCO_MODE_VIRTUAL_CALL) { 2938 status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall( 2939 mBluetoothHeadsetDevice); 2940 } else if (mScoAudioMode == SCO_MODE_VR) { 2941 status = mBluetoothHeadset.stopVoiceRecognition( 2942 mBluetoothHeadsetDevice); 2943 } 2944 2945 if (!status) { 2946 mScoAudioState = SCO_STATE_INACTIVE; 2947 broadcastScoConnectionState( 2948 AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 2949 } 2950 } else if (getBluetoothHeadset()) { 2951 mScoAudioState = SCO_STATE_DEACTIVATE_REQ; 2952 } 2953 } else { 2954 mScoAudioState = SCO_STATE_INACTIVE; 2955 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 2956 } 2957 } 2958 } 2959 } 2960 } 2961 2962 private void checkScoAudioState() { 2963 if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null && 2964 mScoAudioState == SCO_STATE_INACTIVE && 2965 mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice) 2966 != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { 2967 mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; 2968 } 2969 } 2970 2971 private ScoClient getScoClient(IBinder cb, boolean create) { 2972 synchronized(mScoClients) { 2973 ScoClient client = null; 2974 int size = mScoClients.size(); 2975 for (int i = 0; i < size; i++) { 2976 client = mScoClients.get(i); 2977 if (client.getBinder() == cb) 2978 return client; 2979 } 2980 if (create) { 2981 client = new ScoClient(cb); 2982 mScoClients.add(client); 2983 } 2984 return client; 2985 } 2986 } 2987 2988 public void clearAllScoClients(int exceptPid, boolean stopSco) { 2989 synchronized(mScoClients) { 2990 ScoClient savedClient = null; 2991 int size = mScoClients.size(); 2992 for (int i = 0; i < size; i++) { 2993 ScoClient cl = mScoClients.get(i); 2994 if (cl.getPid() != exceptPid) { 2995 cl.clearCount(stopSco); 2996 } else { 2997 savedClient = cl; 2998 } 2999 } 3000 mScoClients.clear(); 3001 if (savedClient != null) { 3002 mScoClients.add(savedClient); 3003 } 3004 } 3005 } 3006 3007 private boolean getBluetoothHeadset() { 3008 boolean result = false; 3009 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 3010 if (adapter != null) { 3011 result = adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, 3012 BluetoothProfile.HEADSET); 3013 } 3014 // If we could not get a bluetooth headset proxy, send a failure message 3015 // without delay to reset the SCO audio state and clear SCO clients. 3016 // If we could get a proxy, send a delayed failure message that will reset our state 3017 // in case we don't receive onServiceConnected(). 3018 sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED, 3019 SENDMSG_REPLACE, 0, 0, null, result ? BT_HEADSET_CNCT_TIMEOUT_MS : 0); 3020 return result; 3021 } 3022 3023 private void disconnectBluetoothSco(int exceptPid) { 3024 synchronized(mScoClients) { 3025 checkScoAudioState(); 3026 if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL || 3027 mScoAudioState == SCO_STATE_DEACTIVATE_EXT_REQ) { 3028 if (mBluetoothHeadsetDevice != null) { 3029 if (mBluetoothHeadset != null) { 3030 if (!mBluetoothHeadset.stopVoiceRecognition( 3031 mBluetoothHeadsetDevice)) { 3032 sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED, 3033 SENDMSG_REPLACE, 0, 0, null, 0); 3034 } 3035 } else if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL && 3036 getBluetoothHeadset()) { 3037 mScoAudioState = SCO_STATE_DEACTIVATE_EXT_REQ; 3038 } 3039 } 3040 } else { 3041 clearAllScoClients(exceptPid, true); 3042 } 3043 } 3044 } 3045 3046 private void resetBluetoothSco() { 3047 synchronized(mScoClients) { 3048 clearAllScoClients(0, false); 3049 mScoAudioState = SCO_STATE_INACTIVE; 3050 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED); 3051 } 3052 AudioSystem.setParameters("A2dpSuspended=false"); 3053 setBluetoothScoOnInt(false); 3054 } 3055 3056 private void broadcastScoConnectionState(int state) { 3057 sendMsg(mAudioHandler, MSG_BROADCAST_BT_CONNECTION_STATE, 3058 SENDMSG_QUEUE, state, 0, null, 0); 3059 } 3060 3061 private void onBroadcastScoConnectionState(int state) { 3062 if (state != mScoConnectionState) { 3063 Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); 3064 newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, state); 3065 newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, 3066 mScoConnectionState); 3067 sendStickyBroadcastToAll(newIntent); 3068 mScoConnectionState = state; 3069 } 3070 } 3071 3072 void setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state) { 3073 if (btDevice == null) { 3074 return; 3075 } 3076 3077 String address = btDevice.getAddress(); 3078 BluetoothClass btClass = btDevice.getBluetoothClass(); 3079 int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; 3080 int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET; 3081 if (btClass != null) { 3082 switch (btClass.getDeviceClass()) { 3083 case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: 3084 case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: 3085 outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 3086 break; 3087 case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: 3088 outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 3089 break; 3090 } 3091 } 3092 3093 if (!BluetoothAdapter.checkBluetoothAddress(address)) { 3094 address = ""; 3095 } 3096 3097 boolean connected = (state == BluetoothProfile.STATE_CONNECTED); 3098 3099 String btDeviceName = btDevice.getName(); 3100 boolean success = 3101 handleDeviceConnection(connected, outDevice, address, btDeviceName) && 3102 handleDeviceConnection(connected, inDevice, address, btDeviceName); 3103 if (success) { 3104 synchronized (mScoClients) { 3105 if (connected) { 3106 mBluetoothHeadsetDevice = btDevice; 3107 } else { 3108 mBluetoothHeadsetDevice = null; 3109 resetBluetoothSco(); 3110 } 3111 } 3112 } 3113 } 3114 3115 private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = 3116 new BluetoothProfile.ServiceListener() { 3117 public void onServiceConnected(int profile, BluetoothProfile proxy) { 3118 BluetoothDevice btDevice; 3119 List<BluetoothDevice> deviceList; 3120 switch(profile) { 3121 case BluetoothProfile.A2DP: 3122 synchronized (mConnectedDevices) { 3123 synchronized (mA2dpAvrcpLock) { 3124 mA2dp = (BluetoothA2dp) proxy; 3125 deviceList = mA2dp.getConnectedDevices(); 3126 if (deviceList.size() > 0) { 3127 btDevice = deviceList.get(0); 3128 int state = mA2dp.getConnectionState(btDevice); 3129 int delay = checkSendBecomingNoisyIntent( 3130 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 3131 (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0); 3132 queueMsgUnderWakeLock(mAudioHandler, 3133 MSG_SET_A2DP_SINK_CONNECTION_STATE, 3134 state, 3135 0, 3136 btDevice, 3137 delay); 3138 } 3139 } 3140 } 3141 break; 3142 3143 case BluetoothProfile.A2DP_SINK: 3144 deviceList = proxy.getConnectedDevices(); 3145 if (deviceList.size() > 0) { 3146 btDevice = deviceList.get(0); 3147 synchronized (mConnectedDevices) {