1 /* 2 * Copyright (C) 2007 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 android.media; 18 19 import android.Manifest; 20 import android.annotation.SdkConstant; 21 import android.annotation.SdkConstant.SdkConstantType; 22 import android.annotation.SystemApi; 23 import android.app.PendingIntent; 24 import android.bluetooth.BluetoothDevice; 25 import android.content.ComponentName; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.media.RemoteController.OnClientUpdateListener; 29 import android.media.audiopolicy.AudioPolicy; 30 import android.media.audiopolicy.AudioPolicyConfig; 31 import android.media.session.MediaController; 32 import android.media.session.MediaSession; 33 import android.media.session.MediaSessionLegacyHelper; 34 import android.media.session.MediaSessionManager; 35 import android.os.Binder; 36 import android.os.Handler; 37 import android.os.IBinder; 38 import android.os.Looper; 39 import android.os.Message; 40 import android.os.Process; 41 import android.os.RemoteException; 42 import android.os.SystemClock; 43 import android.os.ServiceManager; 44 import android.provider.Settings; 45 import android.util.Log; 46 import android.view.KeyEvent; 47 48 import java.util.HashMap; 49 import java.util.ArrayList; 50 51 52 /** 53 * AudioManager provides access to volume and ringer mode control. 54 * <p> 55 * Use <code>Context.getSystemService(Context.AUDIO_SERVICE)</code> to get 56 * an instance of this class. 57 */ 58 public class AudioManager { 59 60 private final Context mContext; 61 private long mVolumeKeyUpTime; 62 private final boolean mUseMasterVolume; 63 private final boolean mUseVolumeKeySounds; 64 private final boolean mUseFixedVolume; 65 private final Binder mToken = new Binder(); 66 private static String TAG = "AudioManager"; 67 AudioPortEventHandler mAudioPortEventHandler; 68 69 /** 70 * Broadcast intent, a hint for applications that audio is about to become 71 * 'noisy' due to a change in audio outputs. For example, this intent may 72 * be sent when a wired headset is unplugged, or when an A2DP audio 73 * sink is disconnected, and the audio system is about to automatically 74 * switch audio route to the speaker. Applications that are controlling 75 * audio streams may consider pausing, reducing volume or some other action 76 * on receipt of this intent so as not to surprise the user with audio 77 * from the speaker. 78 */ 79 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 80 public static final String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY"; 81 82 /** 83 * Sticky broadcast intent action indicating that the ringer mode has 84 * changed. Includes the new ringer mode. 85 * 86 * @see #EXTRA_RINGER_MODE 87 */ 88 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 89 public static final String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED"; 90 91 /** 92 * The new ringer mode. 93 * 94 * @see #RINGER_MODE_CHANGED_ACTION 95 * @see #RINGER_MODE_NORMAL 96 * @see #RINGER_MODE_SILENT 97 * @see #RINGER_MODE_VIBRATE 98 */ 99 public static final String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE"; 100 101 /** 102 * Broadcast intent action indicating that the vibrate setting has 103 * changed. Includes the vibrate type and its new setting. 104 * 105 * @see #EXTRA_VIBRATE_TYPE 106 * @see #EXTRA_VIBRATE_SETTING 107 * @deprecated Applications should maintain their own vibrate policy based on 108 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 109 */ 110 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 111 public static final String VIBRATE_SETTING_CHANGED_ACTION = 112 "android.media.VIBRATE_SETTING_CHANGED"; 113 114 /** 115 * @hide Broadcast intent when the volume for a particular stream type changes. 116 * Includes the stream, the new volume and previous volumes. 117 * Notes: 118 * - for internal platform use only, do not make public, 119 * - never used for "remote" volume changes 120 * 121 * @see #EXTRA_VOLUME_STREAM_TYPE 122 * @see #EXTRA_VOLUME_STREAM_VALUE 123 * @see #EXTRA_PREV_VOLUME_STREAM_VALUE 124 */ 125 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 126 public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION"; 127 128 /** 129 * @hide Broadcast intent when the master volume changes. 130 * Includes the new volume 131 * 132 * @see #EXTRA_MASTER_VOLUME_VALUE 133 * @see #EXTRA_PREV_MASTER_VOLUME_VALUE 134 */ 135 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 136 public static final String MASTER_VOLUME_CHANGED_ACTION = 137 "android.media.MASTER_VOLUME_CHANGED_ACTION"; 138 139 /** 140 * @hide Broadcast intent when the master mute state changes. 141 * Includes the the new volume 142 * 143 * @see #EXTRA_MASTER_VOLUME_MUTED 144 */ 145 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 146 public static final String MASTER_MUTE_CHANGED_ACTION = 147 "android.media.MASTER_MUTE_CHANGED_ACTION"; 148 149 /** 150 * The new vibrate setting for a particular type. 151 * 152 * @see #VIBRATE_SETTING_CHANGED_ACTION 153 * @see #EXTRA_VIBRATE_TYPE 154 * @see #VIBRATE_SETTING_ON 155 * @see #VIBRATE_SETTING_OFF 156 * @see #VIBRATE_SETTING_ONLY_SILENT 157 * @deprecated Applications should maintain their own vibrate policy based on 158 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 159 */ 160 public static final String EXTRA_VIBRATE_SETTING = "android.media.EXTRA_VIBRATE_SETTING"; 161 162 /** 163 * The vibrate type whose setting has changed. 164 * 165 * @see #VIBRATE_SETTING_CHANGED_ACTION 166 * @see #VIBRATE_TYPE_NOTIFICATION 167 * @see #VIBRATE_TYPE_RINGER 168 * @deprecated Applications should maintain their own vibrate policy based on 169 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 170 */ 171 public static final String EXTRA_VIBRATE_TYPE = "android.media.EXTRA_VIBRATE_TYPE"; 172 173 /** 174 * @hide The stream type for the volume changed intent. 175 */ 176 public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE"; 177 178 /** 179 * @hide The volume associated with the stream for the volume changed intent. 180 */ 181 public static final String EXTRA_VOLUME_STREAM_VALUE = 182 "android.media.EXTRA_VOLUME_STREAM_VALUE"; 183 184 /** 185 * @hide The previous volume associated with the stream for the volume changed intent. 186 */ 187 public static final String EXTRA_PREV_VOLUME_STREAM_VALUE = 188 "android.media.EXTRA_PREV_VOLUME_STREAM_VALUE"; 189 190 /** 191 * @hide The new master volume value for the master volume changed intent. 192 * Value is integer between 0 and 100 inclusive. 193 */ 194 public static final String EXTRA_MASTER_VOLUME_VALUE = 195 "android.media.EXTRA_MASTER_VOLUME_VALUE"; 196 197 /** 198 * @hide The previous master volume value for the master volume changed intent. 199 * Value is integer between 0 and 100 inclusive. 200 */ 201 public static final String EXTRA_PREV_MASTER_VOLUME_VALUE = 202 "android.media.EXTRA_PREV_MASTER_VOLUME_VALUE"; 203 204 /** 205 * @hide The new master volume mute state for the master mute changed intent. 206 * Value is boolean 207 */ 208 public static final String EXTRA_MASTER_VOLUME_MUTED = 209 "android.media.EXTRA_MASTER_VOLUME_MUTED"; 210 211 /** 212 * Broadcast Action: Wired Headset plugged in or unplugged. 213 * 214 * You <em>cannot</em> receive this through components declared 215 * in manifests, only by explicitly registering for it with 216 * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) 217 * Context.registerReceiver()}. 218 * 219 * <p>The intent will have the following extra values: 220 * <ul> 221 * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li> 222 * <li><em>name</em> - Headset type, human readable string </li> 223 * <li><em>microphone</em> - 1 if headset has a microphone, 0 otherwise </li> 224 * </ul> 225 * </ul> 226 */ 227 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 228 public static final String ACTION_HEADSET_PLUG = 229 "android.intent.action.HEADSET_PLUG"; 230 231 /** 232 * Broadcast Action: A sticky broadcast indicating an HMDI cable was plugged or unplugged 233 * 234 * The intent will have the following extra values: {@link #EXTRA_AUDIO_PLUG_STATE}, 235 * {@link #EXTRA_MAX_CHANNEL_COUNT}, {@link #EXTRA_ENCODINGS}. 236 * <p>It can only be received by explicitly registering for it with 237 * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)}. 238 */ 239 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 240 public static final String ACTION_HDMI_AUDIO_PLUG = 241 "android.media.action.HDMI_AUDIO_PLUG"; 242 243 /** 244 * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to communicate whether HDMI is plugged in 245 * or unplugged. 246 * An integer value of 1 indicates a plugged-in state, 0 is unplugged. 247 */ 248 public static final String EXTRA_AUDIO_PLUG_STATE = "android.media.extra.AUDIO_PLUG_STATE"; 249 250 /** 251 * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to define the maximum number of channels 252 * supported by the HDMI device. 253 * The corresponding integer value is only available when the device is plugged in (as expressed 254 * by {@link #EXTRA_AUDIO_PLUG_STATE}). 255 */ 256 public static final String EXTRA_MAX_CHANNEL_COUNT = "android.media.extra.MAX_CHANNEL_COUNT"; 257 258 /** 259 * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to define the audio encodings supported by 260 * the connected HDMI device. 261 * The corresponding array of encoding values is only available when the device is plugged in 262 * (as expressed by {@link #EXTRA_AUDIO_PLUG_STATE}). Encoding values are defined in 263 * {@link AudioFormat} (for instance see {@link AudioFormat#ENCODING_PCM_16BIT}). Use 264 * {@link android.content.Intent#getIntArrayExtra(String)} to retrieve the encoding values. 265 */ 266 public static final String EXTRA_ENCODINGS = "android.media.extra.ENCODINGS"; 267 268 /** 269 * Broadcast Action: An analog audio speaker/headset plugged in or unplugged. 270 * 271 * <p>The intent will have the following extra values: 272 * <ul> 273 * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li> 274 * <li><em>name</em> - Headset type, human readable string </li> 275 * </ul> 276 * </ul> 277 * @hide 278 */ 279 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 280 public static final String ACTION_ANALOG_AUDIO_DOCK_PLUG = 281 "android.media.action.ANALOG_AUDIO_DOCK_PLUG"; 282 283 /** 284 * Broadcast Action: A digital audio speaker/headset plugged in or unplugged. 285 * 286 * <p>The intent will have the following extra values: 287 * <ul> 288 * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li> 289 * <li><em>name</em> - Headset type, human readable string </li> 290 * </ul> 291 * </ul> 292 * @hide 293 */ 294 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 295 public static final String ACTION_DIGITAL_AUDIO_DOCK_PLUG = 296 "android.media.action.DIGITAL_AUDIO_DOCK_PLUG"; 297 298 /** 299 * Broadcast Action: A USB audio accessory was plugged in or unplugged. 300 * 301 * <p>The intent will have the following extra values: 302 * <ul> 303 * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li> 304 * <li><em>card</em> - ALSA card number (integer) </li> 305 * <li><em>device</em> - ALSA device number (integer) </li> 306 * </ul> 307 * </ul> 308 * @hide 309 */ 310 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 311 public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG = 312 "android.media.action.USB_AUDIO_ACCESSORY_PLUG"; 313 314 /** 315 * Broadcast Action: A USB audio device was plugged in or unplugged. 316 * 317 * <p>The intent will have the following extra values: 318 * <ul> 319 * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li> 320 * <li><em>card</em> - ALSA card number (integer) </li> 321 * <li><em>device</em> - ALSA device number (integer) </li> 322 * </ul> 323 * </ul> 324 * @hide 325 */ 326 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 327 public static final String ACTION_USB_AUDIO_DEVICE_PLUG = 328 "android.media.action.USB_AUDIO_DEVICE_PLUG"; 329 330 /** The audio stream for phone calls */ 331 public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL; 332 /** The audio stream for system sounds */ 333 public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM; 334 /** The audio stream for the phone ring */ 335 public static final int STREAM_RING = AudioSystem.STREAM_RING; 336 /** The audio stream for music playback */ 337 public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC; 338 /** The audio stream for alarms */ 339 public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM; 340 /** The audio stream for notifications */ 341 public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION; 342 /** @hide The audio stream for phone calls when connected to bluetooth */ 343 public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO; 344 /** @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */ 345 public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED; 346 /** The audio stream for DTMF Tones */ 347 public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF; 348 /** @hide The audio stream for text to speech (TTS) */ 349 public static final int STREAM_TTS = AudioSystem.STREAM_TTS; 350 /** Number of audio streams */ 351 /** 352 * @deprecated Use AudioSystem.getNumStreamTypes() instead 353 */ 354 @Deprecated public static final int NUM_STREAMS = AudioSystem.NUM_STREAMS; 355 356 357 /** @hide Default volume index values for audio streams */ 358 public static final int[] DEFAULT_STREAM_VOLUME = new int[] { 359 4, // STREAM_VOICE_CALL 360 7, // STREAM_SYSTEM 361 5, // STREAM_RING 362 11, // STREAM_MUSIC 363 6, // STREAM_ALARM 364 5, // STREAM_NOTIFICATION 365 7, // STREAM_BLUETOOTH_SCO 366 7, // STREAM_SYSTEM_ENFORCED 367 11, // STREAM_DTMF 368 11 // STREAM_TTS 369 }; 370 371 /** 372 * Increase the ringer volume. 373 * 374 * @see #adjustVolume(int, int) 375 * @see #adjustStreamVolume(int, int, int) 376 */ 377 public static final int ADJUST_RAISE = 1; 378 379 /** 380 * Decrease the ringer volume. 381 * 382 * @see #adjustVolume(int, int) 383 * @see #adjustStreamVolume(int, int, int) 384 */ 385 public static final int ADJUST_LOWER = -1; 386 387 /** 388 * Maintain the previous ringer volume. This may be useful when needing to 389 * show the volume toast without actually modifying the volume. 390 * 391 * @see #adjustVolume(int, int) 392 * @see #adjustStreamVolume(int, int, int) 393 */ 394 public static final int ADJUST_SAME = 0; 395 396 // Flags should be powers of 2! 397 398 /** 399 * Show a toast containing the current volume. 400 * 401 * @see #adjustStreamVolume(int, int, int) 402 * @see #adjustVolume(int, int) 403 * @see #setStreamVolume(int, int, int) 404 * @see #setRingerMode(int) 405 */ 406 public static final int FLAG_SHOW_UI = 1 << 0; 407 408 /** 409 * Whether to include ringer modes as possible options when changing volume. 410 * For example, if true and volume level is 0 and the volume is adjusted 411 * with {@link #ADJUST_LOWER}, then the ringer mode may switch the silent or 412 * vibrate mode. 413 * <p> 414 * By default this is on for the ring stream. If this flag is included, 415 * this behavior will be present regardless of the stream type being 416 * affected by the ringer mode. 417 * 418 * @see #adjustVolume(int, int) 419 * @see #adjustStreamVolume(int, int, int) 420 */ 421 public static final int FLAG_ALLOW_RINGER_MODES = 1 << 1; 422 423 /** 424 * Whether to play a sound when changing the volume. 425 * <p> 426 * If this is given to {@link #adjustVolume(int, int)} or 427 * {@link #adjustSuggestedStreamVolume(int, int, int)}, it may be ignored 428 * in some cases (for example, the decided stream type is not 429 * {@link AudioManager#STREAM_RING}, or the volume is being adjusted 430 * downward). 431 * 432 * @see #adjustStreamVolume(int, int, int) 433 * @see #adjustVolume(int, int) 434 * @see #setStreamVolume(int, int, int) 435 */ 436 public static final int FLAG_PLAY_SOUND = 1 << 2; 437 438 /** 439 * Removes any sounds/vibrate that may be in the queue, or are playing (related to 440 * changing volume). 441 */ 442 public static final int FLAG_REMOVE_SOUND_AND_VIBRATE = 1 << 3; 443 444 /** 445 * Whether to vibrate if going into the vibrate ringer mode. 446 */ 447 public static final int FLAG_VIBRATE = 1 << 4; 448 449 /** 450 * Indicates to VolumePanel that the volume slider should be disabled as user 451 * cannot change the stream volume 452 * @hide 453 */ 454 public static final int FLAG_FIXED_VOLUME = 1 << 5; 455 456 /** 457 * Indicates the volume set/adjust call is for Bluetooth absolute volume 458 * @hide 459 */ 460 public static final int FLAG_BLUETOOTH_ABS_VOLUME = 1 << 6; 461 462 /** 463 * Adjusting the volume was prevented due to silent mode, display a hint in the UI. 464 * @hide 465 */ 466 public static final int FLAG_SHOW_SILENT_HINT = 1 << 7; 467 468 /** 469 * Indicates the volume call is for Hdmi Cec system audio volume 470 * @hide 471 */ 472 public static final int FLAG_HDMI_SYSTEM_AUDIO_VOLUME = 1 << 8; 473 474 /** 475 * Indicates that this should only be handled if media is actively playing. 476 * @hide 477 */ 478 public static final int FLAG_ACTIVE_MEDIA_ONLY = 1 << 9; 479 480 /** 481 * Like FLAG_SHOW_UI, but only dialog warnings and confirmations, no sliders. 482 * @hide 483 */ 484 public static final int FLAG_SHOW_UI_WARNINGS = 1 << 10; 485 486 /** 487 * Ringer mode that will be silent and will not vibrate. (This overrides the 488 * vibrate setting.) 489 * 490 * @see #setRingerMode(int) 491 * @see #getRingerMode() 492 */ 493 public static final int RINGER_MODE_SILENT = 0; 494 495 /** 496 * Ringer mode that will be silent and will vibrate. (This will cause the 497 * phone ringer to always vibrate, but the notification vibrate to only 498 * vibrate if set.) 499 * 500 * @see #setRingerMode(int) 501 * @see #getRingerMode() 502 */ 503 public static final int RINGER_MODE_VIBRATE = 1; 504 505 /** 506 * Ringer mode that may be audible and may vibrate. It will be audible if 507 * the volume before changing out of this mode was audible. It will vibrate 508 * if the vibrate setting is on. 509 * 510 * @see #setRingerMode(int) 511 * @see #getRingerMode() 512 */ 513 public static final int RINGER_MODE_NORMAL = 2; 514 515 // maximum valid ringer mode value. Values must start from 0 and be contiguous. 516 private static final int RINGER_MODE_MAX = RINGER_MODE_NORMAL; 517 518 /** 519 * Vibrate type that corresponds to the ringer. 520 * 521 * @see #setVibrateSetting(int, int) 522 * @see #getVibrateSetting(int) 523 * @see #shouldVibrate(int) 524 * @deprecated Applications should maintain their own vibrate policy based on 525 * current ringer mode that can be queried via {@link #getRingerMode()}. 526 */ 527 public static final int VIBRATE_TYPE_RINGER = 0; 528 529 /** 530 * Vibrate type that corresponds to notifications. 531 * 532 * @see #setVibrateSetting(int, int) 533 * @see #getVibrateSetting(int) 534 * @see #shouldVibrate(int) 535 * @deprecated Applications should maintain their own vibrate policy based on 536 * current ringer mode that can be queried via {@link #getRingerMode()}. 537 */ 538 public static final int VIBRATE_TYPE_NOTIFICATION = 1; 539 540 /** 541 * Vibrate setting that suggests to never vibrate. 542 * 543 * @see #setVibrateSetting(int, int) 544 * @see #getVibrateSetting(int) 545 * @deprecated Applications should maintain their own vibrate policy based on 546 * current ringer mode that can be queried via {@link #getRingerMode()}. 547 */ 548 public static final int VIBRATE_SETTING_OFF = 0; 549 550 /** 551 * Vibrate setting that suggests to vibrate when possible. 552 * 553 * @see #setVibrateSetting(int, int) 554 * @see #getVibrateSetting(int) 555 * @deprecated Applications should maintain their own vibrate policy based on 556 * current ringer mode that can be queried via {@link #getRingerMode()}. 557 */ 558 public static final int VIBRATE_SETTING_ON = 1; 559 560 /** 561 * Vibrate setting that suggests to only vibrate when in the vibrate ringer 562 * mode. 563 * 564 * @see #setVibrateSetting(int, int) 565 * @see #getVibrateSetting(int) 566 * @deprecated Applications should maintain their own vibrate policy based on 567 * current ringer mode that can be queried via {@link #getRingerMode()}. 568 */ 569 public static final int VIBRATE_SETTING_ONLY_SILENT = 2; 570 571 /** 572 * Suggests using the default stream type. This may not be used in all 573 * places a stream type is needed. 574 */ 575 public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE; 576 577 private static IAudioService sService; 578 579 /** 580 * @hide 581 */ 582 public AudioManager(Context context) { 583 mContext = context; 584 mUseMasterVolume = mContext.getResources().getBoolean( 585 com.android.internal.R.bool.config_useMasterVolume); 586 mUseVolumeKeySounds = mContext.getResources().getBoolean( 587 com.android.internal.R.bool.config_useVolumeKeySounds); 588 mAudioPortEventHandler = new AudioPortEventHandler(this); 589 mUseFixedVolume = mContext.getResources().getBoolean( 590 com.android.internal.R.bool.config_useFixedVolume); 591 } 592 593 private static IAudioService getService() 594 { 595 if (sService != null) { 596 return sService; 597 } 598 IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); 599 sService = IAudioService.Stub.asInterface(b); 600 return sService; 601 } 602 603 /** 604 * Sends a simulated key event for a media button. 605 * To simulate a key press, you must first send a KeyEvent built with a 606 * {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP} 607 * action. 608 * <p>The key event will be sent to the current media key event consumer which registered with 609 * {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}. 610 * @param keyEvent a {@link KeyEvent} instance whose key code is one of 611 * {@link KeyEvent#KEYCODE_MUTE}, 612 * {@link KeyEvent#KEYCODE_HEADSETHOOK}, 613 * {@link KeyEvent#KEYCODE_MEDIA_PLAY}, 614 * {@link KeyEvent#KEYCODE_MEDIA_PAUSE}, 615 * {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE}, 616 * {@link KeyEvent#KEYCODE_MEDIA_STOP}, 617 * {@link KeyEvent#KEYCODE_MEDIA_NEXT}, 618 * {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}, 619 * {@link KeyEvent#KEYCODE_MEDIA_REWIND}, 620 * {@link KeyEvent#KEYCODE_MEDIA_RECORD}, 621 * {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD}, 622 * {@link KeyEvent#KEYCODE_MEDIA_CLOSE}, 623 * {@link KeyEvent#KEYCODE_MEDIA_EJECT}, 624 * or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}. 625 */ 626 public void dispatchMediaKeyEvent(KeyEvent keyEvent) { 627 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 628 helper.sendMediaButtonEvent(keyEvent, false); 629 } 630 631 /** 632 * @hide 633 */ 634 public void preDispatchKeyEvent(KeyEvent event, int stream) { 635 /* 636 * If the user hits another key within the play sound delay, then 637 * cancel the sound 638 */ 639 int keyCode = event.getKeyCode(); 640 if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP 641 && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE 642 && mVolumeKeyUpTime + AudioService.PLAY_SOUND_DELAY 643 > SystemClock.uptimeMillis()) { 644 /* 645 * The user has hit another key during the delay (e.g., 300ms) 646 * since the last volume key up, so cancel any sounds. 647 */ 648 if (mUseMasterVolume) { 649 adjustMasterVolume(ADJUST_SAME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 650 } else { 651 adjustSuggestedStreamVolume(ADJUST_SAME, 652 stream, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 653 } 654 } 655 } 656 657 /** 658 * @hide 659 */ 660 public void handleKeyDown(KeyEvent event, int stream) { 661 int keyCode = event.getKeyCode(); 662 switch (keyCode) { 663 case KeyEvent.KEYCODE_VOLUME_UP: 664 case KeyEvent.KEYCODE_VOLUME_DOWN: 665 /* 666 * Adjust the volume in on key down since it is more 667 * responsive to the user. 668 */ 669 int flags = FLAG_SHOW_UI | FLAG_VIBRATE; 670 671 if (mUseMasterVolume) { 672 adjustMasterVolume( 673 keyCode == KeyEvent.KEYCODE_VOLUME_UP 674 ? ADJUST_RAISE 675 : ADJUST_LOWER, 676 flags); 677 } else { 678 adjustSuggestedStreamVolume( 679 keyCode == KeyEvent.KEYCODE_VOLUME_UP 680 ? ADJUST_RAISE 681 : ADJUST_LOWER, 682 stream, 683 flags); 684 } 685 break; 686 case KeyEvent.KEYCODE_VOLUME_MUTE: 687 if (event.getRepeatCount() == 0) { 688 if (mUseMasterVolume) { 689 setMasterMute(!isMasterMute()); 690 } else { 691 // TODO: Actually handle MUTE. 692 } 693 } 694 break; 695 } 696 } 697 698 /** 699 * @hide 700 */ 701 public void handleKeyUp(KeyEvent event, int stream) { 702 int keyCode = event.getKeyCode(); 703 switch (keyCode) { 704 case KeyEvent.KEYCODE_VOLUME_UP: 705 case KeyEvent.KEYCODE_VOLUME_DOWN: 706 /* 707 * Play a sound. This is done on key up since we don't want the 708 * sound to play when a user holds down volume down to mute. 709 */ 710 if (mUseVolumeKeySounds) { 711 if (mUseMasterVolume) { 712 adjustMasterVolume(ADJUST_SAME, FLAG_PLAY_SOUND); 713 } else { 714 int flags = FLAG_PLAY_SOUND; 715 adjustSuggestedStreamVolume( 716 ADJUST_SAME, 717 stream, 718 flags); 719 } 720 } 721 mVolumeKeyUpTime = SystemClock.uptimeMillis(); 722 break; 723 } 724 } 725 726 /** 727 * Indicates if the device implements a fixed volume policy. 728 * <p>Some devices may not have volume control and may operate at a fixed volume, 729 * and may not enable muting or changing the volume of audio streams. 730 * This method will return true on such devices. 731 * <p>The following APIs have no effect when volume is fixed: 732 * <ul> 733 * <li> {@link #adjustVolume(int, int)} 734 * <li> {@link #adjustSuggestedStreamVolume(int, int, int)} 735 * <li> {@link #adjustStreamVolume(int, int, int)} 736 * <li> {@link #setStreamVolume(int, int, int)} 737 * <li> {@link #setRingerMode(int)} 738 * <li> {@link #setStreamSolo(int, boolean)} 739 * <li> {@link #setStreamMute(int, boolean)} 740 * </ul> 741 */ 742 public boolean isVolumeFixed() { 743 return mUseFixedVolume; 744 } 745 746 /** 747 * Adjusts the volume of a particular stream by one step in a direction. 748 * <p> 749 * This method should only be used by applications that replace the platform-wide 750 * management of audio settings or the main telephony application. 751 * 752 * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL}, 753 * {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC} or 754 * {@link #STREAM_ALARM} 755 * @param direction The direction to adjust the volume. One of 756 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 757 * {@link #ADJUST_SAME}. 758 * @param flags One or more flags. 759 * @see #adjustVolume(int, int) 760 * @see #setStreamVolume(int, int, int) 761 */ 762 public void adjustStreamVolume(int streamType, int direction, int flags) { 763 IAudioService service = getService(); 764 try { 765 if (mUseMasterVolume) { 766 service.adjustMasterVolume(direction, flags, mContext.getOpPackageName()); 767 } else { 768 service.adjustStreamVolume(streamType, direction, flags, 769 mContext.getOpPackageName()); 770 } 771 } catch (RemoteException e) { 772 Log.e(TAG, "Dead object in adjustStreamVolume", e); 773 } 774 } 775 776 /** 777 * Adjusts the volume of the most relevant stream. For example, if a call is 778 * active, it will have the highest priority regardless of if the in-call 779 * screen is showing. Another example, if music is playing in the background 780 * and a call is not active, the music stream will be adjusted. 781 * <p> 782 * This method should only be used by applications that replace the platform-wide 783 * management of audio settings or the main telephony application. 784 * <p>This method has no effect if the device implements a fixed volume policy 785 * as indicated by {@link #isVolumeFixed()}. 786 * @param direction The direction to adjust the volume. One of 787 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 788 * {@link #ADJUST_SAME}. 789 * @param flags One or more flags. 790 * @see #adjustSuggestedStreamVolume(int, int, int) 791 * @see #adjustStreamVolume(int, int, int) 792 * @see #setStreamVolume(int, int, int) 793 * @see #isVolumeFixed() 794 */ 795 public void adjustVolume(int direction, int flags) { 796 IAudioService service = getService(); 797 try { 798 if (mUseMasterVolume) { 799 service.adjustMasterVolume(direction, flags, mContext.getOpPackageName()); 800 } else { 801 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 802 helper.sendAdjustVolumeBy(USE_DEFAULT_STREAM_TYPE, direction, flags); 803 } 804 } catch (RemoteException e) { 805 Log.e(TAG, "Dead object in adjustVolume", e); 806 } 807 } 808 809 /** 810 * Adjusts the volume of the most relevant stream, or the given fallback 811 * stream. 812 * <p> 813 * This method should only be used by applications that replace the platform-wide 814 * management of audio settings or the main telephony application. 815 * 816 * <p>This method has no effect if the device implements a fixed volume policy 817 * as indicated by {@link #isVolumeFixed()}. 818 * @param direction The direction to adjust the volume. One of 819 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 820 * {@link #ADJUST_SAME}. 821 * @param suggestedStreamType The stream type that will be used if there 822 * isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is valid here. 823 * @param flags One or more flags. 824 * @see #adjustVolume(int, int) 825 * @see #adjustStreamVolume(int, int, int) 826 * @see #setStreamVolume(int, int, int) 827 * @see #isVolumeFixed() 828 */ 829 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) { 830 IAudioService service = getService(); 831 try { 832 if (mUseMasterVolume) { 833 service.adjustMasterVolume(direction, flags, mContext.getOpPackageName()); 834 } else { 835 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 836 helper.sendAdjustVolumeBy(suggestedStreamType, direction, flags); 837 } 838 } catch (RemoteException e) { 839 Log.e(TAG, "Dead object in adjustSuggestedStreamVolume", e); 840 } 841 } 842 843 /** 844 * Adjusts the master volume for the device's audio amplifier. 845 * <p> 846 * 847 * @param steps The number of volume steps to adjust. A positive 848 * value will raise the volume. 849 * @param flags One or more flags. 850 * @hide 851 */ 852 public void adjustMasterVolume(int steps, int flags) { 853 IAudioService service = getService(); 854 try { 855 service.adjustMasterVolume(steps, flags, mContext.getOpPackageName()); 856 } catch (RemoteException e) { 857 Log.e(TAG, "Dead object in adjustMasterVolume", e); 858 } 859 } 860 861 /** 862 * Returns the current ringtone mode. 863 * 864 * @return The current ringtone mode, one of {@link #RINGER_MODE_NORMAL}, 865 * {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}. 866 * @see #setRingerMode(int) 867 */ 868 public int getRingerMode() { 869 IAudioService service = getService(); 870 try { 871 return service.getRingerMode(); 872 } catch (RemoteException e) { 873 Log.e(TAG, "Dead object in getRingerMode", e); 874 return RINGER_MODE_NORMAL; 875 } 876 } 877 878 /** 879 * Checks valid ringer mode values. 880 * 881 * @return true if the ringer mode indicated is valid, false otherwise. 882 * 883 * @see #setRingerMode(int) 884 * @hide 885 */ 886 public static boolean isValidRingerMode(int ringerMode) { 887 if (ringerMode < 0 || ringerMode > RINGER_MODE_MAX) { 888 return false; 889 } 890 return true; 891 } 892 893 /** 894 * Returns the maximum volume index for a particular stream. 895 * 896 * @param streamType The stream type whose maximum volume index is returned. 897 * @return The maximum valid volume index for the stream. 898 * @see #getStreamVolume(int) 899 */ 900 public int getStreamMaxVolume(int streamType) { 901 IAudioService service = getService(); 902 try { 903 if (mUseMasterVolume) { 904 return service.getMasterMaxVolume(); 905 } else { 906 return service.getStreamMaxVolume(streamType); 907 } 908 } catch (RemoteException e) { 909 Log.e(TAG, "Dead object in getStreamMaxVolume", e); 910 return 0; 911 } 912 } 913 914 /** 915 * Returns the current volume index for a particular stream. 916 * 917 * @param streamType The stream type whose volume index is returned. 918 * @return The current volume index for the stream. 919 * @see #getStreamMaxVolume(int) 920 * @see #setStreamVolume(int, int, int) 921 */ 922 public int getStreamVolume(int streamType) { 923 IAudioService service = getService(); 924 try { 925 if (mUseMasterVolume) { 926 return service.getMasterVolume(); 927 } else { 928 return service.getStreamVolume(streamType); 929 } 930 } catch (RemoteException e) { 931 Log.e(TAG, "Dead object in getStreamVolume", e); 932 return 0; 933 } 934 } 935 936 /** 937 * Get last audible volume before stream was muted. 938 * 939 * @hide 940 */ 941 public int getLastAudibleStreamVolume(int streamType) { 942 IAudioService service = getService(); 943 try { 944 if (mUseMasterVolume) { 945 return service.getLastAudibleMasterVolume(); 946 } else { 947 return service.getLastAudibleStreamVolume(streamType); 948 } 949 } catch (RemoteException e) { 950 Log.e(TAG, "Dead object in getLastAudibleStreamVolume", e); 951 return 0; 952 } 953 } 954 955 /** 956 * Get the stream type whose volume is driving the UI sounds volume. 957 * UI sounds are screen lock/unlock, camera shutter, key clicks... 958 * It is assumed that this stream type is also tied to ringer mode changes. 959 * @hide 960 */ 961 public int getMasterStreamType() { 962 IAudioService service = getService(); 963 try { 964 return service.getMasterStreamType(); 965 } catch (RemoteException e) { 966 Log.e(TAG, "Dead object in getMasterStreamType", e); 967 return STREAM_RING; 968 } 969 } 970 971 /** 972 * Sets the ringer mode. 973 * <p> 974 * Silent mode will mute the volume and will not vibrate. Vibrate mode will 975 * mute the volume and vibrate. Normal mode will be audible and may vibrate 976 * according to user settings. 977 * <p>This method has no effect if the device implements a fixed volume policy 978 * as indicated by {@link #isVolumeFixed()}. 979 * @param ringerMode The ringer mode, one of {@link #RINGER_MODE_NORMAL}, 980 * {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}. 981 * @see #getRingerMode() 982 * @see #isVolumeFixed() 983 */ 984 public void setRingerMode(int ringerMode) { 985 setRingerMode(ringerMode, true /*checkZen*/); 986 } 987 988 /** 989 * @see #setRingerMode(int) 990 * @param checkZen Update zen mode if necessary to compensate. 991 * @hide 992 */ 993 public void setRingerMode(int ringerMode, boolean checkZen) { 994 if (!isValidRingerMode(ringerMode)) { 995 return; 996 } 997 IAudioService service = getService(); 998 try { 999 service.setRingerMode(ringerMode, checkZen); 1000 } catch (RemoteException e) { 1001 Log.e(TAG, "Dead object in setRingerMode", e); 1002 } 1003 } 1004 1005 /** 1006 * Sets the volume index for a particular stream. 1007 * <p>This method has no effect if the device implements a fixed volume policy 1008 * as indicated by {@link #isVolumeFixed()}. 1009 * @param streamType The stream whose volume index should be set. 1010 * @param index The volume index to set. See 1011 * {@link #getStreamMaxVolume(int)} for the largest valid value. 1012 * @param flags One or more flags. 1013 * @see #getStreamMaxVolume(int) 1014 * @see #getStreamVolume(int) 1015 * @see #isVolumeFixed() 1016 */ 1017 public void setStreamVolume(int streamType, int index, int flags) { 1018 IAudioService service = getService(); 1019 try { 1020 if (mUseMasterVolume) { 1021 service.setMasterVolume(index, flags, mContext.getOpPackageName()); 1022 } else { 1023 service.setStreamVolume(streamType, index, flags, mContext.getOpPackageName()); 1024 } 1025 } catch (RemoteException e) { 1026 Log.e(TAG, "Dead object in setStreamVolume", e); 1027 } 1028 } 1029 1030 /** 1031 * Returns the maximum volume index for master volume. 1032 * 1033 * @hide 1034 */ 1035 public int getMasterMaxVolume() { 1036 IAudioService service = getService(); 1037 try { 1038 return service.getMasterMaxVolume(); 1039 } catch (RemoteException e) { 1040 Log.e(TAG, "Dead object in getMasterMaxVolume", e); 1041 return 0; 1042 } 1043 } 1044 1045 /** 1046 * Returns the current volume index for master volume. 1047 * 1048 * @return The current volume index for master volume. 1049 * @hide 1050 */ 1051 public int getMasterVolume() { 1052 IAudioService service = getService(); 1053 try { 1054 return service.getMasterVolume(); 1055 } catch (RemoteException e) { 1056 Log.e(TAG, "Dead object in getMasterVolume", e); 1057 return 0; 1058 } 1059 } 1060 1061 /** 1062 * Get last audible volume before master volume was muted. 1063 * 1064 * @hide 1065 */ 1066 public int getLastAudibleMasterVolume() { 1067 IAudioService service = getService(); 1068 try { 1069 return service.getLastAudibleMasterVolume(); 1070 } catch (RemoteException e) { 1071 Log.e(TAG, "Dead object in getLastAudibleMasterVolume", e); 1072 return 0; 1073 } 1074 } 1075 1076 /** 1077 * Sets the volume index for master volume. 1078 * 1079 * @param index The volume index to set. See 1080 * {@link #getMasterMaxVolume()} for the largest valid value. 1081 * @param flags One or more flags. 1082 * @see #getMasterMaxVolume() 1083 * @see #getMasterVolume() 1084 * @hide 1085 */ 1086 public void setMasterVolume(int index, int flags) { 1087 IAudioService service = getService(); 1088 try { 1089 service.setMasterVolume(index, flags, mContext.getOpPackageName()); 1090 } catch (RemoteException e) { 1091 Log.e(TAG, "Dead object in setMasterVolume", e); 1092 } 1093 } 1094 1095 /** 1096 * Solo or unsolo a particular stream. All other streams are muted. 1097 * <p> 1098 * The solo command is protected against client process death: if a process 1099 * with an active solo request on a stream dies, all streams that were muted 1100 * because of this request will be unmuted automatically. 1101 * <p> 1102 * The solo requests for a given stream are cumulative: the AudioManager 1103 * can receive several solo requests from one or more clients and the stream 1104 * will be unsoloed only when the same number of unsolo requests are received. 1105 * <p> 1106 * For a better user experience, applications MUST unsolo a soloed stream 1107 * in onPause() and solo is again in onResume() if appropriate. 1108 * <p>This method has no effect if the device implements a fixed volume policy 1109 * as indicated by {@link #isVolumeFixed()}. 1110 * 1111 * @param streamType The stream to be soloed/unsoloed. 1112 * @param state The required solo state: true for solo ON, false for solo OFF 1113 * 1114 * @see #isVolumeFixed() 1115 */ 1116 public void setStreamSolo(int streamType, boolean state) { 1117 IAudioService service = getService(); 1118 try { 1119 service.setStreamSolo(streamType, state, mICallBack); 1120 } catch (RemoteException e) { 1121 Log.e(TAG, "Dead object in setStreamSolo", e); 1122 } 1123 } 1124 1125 /** 1126 * Mute or unmute an audio stream. 1127 * <p> 1128 * The mute command is protected against client process death: if a process 1129 * with an active mute request on a stream dies, this stream will be unmuted 1130 * automatically. 1131 * <p> 1132 * The mute requests for a given stream are cumulative: the AudioManager 1133 * can receive several mute requests from one or more clients and the stream 1134 * will be unmuted only when the same number of unmute requests are received. 1135 * <p> 1136 * For a better user experience, applications MUST unmute a muted stream 1137 * in onPause() and mute is again in onResume() if appropriate. 1138 * <p> 1139 * This method should only be used by applications that replace the platform-wide 1140 * management of audio settings or the main telephony application. 1141 * <p>This method has no effect if the device implements a fixed volume policy 1142 * as indicated by {@link #isVolumeFixed()}. 1143 * 1144 * @param streamType The stream to be muted/unmuted. 1145 * @param state The required mute state: true for mute ON, false for mute OFF 1146 * 1147 * @see #isVolumeFixed() 1148 */ 1149 public void setStreamMute(int streamType, boolean state) { 1150 IAudioService service = getService(); 1151 try { 1152 service.setStreamMute(streamType, state, mICallBack); 1153 } catch (RemoteException e) { 1154 Log.e(TAG, "Dead object in setStreamMute", e); 1155 } 1156 } 1157 1158 /** 1159 * get stream mute state. 1160 * 1161 * @hide 1162 */ 1163 public boolean isStreamMute(int streamType) { 1164 IAudioService service = getService(); 1165 try { 1166 return service.isStreamMute(streamType); 1167 } catch (RemoteException e) { 1168 Log.e(TAG, "Dead object in isStreamMute", e); 1169 return false; 1170 } 1171 } 1172 1173 /** 1174 * set master mute state. 1175 * 1176 * @hide 1177 */ 1178 public void setMasterMute(boolean state) { 1179 setMasterMute(state, FLAG_SHOW_UI); 1180 } 1181 1182 /** 1183 * set master mute state with optional flags. 1184 * 1185 * @hide 1186 */ 1187 public void setMasterMute(boolean state, int flags) { 1188 IAudioService service = getService(); 1189 try { 1190 service.setMasterMute(state, flags, mContext.getOpPackageName(), mICallBack); 1191 } catch (RemoteException e) { 1192 Log.e(TAG, "Dead object in setMasterMute", e); 1193 } 1194 } 1195 1196 /** 1197 * get master mute state. 1198 * 1199 * @hide 1200 */ 1201 public boolean isMasterMute() { 1202 IAudioService service = getService(); 1203 try { 1204 return service.isMasterMute(); 1205 } catch (RemoteException e) { 1206 Log.e(TAG, "Dead object in isMasterMute", e); 1207 return false; 1208 } 1209 } 1210 1211 /** 1212 * forces the stream controlled by hard volume keys 1213 * specifying streamType == -1 releases control to the 1214 * logic. 1215 * 1216 * @hide 1217 */ 1218 public void forceVolumeControlStream(int streamType) { 1219 IAudioService service = getService(); 1220 try { 1221 service.forceVolumeControlStream(streamType, mICallBack); 1222 } catch (RemoteException e) { 1223 Log.e(TAG, "Dead object in forceVolumeControlStream", e); 1224 } 1225 } 1226 1227 /** 1228 * Returns whether a particular type should vibrate according to user 1229 * settings and the current ringer mode. 1230 * <p> 1231 * This shouldn't be needed by most clients that use notifications to 1232 * vibrate. The notification manager will not vibrate if the policy doesn't 1233 * allow it, so the client should always set a vibrate pattern and let the 1234 * notification manager control whether or not to actually vibrate. 1235 * 1236 * @param vibrateType The type of vibrate. One of 1237 * {@link #VIBRATE_TYPE_NOTIFICATION} or 1238 * {@link #VIBRATE_TYPE_RINGER}. 1239 * @return Whether the type should vibrate at the instant this method is 1240 * called. 1241 * @see #setVibrateSetting(int, int) 1242 * @see #getVibrateSetting(int) 1243 * @deprecated Applications should maintain their own vibrate policy based on 1244 * current ringer mode that can be queried via {@link #getRingerMode()}. 1245 */ 1246 public boolean shouldVibrate(int vibrateType) { 1247 IAudioService service = getService(); 1248 try { 1249 return service.shouldVibrate(vibrateType); 1250 } catch (RemoteException e) { 1251 Log.e(TAG, "Dead object in shouldVibrate", e); 1252 return false; 1253 } 1254 } 1255 1256 /** 1257 * Returns whether the user's vibrate setting for a vibrate type. 1258 * <p> 1259 * This shouldn't be needed by most clients that want to vibrate, instead 1260 * see {@link #shouldVibrate(int)}. 1261 * 1262 * @param vibrateType The type of vibrate. One of 1263 * {@link #VIBRATE_TYPE_NOTIFICATION} or 1264 * {@link #VIBRATE_TYPE_RINGER}. 1265 * @return The vibrate setting, one of {@link #VIBRATE_SETTING_ON}, 1266 * {@link #VIBRATE_SETTING_OFF}, or 1267 * {@link #VIBRATE_SETTING_ONLY_SILENT}. 1268 * @see #setVibrateSetting(int, int) 1269 * @see #shouldVibrate(int) 1270 * @deprecated Applications should maintain their own vibrate policy based on 1271 * current ringer mode that can be queried via {@link #getRingerMode()}. 1272 */ 1273 public int getVibrateSetting(int vibrateType) { 1274 IAudioService service = getService(); 1275 try { 1276 return service.getVibrateSetting(vibrateType); 1277 } catch (RemoteException e) { 1278 Log.e(TAG, "Dead object in getVibrateSetting", e); 1279 return VIBRATE_SETTING_OFF; 1280 } 1281 } 1282 1283 /** 1284 * Sets the setting for when the vibrate type should vibrate. 1285 * <p> 1286 * This method should only be used by applications that replace the platform-wide 1287 * management of audio settings or the main telephony application. 1288 * 1289 * @param vibrateType The type of vibrate. One of 1290 * {@link #VIBRATE_TYPE_NOTIFICATION} or 1291 * {@link #VIBRATE_TYPE_RINGER}. 1292 * @param vibrateSetting The vibrate setting, one of 1293 * {@link #VIBRATE_SETTING_ON}, 1294 * {@link #VIBRATE_SETTING_OFF}, or 1295 * {@link #VIBRATE_SETTING_ONLY_SILENT}. 1296 * @see #getVibrateSetting(int) 1297 * @see #shouldVibrate(int) 1298 * @deprecated Applications should maintain their own vibrate policy based on 1299 * current ringer mode that can be queried via {@link #getRingerMode()}. 1300 */ 1301 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 1302 IAudioService service = getService(); 1303 try { 1304 service.setVibrateSetting(vibrateType, vibrateSetting); 1305 } catch (RemoteException e) { 1306 Log.e(TAG, "Dead object in setVibrateSetting", e); 1307 } 1308 } 1309 1310 /** 1311 * Sets the speakerphone on or off. 1312 * <p> 1313 * This method should only be used by applications that replace the platform-wide 1314 * management of audio settings or the main telephony application. 1315 * 1316 * @param on set <var>true</var> to turn on speakerphone; 1317 * <var>false</var> to turn it off 1318 */ 1319 public void setSpeakerphoneOn(boolean on){ 1320 IAudioService service = getService(); 1321 try { 1322 service.setSpeakerphoneOn(on); 1323 } catch (RemoteException e) { 1324 Log.e(TAG, "Dead object in setSpeakerphoneOn", e); 1325 } 1326 } 1327 1328 /** 1329 * Checks whether the speakerphone is on or off. 1330 * 1331 * @return true if speakerphone is on, false if it's off 1332 */ 1333 public boolean isSpeakerphoneOn() { 1334 IAudioService service = getService(); 1335 try { 1336 return service.isSpeakerphoneOn(); 1337 } catch (RemoteException e) { 1338 Log.e(TAG, "Dead object in isSpeakerphoneOn", e); 1339 return false; 1340 } 1341 } 1342 1343 //==================================================================== 1344 // Bluetooth SCO control 1345 /** 1346 * Sticky broadcast intent action indicating that the bluetoooth SCO audio 1347 * connection state has changed. The intent contains on extra {@link #EXTRA_SCO_AUDIO_STATE} 1348 * indicating the new state which is either {@link #SCO_AUDIO_STATE_DISCONNECTED} 1349 * or {@link #SCO_AUDIO_STATE_CONNECTED} 1350 * 1351 * @see #startBluetoothSco() 1352 * @deprecated Use {@link #ACTION_SCO_AUDIO_STATE_UPDATED} instead 1353 */ 1354 @Deprecated 1355 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1356 public static final String ACTION_SCO_AUDIO_STATE_CHANGED = 1357 "android.media.SCO_AUDIO_STATE_CHANGED"; 1358 1359 /** 1360 * Sticky broadcast intent action indicating that the bluetoooth SCO audio 1361 * connection state has been updated. 1362 * <p>This intent has two extras: 1363 * <ul> 1364 * <li> {@link #EXTRA_SCO_AUDIO_STATE} - The new SCO audio state. </li> 1365 * <li> {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE}- The previous SCO audio state. </li> 1366 * </ul> 1367 * <p> EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE can be any of: 1368 * <ul> 1369 * <li> {@link #SCO_AUDIO_STATE_DISCONNECTED}, </li> 1370 * <li> {@link #SCO_AUDIO_STATE_CONNECTING} or </li> 1371 * <li> {@link #SCO_AUDIO_STATE_CONNECTED}, </li> 1372 * </ul> 1373 * @see #startBluetoothSco() 1374 */ 1375 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1376 public static final String ACTION_SCO_AUDIO_STATE_UPDATED = 1377 "android.media.ACTION_SCO_AUDIO_STATE_UPDATED"; 1378 1379 /** 1380 * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_CHANGED} or 1381 * {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the new bluetooth SCO connection state. 1382 */ 1383 public static final String EXTRA_SCO_AUDIO_STATE = 1384 "android.media.extra.SCO_AUDIO_STATE"; 1385 1386 /** 1387 * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the previous 1388 * bluetooth SCO connection state. 1389 */ 1390 public static final String EXTRA_SCO_AUDIO_PREVIOUS_STATE = 1391 "android.media.extra.SCO_AUDIO_PREVIOUS_STATE"; 1392 1393 /** 1394 * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE 1395 * indicating that the SCO audio channel is not established 1396 */ 1397 public static final int SCO_AUDIO_STATE_DISCONNECTED = 0; 1398 /** 1399 * Value for extra {@link #EXTRA_SCO_AUDIO_STATE} or {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE} 1400 * indicating that the SCO audio channel is established 1401 */ 1402 public static final int SCO_AUDIO_STATE_CONNECTED = 1; 1403 /** 1404 * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE 1405 * indicating that the SCO audio channel is being established 1406 */ 1407 public static final int SCO_AUDIO_STATE_CONNECTING = 2; 1408 /** 1409 * Value for extra EXTRA_SCO_AUDIO_STATE indicating that 1410 * there was an error trying to obtain the state 1411 */ 1412 public static final int SCO_AUDIO_STATE_ERROR = -1; 1413 1414 1415 /** 1416 * Indicates if current platform supports use of SCO for off call use cases. 1417 * Application wanted to use bluetooth SCO audio when the phone is not in call 1418 * must first call this method to make sure that the platform supports this 1419 * feature. 1420 * @return true if bluetooth SCO can be used for audio when not in call 1421 * false otherwise 1422 * @see #startBluetoothSco() 1423 */ 1424 public boolean isBluetoothScoAvailableOffCall() { 1425 return mContext.getResources().getBoolean( 1426 com.android.internal.R.bool.config_bluetooth_sco_off_call); 1427 } 1428 1429 /** 1430 * Start bluetooth SCO audio connection. 1431 * <p>Requires Permission: 1432 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1433 * <p>This method can be used by applications wanting to send and received audio 1434 * to/from a bluetooth SCO headset while the phone is not in call. 1435 * <p>As the SCO connection establishment can take several seconds, 1436 * applications should not rely on the connection to be available when the method 1437 * returns but instead register to receive the intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} 1438 * and wait for the state to be {@link #SCO_AUDIO_STATE_CONNECTED}. 1439 * <p>As the ACTION_SCO_AUDIO_STATE_UPDATED intent is sticky, the application can check the SCO 1440 * audio state before calling startBluetoothSco() by reading the intent returned by the receiver 1441 * registration. If the state is already CONNECTED, no state change will be received via the 1442 * intent after calling startBluetoothSco(). It is however useful to call startBluetoothSco() 1443 * so that the connection stays active in case the current initiator stops the connection. 1444 * <p>Unless the connection is already active as described above, the state will always 1445 * transition from DISCONNECTED to CONNECTING and then either to CONNECTED if the connection 1446 * succeeds or back to DISCONNECTED if the connection fails (e.g no headset is connected). 1447 * <p>When finished with the SCO connection or if the establishment fails, the application must 1448 * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection. 1449 * <p>Even if a SCO connection is established, the following restrictions apply on audio 1450 * output streams so that they can be routed to SCO headset: 1451 * <ul> 1452 * <li> the stream type must be {@link #STREAM_VOICE_CALL} </li> 1453 * <li> the format must be mono </li> 1454 * <li> the sampling must be 16kHz or 8kHz </li> 1455 * </ul> 1456 * <p>The following restrictions apply on input streams: 1457 * <ul> 1458 * <li> the format must be mono </li> 1459 * <li> the sampling must be 8kHz </li> 1460 * </ul> 1461 * <p>Note that the phone application always has the priority on the usage of the SCO 1462 * connection for telephony. If this method is called while the phone is in call 1463 * it will be ignored. Similarly, if a call is received or sent while an application 1464 * is using the SCO connection, the connection will be lost for the application and NOT 1465 * returned automatically when the call ends. 1466 * <p>NOTE: up to and including API version 1467 * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual 1468 * voice call to the bluetooth headset. 1469 * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio 1470 * connection is established. 1471 * @see #stopBluetoothSco() 1472 * @see #ACTION_SCO_AUDIO_STATE_UPDATED 1473 */ 1474 public void startBluetoothSco(){ 1475 IAudioService service = getService(); 1476 try { 1477 service.startBluetoothSco(mICallBack, mContext.getApplicationInfo().targetSdkVersion); 1478 } catch (RemoteException e) { 1479 Log.e(TAG, "Dead object in startBluetoothSco", e); 1480 } 1481 } 1482 1483 /** 1484 * @hide 1485 * Start bluetooth SCO audio connection in virtual call mode. 1486 * <p>Requires Permission: 1487 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1488 * <p>Similar to {@link #startBluetoothSco()} with explicit selection of virtual call mode. 1489 * Telephony and communication applications (VoIP, Video Chat) should preferably select 1490 * virtual call mode. 1491 * Applications using voice input for search or commands should first try raw audio connection 1492 * with {@link #startBluetoothSco()} and fall back to startBluetoothScoVirtualCall() in case of 1493 * failure. 1494 * @see #startBluetoothSco() 1495 * @see #stopBluetoothSco() 1496 * @see #ACTION_SCO_AUDIO_STATE_UPDATED 1497 */ 1498 public void startBluetoothScoVirtualCall() { 1499 IAudioService service = getService(); 1500 try { 1501 service.startBluetoothScoVirtualCall(mICallBack); 1502 } catch (RemoteException e) { 1503 Log.e(TAG, "Dead object in startBluetoothScoVirtualCall", e); 1504 } 1505 } 1506 1507 /** 1508 * Stop bluetooth SCO audio connection. 1509 * <p>Requires Permission: 1510 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1511 * <p>This method must be called by applications having requested the use of 1512 * bluetooth SCO audio with {@link #startBluetoothSco()} when finished with the SCO 1513 * connection or if connection fails. 1514 * @see #startBluetoothSco() 1515 */ 1516 // Also used for connections started with {@link #startBluetoothScoVirtualCall()} 1517 public void stopBluetoothSco(){ 1518 IAudioService service = getService(); 1519 try { 1520 service.stopBluetoothSco(mICallBack); 1521 } catch (RemoteException e) { 1522 Log.e(TAG, "Dead object in stopBluetoothSco", e); 1523 } 1524 } 1525 1526 /** 1527 * Request use of Bluetooth SCO headset for communications. 1528 * <p> 1529 * This method should only be used by applications that replace the platform-wide 1530 * management of audio settings or the main telephony application. 1531 * 1532 * @param on set <var>true</var> to use bluetooth SCO for communications; 1533 * <var>false</var> to not use bluetooth SCO for communications 1534 */ 1535 public void setBluetoothScoOn(boolean on){ 1536 IAudioService service = getService(); 1537 try { 1538 service.setBluetoothScoOn(on); 1539 } catch (RemoteException e) { 1540 Log.e(TAG, "Dead object in setBluetoothScoOn", e); 1541 } 1542 } 1543 1544 /** 1545 * Checks whether communications use Bluetooth SCO. 1546 * 1547 * @return true if SCO is used for communications; 1548 * false if otherwise 1549 */ 1550 public boolean isBluetoothScoOn() { 1551 IAudioService service = getService(); 1552 try { 1553 return service.isBluetoothScoOn(); 1554 } catch (RemoteException e) { 1555 Log.e(TAG, "Dead object in isBluetoothScoOn", e); 1556 return false; 1557 } 1558 } 1559 1560 /** 1561 * @param on set <var>true</var> to route A2DP audio to/from Bluetooth 1562 * headset; <var>false</var> disable A2DP audio 1563 * @deprecated Do not use. 1564 */ 1565 @Deprecated public void setBluetoothA2dpOn(boolean on){ 1566 } 1567 1568 /** 1569 * Checks whether A2DP audio routing to the Bluetooth headset is on or off. 1570 * 1571 * @return true if A2DP audio is being routed to/from Bluetooth headset; 1572 * false if otherwise 1573 */ 1574 public boolean isBluetoothA2dpOn() { 1575 if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"") 1576 == AudioSystem.DEVICE_STATE_UNAVAILABLE) { 1577 return false; 1578 } else { 1579 return true; 1580 } 1581 } 1582 1583 /** 1584 * Sets audio routing to the wired headset on or off. 1585 * 1586 * @param on set <var>true</var> to route audio to/from wired 1587 * headset; <var>false</var> disable wired headset audio 1588 * @deprecated Do not use. 1589 */ 1590 @Deprecated public void setWiredHeadsetOn(boolean on){ 1591 } 1592 1593 /** 1594 * Checks whether a wired headset is connected or not. 1595 * <p>This is not a valid indication that audio playback is 1596 * actually over the wired headset as audio routing depends on other conditions. 1597 * 1598 * @return true if a wired headset is connected. 1599 * false if otherwise 1600 * @deprecated Use only to check is a headset is connected or not. 1601 */ 1602 public boolean isWiredHeadsetOn() { 1603 if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"") 1604 == AudioSystem.DEVICE_STATE_UNAVAILABLE && 1605 AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"") 1606 == AudioSystem.DEVICE_STATE_UNAVAILABLE) { 1607 return false; 1608 } else { 1609 return true; 1610 } 1611 } 1612 1613 /** 1614 * Sets the microphone mute on or off. 1615 * <p> 1616 * This method should only be used by applications that replace the platform-wide 1617 * management of audio settings or the main telephony application. 1618 * 1619 * @param on set <var>true</var> to mute the microphone; 1620 * <var>false</var> to turn mute off 1621 */ 1622 public void setMicrophoneMute(boolean on){ 1623 IAudioService service = getService(); 1624 try { 1625 service.setMicrophoneMute(on, mContext.getOpPackageName()); 1626 } catch (RemoteException e) { 1627 Log.e(TAG, "Dead object in setMicrophoneMute", e); 1628 } 1629 } 1630 1631 /** 1632 * Checks whether the microphone mute is on or off. 1633 * 1634 * @return true if microphone is muted, false if it's not 1635 */ 1636 public boolean isMicrophoneMute() { 1637 return AudioSystem.isMicrophoneMuted(); 1638 } 1639 1640 /** 1641 * Sets the audio mode. 1642 * <p> 1643 * The audio mode encompasses audio routing AND the behavior of 1644 * the telephony layer. Therefore this method should only be used by applications that 1645 * replace the platform-wide management of audio settings or the main telephony application. 1646 * In particular, the {@link #MODE_IN_CALL} mode should only be used by the telephony 1647 * application when it places a phone call, as it will cause signals from the radio layer 1648 * to feed the platform mixer. 1649 * 1650 * @param mode the requested audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, 1651 * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). 1652 * Informs the HAL about the current audio state so that 1653 * it can route the audio appropriately. 1654 */ 1655 public void setMode(int mode) { 1656 IAudioService service = getService(); 1657 try { 1658 service.setMode(mode, mICallBack); 1659 } catch (RemoteException e) { 1660 Log.e(TAG, "Dead object in setMode", e); 1661 } 1662 } 1663 1664 /** 1665 * Returns the current audio mode. 1666 * 1667 * @return the current audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, 1668 * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). 1669 * Returns the current current audio state from the HAL. 1670 */ 1671 public int getMode() { 1672 IAudioService service = getService(); 1673 try { 1674 return service.getMode(); 1675 } catch (RemoteException e) { 1676 Log.e(TAG, "Dead object in getMode", e); 1677 return MODE_INVALID; 1678 } 1679 } 1680 1681 /* modes for setMode/getMode/setRoute/getRoute */ 1682 /** 1683 * Audio harware modes. 1684 */ 1685 /** 1686 * Invalid audio mode. 1687 */ 1688 public static final int MODE_INVALID = AudioSystem.MODE_INVALID; 1689 /** 1690 * Current audio mode. Used to apply audio routing to current mode. 1691 */ 1692 public static final int MODE_CURRENT = AudioSystem.MODE_CURRENT; 1693 /** 1694 * Normal audio mode: not ringing and no call established. 1695 */ 1696 public static final int MODE_NORMAL = AudioSystem.MODE_NORMAL; 1697 /** 1698 * Ringing audio mode. An incoming is being signaled. 1699 */ 1700 public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE; 1701 /** 1702 * In call audio mode. A telephony call is established. 1703 */ 1704 public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL; 1705 /** 1706 * In communication audio mode. An audio/video chat or VoIP call is established. 1707 */ 1708 public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION; 1709 1710 /* Routing bits for setRouting/getRouting API */ 1711 /** 1712 * Routing audio output to earpiece 1713 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1714 * setBluetoothScoOn() methods instead. 1715 */ 1716 @Deprecated public static final int ROUTE_EARPIECE = AudioSystem.ROUTE_EARPIECE; 1717 /** 1718 * Routing audio output to speaker 1719 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1720 * setBluetoothScoOn() methods instead. 1721 */ 1722 @Deprecated public static final int ROUTE_SPEAKER = AudioSystem.ROUTE_SPEAKER; 1723 /** 1724 * @deprecated use {@link #ROUTE_BLUETOOTH_SCO} 1725 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1726 * setBluetoothScoOn() methods instead. 1727 */ 1728 @Deprecated public static final int ROUTE_BLUETOOTH = AudioSystem.ROUTE_BLUETOOTH_SCO; 1729 /** 1730 * Routing audio output to bluetooth SCO 1731 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1732 * setBluetoothScoOn() methods instead. 1733 */ 1734 @Deprecated public static final int ROUTE_BLUETOOTH_SCO = AudioSystem.ROUTE_BLUETOOTH_SCO; 1735 /** 1736 * Routing audio output to headset 1737 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1738 * setBluetoothScoOn() methods instead. 1739 */ 1740 @Deprecated public static final int ROUTE_HEADSET = AudioSystem.ROUTE_HEADSET; 1741 /** 1742 * Routing audio output to bluetooth A2DP 1743 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1744 * setBluetoothScoOn() methods instead. 1745 */ 1746 @Deprecated public static final int ROUTE_BLUETOOTH_A2DP = AudioSystem.ROUTE_BLUETOOTH_A2DP; 1747 /** 1748 * Used for mask parameter of {@link #setRouting(int,int,int)}. 1749 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1750 * setBluetoothScoOn() methods instead. 1751 */ 1752 @Deprecated public static final int ROUTE_ALL = AudioSystem.ROUTE_ALL; 1753 1754 /** 1755 * Sets the audio routing for a specified mode 1756 * 1757 * @param mode audio mode to change route. E.g., MODE_RINGTONE. 1758 * @param routes bit vector of routes requested, created from one or 1759 * more of ROUTE_xxx types. Set bits indicate that route should be on 1760 * @param mask bit vector of routes to change, created from one or more of 1761 * ROUTE_xxx types. Unset bits indicate the route should be left unchanged 1762 * 1763 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1764 * setBluetoothScoOn() methods instead. 1765 */ 1766 @Deprecated 1767 public void setRouting(int mode, int routes, int mask) { 1768 } 1769 1770 /** 1771 * Returns the current audio routing bit vector for a specified mode. 1772 * 1773 * @param mode audio mode to get route (e.g., MODE_RINGTONE) 1774 * @return an audio route bit vector that can be compared with ROUTE_xxx 1775 * bits 1776 * @deprecated Do not query audio routing directly, use isSpeakerphoneOn(), 1777 * isBluetoothScoOn(), isBluetoothA2dpOn() and isWiredHeadsetOn() methods instead. 1778 */ 1779 @Deprecated 1780 public int getRouting(int mode) { 1781 return -1; 1782 } 1783 1784 /** 1785 * Checks whether any music is active. 1786 * 1787 * @return true if any music tracks are active. 1788 */ 1789 public boolean isMusicActive() { 1790 return AudioSystem.isStreamActive(STREAM_MUSIC, 0); 1791 } 1792 1793 /** 1794 * @hide 1795 * Checks whether any music or media is actively playing on a remote device (e.g. wireless 1796 * display). Note that BT audio sinks are not considered remote devices. 1797 * @return true if {@link AudioManager#STREAM_MUSIC} is active on a remote device 1798 */ 1799 public boolean isMusicActiveRemotely() { 1800 return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0); 1801 } 1802 1803 /** 1804 * @hide 1805 * Checks whether the current audio focus is exclusive. 1806 * @return true if the top of the audio focus stack requested focus 1807 * with {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} 1808 */ 1809 public boolean isAudioFocusExclusive() { 1810 IAudioService service = getService(); 1811 try { 1812 return service.getCurrentAudioFocus() == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE; 1813 } catch (RemoteException e) { 1814 Log.e(TAG, "Dead object in isAudioFocusExclusive()", e); 1815 return false; 1816 } 1817 } 1818 1819 /** 1820 * Return a new audio session identifier not associated with any player or effect. 1821 * An audio session identifier is a system wide unique identifier for a set of audio streams 1822 * (one or more mixed together). 1823 * <p>The primary use of the audio session ID is to associate audio effects to audio players, 1824 * such as {@link MediaPlayer} or {@link AudioTrack}: all audio effects sharing the same audio 1825 * session ID will be applied to the mixed audio content of the players that share the same 1826 * audio session. 1827 * <p>This method can for instance be used when creating one of the 1828 * {@link android.media.audiofx.AudioEffect} objects to define the audio session of the effect, 1829 * or to specify a session for a speech synthesis utterance 1830 * in {@link android.speech.tts.TextToSpeech.Engine}. 1831 * @return a new unclaimed and unused audio session identifier, or {@link #ERROR} when the 1832 * system failed to generate a new session, a condition in which audio playback or recording 1833 * will subsequently fail as well. 1834 */ 1835 public int generateAudioSessionId() { 1836 int session = AudioSystem.newAudioSessionId(); 1837 if (session > 0) { 1838 return session; 1839 } else { 1840 Log.e(TAG, "Failure to generate a new audio session ID"); 1841 return ERROR; 1842 } 1843 } 1844 1845 /** 1846 * A special audio session ID to indicate that the audio session ID isn't known and the 1847 * framework should generate a new value. This can be used when building a new 1848 * {@link AudioTrack} instance with 1849 * {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}. 1850 */ 1851 public static final int AUDIO_SESSION_ID_GENERATE = AudioSystem.AUDIO_SESSION_ALLOCATE; 1852 1853 1854 /* 1855 * Sets a generic audio configuration parameter. The use of these parameters 1856 * are platform dependant, see libaudio 1857 * 1858 * ** Temporary interface - DO NOT USE 1859 * 1860 * TODO: Replace with a more generic key:value get/set mechanism 1861 * 1862 * param key name of parameter to set. Must not be null. 1863 * param value value of parameter. Must not be null. 1864 */ 1865 /** 1866 * @hide 1867 * @deprecated Use {@link #setParameters(String)} instead 1868 */ 1869 @Deprecated public void setParameter(String key, String value) { 1870 setParameters(key+"="+value); 1871 } 1872 1873 /** 1874 * Sets a variable number of parameter values to audio hardware. 1875 * 1876 * @param keyValuePairs list of parameters key value pairs in the form: 1877 * key1=value1;key2=value2;... 1878 * 1879 */ 1880 public void setParameters(String keyValuePairs) { 1881 AudioSystem.setParameters(keyValuePairs); 1882 } 1883 1884 /** 1885 * Gets a variable number of parameter values from audio hardware. 1886 * 1887 * @param keys list of parameters 1888 * @return list of parameters key value pairs in the form: 1889 * key1=value1;key2=value2;... 1890 */ 1891 public String getParameters(String keys) { 1892 return AudioSystem.getParameters(keys); 1893 } 1894 1895 /* Sound effect identifiers */ 1896 /** 1897 * Keyboard and direction pad click sound 1898 * @see #playSoundEffect(int) 1899 */ 1900 public static final int FX_KEY_CLICK = 0; 1901 /** 1902 * Focus has moved up 1903 * @see #playSoundEffect(int) 1904 */ 1905 public static final int FX_FOCUS_NAVIGATION_UP = 1; 1906 /** 1907 * Focus has moved down 1908 * @see #playSoundEffect(int) 1909 */ 1910 public static final int FX_FOCUS_NAVIGATION_DOWN = 2; 1911 /** 1912 * Focus has moved left 1913 * @see #playSoundEffect(int) 1914 */ 1915 public static final int FX_FOCUS_NAVIGATION_LEFT = 3; 1916 /** 1917 * Focus has moved right 1918 * @see #playSoundEffect(int) 1919 */ 1920 public static final int FX_FOCUS_NAVIGATION_RIGHT = 4; 1921 /** 1922 * IME standard keypress sound 1923 * @see #playSoundEffect(int) 1924 */ 1925 public static final int FX_KEYPRESS_STANDARD = 5; 1926 /** 1927 * IME spacebar keypress sound 1928 * @see #playSoundEffect(int) 1929 */ 1930 public static final int FX_KEYPRESS_SPACEBAR = 6; 1931 /** 1932 * IME delete keypress sound 1933 * @see #playSoundEffect(int) 1934 */ 1935 public static final int FX_KEYPRESS_DELETE = 7; 1936 /** 1937 * IME return_keypress sound 1938 * @see #playSoundEffect(int) 1939 */ 1940 public static final int FX_KEYPRESS_RETURN = 8; 1941 1942 /** 1943 * Invalid keypress sound 1944 * @see #playSoundEffect(int) 1945 */ 1946 public static final int FX_KEYPRESS_INVALID = 9; 1947 /** 1948 * @hide Number of sound effects 1949 */ 1950 public static final int NUM_SOUND_EFFECTS = 10; 1951 1952 /** 1953 * Plays a sound effect (Key clicks, lid open/close...) 1954 * @param effectType The type of sound effect. One of 1955 * {@link #FX_KEY_CLICK}, 1956 * {@link #FX_FOCUS_NAVIGATION_UP}, 1957 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 1958 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 1959 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 1960 * {@link #FX_KEYPRESS_STANDARD}, 1961 * {@link #FX_KEYPRESS_SPACEBAR}, 1962 * {@link #FX_KEYPRESS_DELETE}, 1963 * {@link #FX_KEYPRESS_RETURN}, 1964 * {@link #FX_KEYPRESS_INVALID}, 1965 * NOTE: This version uses the UI settings to determine 1966 * whether sounds are heard or not. 1967 */ 1968 public void playSoundEffect(int effectType) { 1969 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 1970 return; 1971 } 1972 1973 if (!querySoundEffectsEnabled(Process.myUserHandle().getIdentifier())) { 1974 return; 1975 } 1976 1977 IAudioService service = getService(); 1978 try { 1979 service.playSoundEffect(effectType); 1980 } catch (RemoteException e) { 1981 Log.e(TAG, "Dead object in playSoundEffect"+e); 1982 } 1983 } 1984 1985 /** 1986 * Plays a sound effect (Key clicks, lid open/close...) 1987 * @param effectType The type of sound effect. One of 1988 * {@link #FX_KEY_CLICK}, 1989 * {@link #FX_FOCUS_NAVIGATION_UP}, 1990 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 1991 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 1992 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 1993 * {@link #FX_KEYPRESS_STANDARD}, 1994 * {@link #FX_KEYPRESS_SPACEBAR}, 1995 * {@link #FX_KEYPRESS_DELETE}, 1996 * {@link #FX_KEYPRESS_RETURN}, 1997 * {@link #FX_KEYPRESS_INVALID}, 1998 * @param userId The current user to pull sound settings from 1999 * NOTE: This version uses the UI settings to determine 2000 * whether sounds are heard or not. 2001 * @hide 2002 */ 2003 public void playSoundEffect(int effectType, int userId) { 2004 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 2005 return; 2006 } 2007 2008 if (!querySoundEffectsEnabled(userId)) { 2009 return; 2010 } 2011 2012 IAudioService service = getService(); 2013 try { 2014 service.playSoundEffect(effectType); 2015 } catch (RemoteException e) { 2016 Log.e(TAG, "Dead object in playSoundEffect"+e); 2017 } 2018 } 2019 2020 /** 2021 * Plays a sound effect (Key clicks, lid open/close...) 2022 * @param effectType The type of sound effect. One of 2023 * {@link #FX_KEY_CLICK}, 2024 * {@link #FX_FOCUS_NAVIGATION_UP}, 2025 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 2026 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 2027 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 2028 * {@link #FX_KEYPRESS_STANDARD}, 2029 * {@link #FX_KEYPRESS_SPACEBAR}, 2030 * {@link #FX_KEYPRESS_DELETE}, 2031 * {@link #FX_KEYPRESS_RETURN}, 2032 * {@link #FX_KEYPRESS_INVALID}, 2033 * @param volume Sound effect volume. 2034 * The volume value is a raw scalar so UI controls should be scaled logarithmically. 2035 * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used. 2036 * NOTE: This version is for applications that have their own 2037 * settings panel for enabling and controlling volume. 2038 */ 2039 public void playSoundEffect(int effectType, float volume) { 2040 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 2041 return; 2042 } 2043 2044 IAudioService service = getService(); 2045 try { 2046 service.playSoundEffectVolume(effectType, volume); 2047 } catch (RemoteException e) { 2048 Log.e(TAG, "Dead object in playSoundEffect"+e); 2049 } 2050 } 2051 2052 /** 2053 * Settings has an in memory cache, so this is fast. 2054 */ 2055 private boolean querySoundEffectsEnabled(int user) { 2056 return Settings.System.getIntForUser(mContext.getContentResolver(), 2057 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0; 2058 } 2059 2060 2061 /** 2062 * Load Sound effects. 2063 * This method must be called when sound effects are enabled. 2064 */ 2065 public void loadSoundEffects() { 2066 IAudioService service = getService(); 2067 try { 2068 service.loadSoundEffects(); 2069 } catch (RemoteException e) { 2070 Log.e(TAG, "Dead object in loadSoundEffects"+e); 2071 } 2072 } 2073 2074 /** 2075 * Unload Sound effects. 2076 * This method can be called to free some memory when 2077 * sound effects are disabled. 2078 */ 2079 public void unloadSoundEffects() { 2080 IAudioService service = getService(); 2081 try { 2082 service.unloadSoundEffects(); 2083 } catch (RemoteException e) { 2084 Log.e(TAG, "Dead object in unloadSoundEffects"+e); 2085 } 2086 } 2087 2088 /** 2089 * @hide 2090 * Used to indicate no audio focus has been gained or lost. 2091 */ 2092 public static final int AUDIOFOCUS_NONE = 0; 2093 2094 /** 2095 * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration. 2096 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 2097 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 2098 */ 2099 public static final int AUDIOFOCUS_GAIN = 1; 2100 /** 2101 * Used to indicate a temporary gain or request of audio focus, anticipated to last a short 2102 * amount of time. Examples of temporary changes are the playback of driving directions, or an 2103 * event notification. 2104 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 2105 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 2106 */ 2107 public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2; 2108 /** 2109 * Used to indicate a temporary request of audio focus, anticipated to last a short 2110 * amount of time, and where it is acceptable for other audio applications to keep playing 2111 * after having lowered their output level (also referred to as "ducking"). 2112 * Examples of temporary changes are the playback of driving directions where playback of music 2113 * in the background is acceptable. 2114 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 2115 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 2116 */ 2117 public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3; 2118 /** 2119 * Used to indicate a temporary request of audio focus, anticipated to last a short 2120 * amount of time, during which no other applications, or system components, should play 2121 * anything. Examples of exclusive and transient audio focus requests are voice 2122 * memo recording and speech recognition, during which the system shouldn't play any 2123 * notifications, and media playback should have paused. 2124 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 2125 */ 2126 public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE = 4; 2127 /** 2128 * Used to indicate a loss of audio focus of unknown duration. 2129 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 2130 */ 2131 public static final int AUDIOFOCUS_LOSS = -1 * AUDIOFOCUS_GAIN; 2132 /** 2133 * Used to indicate a transient loss of audio focus. 2134 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 2135 */ 2136 public static final int AUDIOFOCUS_LOSS_TRANSIENT = -1 * AUDIOFOCUS_GAIN_TRANSIENT; 2137 /** 2138 * Used to indicate a transient loss of audio focus where the loser of the audio focus can 2139 * lower its output volume if it wants to continue playing (also referred to as "ducking"), as 2140 * the new focus owner doesn't require others to be silent. 2141 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 2142 */ 2143 public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = 2144 -1 * AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK; 2145 2146 /** 2147 * Interface definition for a callback to be invoked when the audio focus of the system is 2148 * updated. 2149 */ 2150 public interface OnAudioFocusChangeListener { 2151 /** 2152 * Called on the listener to notify it the audio focus for this listener has been changed. 2153 * The focusChange value indicates whether the focus was gained, 2154 * whether the focus was lost, and whether that loss is transient, or whether the new focus 2155 * holder will hold it for an unknown amount of time. 2156 * When losing focus, listeners can use the focus change information to decide what 2157 * behavior to adopt when losing focus. A music player could for instance elect to lower 2158 * the volume of its music stream (duck) for transient focus losses, and pause otherwise. 2159 * @param focusChange the type of focus change, one of {@link AudioManager#AUDIOFOCUS_GAIN}, 2160 * {@link AudioManager#AUDIOFOCUS_LOSS}, {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT} 2161 * and {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}. 2162 */ 2163 public void onAudioFocusChange(int focusChange); 2164 } 2165 2166 /** 2167 * Map to convert focus event listener IDs, as used in the AudioService audio focus stack, 2168 * to actual listener objects. 2169 */ 2170 private final HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap = 2171 new HashMap<String, OnAudioFocusChangeListener>(); 2172 /** 2173 * Lock to prevent concurrent changes to the list of focus listeners for this AudioManager 2174 * instance. 2175 */ 2176 private final Object mFocusListenerLock = new Object(); 2177 2178 private OnAudioFocusChangeListener findFocusListener(String id) { 2179 return mAudioFocusIdListenerMap.get(id); 2180 } 2181 2182 /** 2183 * Handler for audio focus events coming from the audio service. 2184 */ 2185 private final FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate = 2186 new FocusEventHandlerDelegate(); 2187 2188 /** 2189 * Helper class to handle the forwarding of audio focus events to the appropriate listener 2190 */ 2191 private class FocusEventHandlerDelegate { 2192 private final Handler mHandler; 2193 2194 FocusEventHandlerDelegate() { 2195 Looper looper; 2196 if ((looper = Looper.myLooper()) == null) { 2197 looper = Looper.getMainLooper(); 2198 } 2199 2200 if (looper != null) { 2201 // implement the event handler delegate to receive audio focus events 2202 mHandler = new Handler(looper) { 2203 @Override 2204 public void handleMessage(Message msg) { 2205 OnAudioFocusChangeListener listener = null; 2206 synchronized(mFocusListenerLock) { 2207 listener = findFocusListener((String)msg.obj); 2208 } 2209 if (listener != null) { 2210 listener.onAudioFocusChange(msg.what); 2211 } 2212 } 2213 }; 2214 } else { 2215 mHandler = null; 2216 } 2217 } 2218 2219 Handler getHandler() { 2220 return mHandler; 2221 } 2222 } 2223 2224 private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() { 2225 2226 public void dispatchAudioFocusChange(int focusChange, String id) { 2227 Message m = mAudioFocusEventHandlerDelegate.getHandler().obtainMessage(focusChange, id); 2228 mAudioFocusEventHandlerDelegate.getHandler().sendMessage(m); 2229 } 2230 2231 }; 2232 2233 private String getIdForAudioFocusListener(OnAudioFocusChangeListener l) { 2234 if (l == null) { 2235 return new String(this.toString()); 2236 } else { 2237 return new String(this.toString() + l.toString()); 2238 } 2239 } 2240 2241 /** 2242 * @hide 2243 * Registers a listener to be called when audio focus changes. Calling this method is optional 2244 * before calling {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, as it 2245 * will register the listener as well if it wasn't registered already. 2246 * @param l the listener to be notified of audio focus changes. 2247 */ 2248 public void registerAudioFocusListener(OnAudioFocusChangeListener l) { 2249 synchronized(mFocusListenerLock) { 2250 if (mAudioFocusIdListenerMap.containsKey(getIdForAudioFocusListener(l))) { 2251 return; 2252 } 2253 mAudioFocusIdListenerMap.put(getIdForAudioFocusListener(l), l); 2254 } 2255 } 2256 2257 /** 2258 * @hide 2259 * Causes the specified listener to not be called anymore when focus is gained or lost. 2260 * @param l the listener to unregister. 2261 */ 2262 public void unregisterAudioFocusListener(OnAudioFocusChangeListener l) { 2263 2264 // remove locally 2265 synchronized(mFocusListenerLock) { 2266 mAudioFocusIdListenerMap.remove(getIdForAudioFocusListener(l)); 2267 } 2268 } 2269 2270 2271 /** 2272 * A failed focus change request. 2273 */ 2274 public static final int AUDIOFOCUS_REQUEST_FAILED = 0; 2275 /** 2276 * A successful focus change request. 2277 */ 2278 public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; 2279 2280 2281 /** 2282 * Request audio focus. 2283 * Send a request to obtain the audio focus 2284 * @param l the listener to be notified of audio focus changes 2285 * @param streamType the main audio stream type affected by the focus request 2286 * @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request 2287 * is temporary, and focus will be abandonned shortly. Examples of transient requests are 2288 * for the playback of driving directions, or notifications sounds. 2289 * Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for 2290 * the previous focus owner to keep playing if it ducks its audio output. 2291 * Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request 2292 * that benefits from the system not playing disruptive sounds like notifications, for 2293 * usecases such as voice memo recording, or speech recognition. 2294 * Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such 2295 * as the playback of a song or a video. 2296 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 2297 */ 2298 public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) { 2299 int status = AUDIOFOCUS_REQUEST_FAILED; 2300 if ((durationHint < AUDIOFOCUS_GAIN) || 2301 (durationHint > AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) { 2302 Log.e(TAG, "Invalid duration hint, audio focus request denied"); 2303 return status; 2304 } 2305 registerAudioFocusListener(l); 2306 //TODO protect request by permission check? 2307 IAudioService service = getService(); 2308 try { 2309 status = service.requestAudioFocus(streamType, durationHint, mICallBack, 2310 mAudioFocusDispatcher, getIdForAudioFocusListener(l), 2311 mContext.getOpPackageName() /* package name */); 2312 } catch (RemoteException e) { 2313 Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e); 2314 } 2315 return status; 2316 } 2317 2318 /** 2319 * @hide 2320 * Used internally by telephony package to request audio focus. Will cause the focus request 2321 * to be associated with the "voice communication" identifier only used in AudioService 2322 * to identify this use case. 2323 * @param streamType use STREAM_RING for focus requests when ringing, VOICE_CALL for 2324 * the establishment of the call 2325 * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so 2326 * media applications resume after a call 2327 */ 2328 public void requestAudioFocusForCall(int streamType, int durationHint) { 2329 IAudioService service = getService(); 2330 try { 2331 service.requestAudioFocus(streamType, durationHint, mICallBack, null, 2332 MediaFocusControl.IN_VOICE_COMM_FOCUS_ID, 2333 mContext.getOpPackageName()); 2334 } catch (RemoteException e) { 2335 Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e); 2336 } 2337 } 2338 2339 /** 2340 * @hide 2341 * Used internally by telephony package to abandon audio focus, typically after a call or 2342 * when ringing ends and the call is rejected or not answered. 2343 * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}. 2344 */ 2345 public void abandonAudioFocusForCall() { 2346 IAudioService service = getService(); 2347 try { 2348 service.abandonAudioFocus(null, MediaFocusControl.IN_VOICE_COMM_FOCUS_ID); 2349 } catch (RemoteException e) { 2350 Log.e(TAG, "Can't call abandonAudioFocusForCall() on AudioService due to "+e); 2351 } 2352 } 2353 2354 /** 2355 * Abandon audio focus. Causes the previous focus owner, if any, to receive focus. 2356 * @param l the listener with which focus was requested. 2357 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 2358 */ 2359 public int abandonAudioFocus(OnAudioFocusChangeListener l) { 2360 int status = AUDIOFOCUS_REQUEST_FAILED; 2361 unregisterAudioFocusListener(l); 2362 IAudioService service = getService(); 2363 try { 2364 status = service.abandonAudioFocus(mAudioFocusDispatcher, 2365 getIdForAudioFocusListener(l)); 2366 } catch (RemoteException e) { 2367 Log.e(TAG, "Can't call abandonAudioFocus() on AudioService due to "+e); 2368 } 2369 return status; 2370 } 2371 2372 2373 //==================================================================== 2374 // Remote Control 2375 /** 2376 * Register a component to be the sole receiver of MEDIA_BUTTON intents. 2377 * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} 2378 * that will receive the media button intent. This broadcast receiver must be declared 2379 * in the application manifest. The package of the component must match that of 2380 * the context you're registering from. 2381 * @deprecated Use {@link MediaSession#setMediaButtonReceiver(PendingIntent)} instead. 2382 */ 2383 @Deprecated 2384 public void registerMediaButtonEventReceiver(ComponentName eventReceiver) { 2385 if (eventReceiver == null) { 2386 return; 2387 } 2388 if (!eventReceiver.getPackageName().equals(mContext.getPackageName())) { 2389 Log.e(TAG, "registerMediaButtonEventReceiver() error: " + 2390 "receiver and context package names don't match"); 2391 return; 2392 } 2393 // construct a PendingIntent for the media button and register it 2394 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 2395 // the associated intent will be handled by the component being registered 2396 mediaButtonIntent.setComponent(eventReceiver); 2397 PendingIntent pi = PendingIntent.getBroadcast(mContext, 2398 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); 2399 registerMediaButtonIntent(pi, eventReceiver); 2400 } 2401 2402 /** 2403 * Register a component to be the sole receiver of MEDIA_BUTTON intents. This is like 2404 * {@link #registerMediaButtonEventReceiver(android.content.ComponentName)}, but allows 2405 * the buttons to go to any PendingIntent. Note that you should only use this form if 2406 * you know you will continue running for the full time until unregistering the 2407 * PendingIntent. 2408 * @param eventReceiver target that will receive media button intents. The PendingIntent 2409 * will be sent an {@link Intent#ACTION_MEDIA_BUTTON} event when a media button action 2410 * occurs, with {@link Intent#EXTRA_KEY_EVENT} added and holding the key code of the 2411 * media button that was pressed. 2412 * @deprecated Use {@link MediaSession#setMediaButtonReceiver(PendingIntent)} instead. 2413 */ 2414 @Deprecated 2415 public void registerMediaButtonEventReceiver(PendingIntent eventReceiver) { 2416 if (eventReceiver == null) { 2417 return; 2418 } 2419 registerMediaButtonIntent(eventReceiver, null); 2420 } 2421 2422 /** 2423 * @hide 2424 * no-op if (pi == null) or (eventReceiver == null) 2425 */ 2426 public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) { 2427 if (pi == null) { 2428 Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null parameter"); 2429 return; 2430 } 2431 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 2432 helper.addMediaButtonListener(pi, eventReceiver, mContext); 2433 } 2434 2435 /** 2436 * Unregister the receiver of MEDIA_BUTTON intents. 2437 * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} 2438 * that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}. 2439 * @deprecated Use {@link MediaSession} instead. 2440 */ 2441 @Deprecated 2442 public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) { 2443 if (eventReceiver == null) { 2444 return; 2445 } 2446 // construct a PendingIntent for the media button and unregister it 2447 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 2448 // the associated intent will be handled by the component being registered 2449 mediaButtonIntent.setComponent(eventReceiver); 2450 PendingIntent pi = PendingIntent.getBroadcast(mContext, 2451 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); 2452 unregisterMediaButtonIntent(pi); 2453 } 2454 2455 /** 2456 * Unregister the receiver of MEDIA_BUTTON intents. 2457 * @param eventReceiver same PendingIntent that was registed with 2458 * {@link #registerMediaButtonEventReceiver(PendingIntent)}. 2459 * @deprecated Use {@link MediaSession} instead. 2460 */ 2461 @Deprecated 2462 public void unregisterMediaButtonEventReceiver(PendingIntent eventReceiver) { 2463 if (eventReceiver == null) { 2464 return; 2465 } 2466 unregisterMediaButtonIntent(eventReceiver); 2467 } 2468 2469 /** 2470 * @hide 2471 */ 2472 public void unregisterMediaButtonIntent(PendingIntent pi) { 2473 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 2474 helper.removeMediaButtonListener(pi); 2475 } 2476 2477 /** 2478 * Registers the remote control client for providing information to display on the remote 2479 * controls. 2480 * @param rcClient The remote control client from which remote controls will receive 2481 * information to display. 2482 * @see RemoteControlClient 2483 * @deprecated Use {@link MediaSession} instead. 2484 */ 2485 @Deprecated 2486 public void registerRemoteControlClient(RemoteControlClient rcClient) { 2487 if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { 2488 return; 2489 } 2490 rcClient.registerWithSession(MediaSessionLegacyHelper.getHelper(mContext)); 2491 } 2492 2493 /** 2494 * Unregisters the remote control client that was providing information to display on the 2495 * remote controls. 2496 * @param rcClient The remote control client to unregister. 2497 * @see #registerRemoteControlClient(RemoteControlClient) 2498 * @deprecated Use {@link MediaSession} instead. 2499 */ 2500 @Deprecated 2501 public void unregisterRemoteControlClient(RemoteControlClient rcClient) { 2502 if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { 2503 return; 2504 } 2505 rcClient.unregisterWithSession(MediaSessionLegacyHelper.getHelper(mContext)); 2506 } 2507 2508 /** 2509 * Registers a {@link RemoteController} instance for it to receive media 2510 * metadata updates and playback state information from applications using 2511 * {@link RemoteControlClient}, and control their playback. 2512 * <p> 2513 * Registration requires the {@link OnClientUpdateListener} listener to be 2514 * one of the enabled notification listeners (see 2515 * {@link android.service.notification.NotificationListenerService}). 2516 * 2517 * @param rctlr the object to register. 2518 * @return true if the {@link RemoteController} was successfully registered, 2519 * false if an error occurred, due to an internal system error, or 2520 * insufficient permissions. 2521 * @deprecated Use 2522 * {@link MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, ComponentName)} 2523 * and {@link MediaController} instead. 2524 */ 2525 @Deprecated 2526 public boolean registerRemoteController(RemoteController rctlr) { 2527 if (rctlr == null) { 2528 return false; 2529 } 2530 rctlr.startListeningToSessions(); 2531 return true; 2532 } 2533 2534 /** 2535 * Unregisters a {@link RemoteController}, causing it to no longer receive 2536 * media metadata and playback state information, and no longer be capable 2537 * of controlling playback. 2538 * 2539 * @param rctlr the object to unregister. 2540 * @deprecated Use 2541 * {@link MediaSessionManager#removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener)} 2542 * instead. 2543 */ 2544 @Deprecated 2545 public void unregisterRemoteController(RemoteController rctlr) { 2546 if (rctlr == null) { 2547 return; 2548 } 2549 rctlr.stopListeningToSessions(); 2550 } 2551 2552 /** 2553 * @hide 2554 * Registers a remote control display that will be sent information by remote control clients. 2555 * Use this method if your IRemoteControlDisplay is not going to display artwork, otherwise 2556 * use {@link #registerRemoteControlDisplay(IRemoteControlDisplay, int, int)} to pass the 2557 * artwork size directly, or 2558 * {@link #remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay, int, int)} later if artwork 2559 * is not yet needed. 2560 * <p>Registration requires the {@link Manifest.permission#MEDIA_CONTENT_CONTROL} permission. 2561 * @param rcd the IRemoteControlDisplay 2562 */ 2563 public void registerRemoteControlDisplay(IRemoteControlDisplay rcd) { 2564 // passing a negative value for art work width and height as they are unknown at this stage 2565 registerRemoteControlDisplay(rcd, /*w*/-1, /*h*/ -1); 2566 } 2567 2568 /** 2569 * @hide 2570 * Registers a remote control display that will be sent information by remote control clients. 2571 * <p>Registration requires the {@link Manifest.permission#MEDIA_CONTENT_CONTROL} permission. 2572 * @param rcd 2573 * @param w the maximum width of the expected bitmap. Negative values indicate it is 2574 * useless to send artwork. 2575 * @param h the maximum height of the expected bitmap. Negative values indicate it is 2576 * useless to send artwork. 2577 */ 2578 public void registerRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h) { 2579 if (rcd == null) { 2580 return; 2581 } 2582 IAudioService service = getService(); 2583 try { 2584 service.registerRemoteControlDisplay(rcd, w, h); 2585 } catch (RemoteException e) { 2586 Log.e(TAG, "Dead object in registerRemoteControlDisplay " + e); 2587 } 2588 } 2589 2590 /** 2591 * @hide 2592 * Unregisters a remote control display that was sent information by remote control clients. 2593 * @param rcd 2594 */ 2595 public void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) { 2596 if (rcd == null) { 2597 return; 2598 } 2599 IAudioService service = getService(); 2600 try { 2601 service.unregisterRemoteControlDisplay(rcd); 2602 } catch (RemoteException e) { 2603 Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e); 2604 } 2605 } 2606 2607 /** 2608 * @hide 2609 * Sets the artwork size a remote control display expects when receiving bitmaps. 2610 * @param rcd 2611 * @param w the maximum width of the expected bitmap. Negative values indicate it is 2612 * useless to send artwork. 2613 * @param h the maximum height of the expected bitmap. Negative values indicate it is 2614 * useless to send artwork. 2615 */ 2616 public void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) { 2617 if (rcd == null) { 2618 return; 2619 } 2620 IAudioService service = getService(); 2621 try { 2622 service.remoteControlDisplayUsesBitmapSize(rcd, w, h); 2623 } catch (RemoteException e) { 2624 Log.e(TAG, "Dead object in remoteControlDisplayUsesBitmapSize " + e); 2625 } 2626 } 2627 2628 /** 2629 * @hide 2630 * Controls whether a remote control display needs periodic checks of the RemoteControlClient 2631 * playback position to verify that the estimated position has not drifted from the actual 2632 * position. By default the check is not performed. 2633 * The IRemoteControlDisplay must have been previously registered for this to have any effect. 2634 * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled 2635 * or disabled. No effect is null. 2636 * @param wantsSync if true, RemoteControlClient instances which expose their playback position 2637 * to the framework will regularly compare the estimated playback position with the actual 2638 * position, and will update the IRemoteControlDisplay implementation whenever a drift is 2639 * detected. 2640 */ 2641 public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd, 2642 boolean wantsSync) { 2643 if (rcd == null) { 2644 return; 2645 } 2646 IAudioService service = getService(); 2647 try { 2648 service.remoteControlDisplayWantsPlaybackPositionSync(rcd, wantsSync); 2649 } catch (RemoteException e) { 2650 Log.e(TAG, "Dead object in remoteControlDisplayWantsPlaybackPositionSync " + e); 2651 } 2652 } 2653 2654 /** 2655 * @hide 2656 * CANDIDATE FOR PUBLIC API 2657 * Register the given {@link AudioPolicy}. 2658 * This call is synchronous and blocks until the registration process successfully completed 2659 * or failed to complete. 2660 * @param policy the {@link AudioPolicy} to register. 2661 * @return {@link #ERROR} if there was an error communicating with the registration service 2662 * or if the user doesn't have the required 2663 * {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission, 2664 * {@link #SUCCESS} otherwise. 2665 */ 2666 public int registerAudioPolicy(AudioPolicy policy) { 2667 if (policy == null) { 2668 throw new IllegalArgumentException("Illegal null AudioPolicy argument"); 2669 } 2670 IAudioService service = getService(); 2671 try { 2672 if (!service.registerAudioPolicy(policy.getConfig(), policy.token())) { 2673 return ERROR; 2674 } 2675 } catch (RemoteException e) { 2676 Log.e(TAG, "Dead object in registerAudioPolicyAsync()", e); 2677 return ERROR; 2678 } 2679 return SUCCESS; 2680 } 2681 2682 /** 2683 * @hide 2684 * CANDIDATE FOR PUBLIC API 2685 * @param policy the {@link AudioPolicy} to unregister. 2686 */ 2687 public void unregisterAudioPolicyAsync(AudioPolicy policy) { 2688 if (policy == null) { 2689 throw new IllegalArgumentException("Illegal null AudioPolicy argument"); 2690 } 2691 IAudioService service = getService(); 2692 try { 2693 service.unregisterAudioPolicyAsync(policy.token()); 2694 } catch (RemoteException e) { 2695 Log.e(TAG, "Dead object in unregisterAudioPolicyAsync()", e); 2696 } 2697 } 2698 2699 2700 /** 2701 * @hide 2702 * Reload audio settings. This method is called by Settings backup 2703 * agent when audio settings are restored and causes the AudioService 2704 * to read and apply restored settings. 2705 */ 2706 public void reloadAudioSettings() { 2707 IAudioService service = getService(); 2708 try { 2709 service.reloadAudioSettings(); 2710 } catch (RemoteException e) { 2711 Log.e(TAG, "Dead object in reloadAudioSettings"+e); 2712 } 2713 } 2714 2715 /** 2716 * @hide 2717 * Notifies AudioService that it is connected to an A2DP device that supports absolute volume, 2718 * so that AudioService can send volume change events to the A2DP device, rather than handling 2719 * them. 2720 */ 2721 public void avrcpSupportsAbsoluteVolume(String address, boolean support) { 2722 IAudioService service = getService(); 2723 try { 2724 service.avrcpSupportsAbsoluteVolume(address, support); 2725 } catch (RemoteException e) { 2726 Log.e(TAG, "Dead object in avrcpSupportsAbsoluteVolume", e); 2727 } 2728 } 2729 2730 /** 2731 * {@hide} 2732 */ 2733 private final IBinder mICallBack = new Binder(); 2734 2735 /** 2736 * Checks whether the phone is in silent mode, with or without vibrate. 2737 * 2738 * @return true if phone is in silent mode, with or without vibrate. 2739 * 2740 * @see #getRingerMode() 2741 * 2742 * @hide pending API Council approval 2743 */ 2744 public boolean isSilentMode() { 2745 int ringerMode = getRingerMode(); 2746 boolean silentMode = 2747 (ringerMode == RINGER_MODE_SILENT) || 2748 (ringerMode == RINGER_MODE_VIBRATE); 2749 return silentMode; 2750 } 2751 2752 // This section re-defines new output device constants from AudioSystem, because the AudioSystem 2753 // class is not used by other parts of the framework, which instead use definitions and methods 2754 // from AudioManager. AudioSystem is an internal class used by AudioManager and AudioService. 2755 2756 /** @hide 2757 * The audio device code for representing "no device." */ 2758 public static final int DEVICE_NONE = AudioSystem.DEVICE_NONE; 2759 /** @hide 2760 * The audio output device code for the small speaker at the front of the device used 2761 * when placing calls. Does not refer to an in-ear headphone without attached microphone, 2762 * such as earbuds, earphones, or in-ear monitors (IEM). Those would be handled as a 2763 * {@link #DEVICE_OUT_WIRED_HEADPHONE}. 2764 */ 2765 public static final int DEVICE_OUT_EARPIECE = AudioSystem.DEVICE_OUT_EARPIECE; 2766 /** @hide 2767 * The audio output device code for the built-in speaker */ 2768 public static final int DEVICE_OUT_SPEAKER = AudioSystem.DEVICE_OUT_SPEAKER; 2769 /** @hide 2770 * The audio output device code for a wired headset with attached microphone */ 2771 public static final int DEVICE_OUT_WIRED_HEADSET = AudioSystem.DEVICE_OUT_WIRED_HEADSET; 2772 /** @hide 2773 * The audio output device code for a wired headphone without attached microphone */ 2774 public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE; 2775 /** @hide 2776 * The audio output device code for generic Bluetooth SCO, for voice */ 2777 public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; 2778 /** @hide 2779 * The audio output device code for Bluetooth SCO Headset Profile (HSP) and 2780 * Hands-Free Profile (HFP), for voice 2781 */ 2782 public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 2783 AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2784 /** @hide 2785 * The audio output device code for Bluetooth SCO car audio, for voice */ 2786 public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 2787 AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2788 /** @hide 2789 * The audio output device code for generic Bluetooth A2DP, for music */ 2790 public static final int DEVICE_OUT_BLUETOOTH_A2DP = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; 2791 /** @hide 2792 * The audio output device code for Bluetooth A2DP headphones, for music */ 2793 public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 2794 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2795 /** @hide 2796 * The audio output device code for Bluetooth A2DP external speaker, for music */ 2797 public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 2798 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2799 /** @hide 2800 * The audio output device code for S/PDIF (legacy) or HDMI 2801 * Deprecated: replaced by {@link #DEVICE_OUT_HDMI} */ 2802 public static final int DEVICE_OUT_AUX_DIGITAL = AudioSystem.DEVICE_OUT_AUX_DIGITAL; 2803 /** @hide 2804 * The audio output device code for HDMI */ 2805 public static final int DEVICE_OUT_HDMI = AudioSystem.DEVICE_OUT_HDMI; 2806 /** @hide 2807 * The audio output device code for an analog wired headset attached via a 2808 * docking station 2809 */ 2810 public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET; 2811 /** @hide 2812 * The audio output device code for a digital wired headset attached via a 2813 * docking station 2814 */ 2815 public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; 2816 /** @hide 2817 * The audio output device code for a USB audio accessory. The accessory is in USB host 2818 * mode and the Android device in USB device mode 2819 */ 2820 public static final int DEVICE_OUT_USB_ACCESSORY = AudioSystem.DEVICE_OUT_USB_ACCESSORY; 2821 /** @hide 2822 * The audio output device code for a USB audio device. The device is in USB device 2823 * mode and the Android device in USB host mode 2824 */ 2825 public static final int DEVICE_OUT_USB_DEVICE = AudioSystem.DEVICE_OUT_USB_DEVICE; 2826 /** @hide 2827 * The audio output device code for projection output. 2828 */ 2829 public static final int DEVICE_OUT_REMOTE_SUBMIX = AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 2830 /** @hide 2831 * The audio output device code the telephony voice TX path. 2832 */ 2833 public static final int DEVICE_OUT_TELEPHONY_TX = AudioSystem.DEVICE_OUT_TELEPHONY_TX; 2834 /** @hide 2835 * The audio output device code for an analog jack with line impedance detected. 2836 */ 2837 public static final int DEVICE_OUT_LINE = AudioSystem.DEVICE_OUT_LINE; 2838 /** @hide 2839 * The audio output device code for HDMI Audio Return Channel. 2840 */ 2841 public static final int DEVICE_OUT_HDMI_ARC = AudioSystem.DEVICE_OUT_HDMI_ARC; 2842 /** @hide 2843 * The audio output device code for S/PDIF digital connection. 2844 */ 2845 public static final int DEVICE_OUT_SPDIF = AudioSystem.DEVICE_OUT_SPDIF; 2846 /** @hide 2847 * The audio output device code for built-in FM transmitter. 2848 */ 2849 public static final int DEVICE_OUT_FM = AudioSystem.DEVICE_OUT_FM; 2850 /** @hide 2851 * This is not used as a returned value from {@link #getDevicesForStream}, but could be 2852 * used in the future in a set method to select whatever default device is chosen by the 2853 * platform-specific implementation. 2854 */ 2855 public static final int DEVICE_OUT_DEFAULT = AudioSystem.DEVICE_OUT_DEFAULT; 2856 2857 /** @hide 2858 * The audio input device code for default built-in microphone 2859 */ 2860 public static final int DEVICE_IN_BUILTIN_MIC = AudioSystem.DEVICE_IN_BUILTIN_MIC; 2861 /** @hide 2862 * The audio input device code for a Bluetooth SCO headset 2863 */ 2864 public static final int DEVICE_IN_BLUETOOTH_SCO_HEADSET = 2865 AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET; 2866 /** @hide 2867 * The audio input device code for wired headset microphone 2868 */ 2869 public static final int DEVICE_IN_WIRED_HEADSET = 2870 AudioSystem.DEVICE_IN_WIRED_HEADSET; 2871 /** @hide 2872 * The audio input device code for HDMI 2873 */ 2874 public static final int DEVICE_IN_HDMI = 2875 AudioSystem.DEVICE_IN_HDMI; 2876 /** @hide 2877 * The audio input device code for telephony voice RX path 2878 */ 2879 public static final int DEVICE_IN_TELEPHONY_RX = 2880 AudioSystem.DEVICE_IN_TELEPHONY_RX; 2881 /** @hide 2882 * The audio input device code for built-in microphone pointing to the back 2883 */ 2884 public static final int DEVICE_IN_BACK_MIC = 2885 AudioSystem.DEVICE_IN_BACK_MIC; 2886 /** @hide 2887 * The audio input device code for analog from a docking station 2888 */ 2889 public static final int DEVICE_IN_ANLG_DOCK_HEADSET = 2890 AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET; 2891 /** @hide 2892 * The audio input device code for digital from a docking station 2893 */ 2894 public static final int DEVICE_IN_DGTL_DOCK_HEADSET = 2895 AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET; 2896 /** @hide 2897 * The audio input device code for a USB audio accessory. The accessory is in USB host 2898 * mode and the Android device in USB device mode 2899 */ 2900 public static final int DEVICE_IN_USB_ACCESSORY = 2901 AudioSystem.DEVICE_IN_USB_ACCESSORY; 2902 /** @hide 2903 * The audio input device code for a USB audio device. The device is in USB device 2904 * mode and the Android device in USB host mode 2905 */ 2906 public static final int DEVICE_IN_USB_DEVICE = 2907 AudioSystem.DEVICE_IN_USB_DEVICE; 2908 /** @hide 2909 * The audio input device code for a FM radio tuner 2910 */ 2911 public static final int DEVICE_IN_FM_TUNER = AudioSystem.DEVICE_IN_FM_TUNER; 2912 /** @hide 2913 * The audio input device code for a TV tuner 2914 */ 2915 public static final int DEVICE_IN_TV_TUNER = AudioSystem.DEVICE_IN_TV_TUNER; 2916 /** @hide 2917 * The audio input device code for an analog jack with line impedance detected 2918 */ 2919 public static final int DEVICE_IN_LINE = AudioSystem.DEVICE_IN_LINE; 2920 /** @hide 2921 * The audio input device code for a S/PDIF digital connection 2922 */ 2923 public static final int DEVICE_IN_SPDIF = AudioSystem.DEVICE_IN_SPDIF; 2924 /** @hide 2925 * The audio input device code for audio loopback 2926 */ 2927 public static final int DEVICE_IN_LOOPBACK = AudioSystem.DEVICE_IN_LOOPBACK; 2928 2929 /** 2930 * Return true if the device code corresponds to an output device. 2931 * @hide 2932 */ 2933 public static boolean isOutputDevice(int device) 2934 { 2935 return (device & AudioSystem.DEVICE_BIT_IN) == 0; 2936 } 2937 2938 /** 2939 * Return true if the device code corresponds to an input device. 2940 * @hide 2941 */ 2942 public static boolean isInputDevice(int device) 2943 { 2944 return (device & AudioSystem.DEVICE_BIT_IN) == AudioSystem.DEVICE_BIT_IN; 2945 } 2946 2947 2948 /** 2949 * Return the enabled devices for the specified output stream type. 2950 * 2951 * @param streamType The stream type to query. One of 2952 * {@link #STREAM_VOICE_CALL}, 2953 * {@link #STREAM_SYSTEM}, 2954 * {@link #STREAM_RING}, 2955 * {@link #STREAM_MUSIC}, 2956 * {@link #STREAM_ALARM}, 2957 * {@link #STREAM_NOTIFICATION}, 2958 * {@link #STREAM_DTMF}. 2959 * 2960 * @return The bit-mask "or" of audio output device codes for all enabled devices on this 2961 * stream. Zero or more of 2962 * {@link #DEVICE_OUT_EARPIECE}, 2963 * {@link #DEVICE_OUT_SPEAKER}, 2964 * {@link #DEVICE_OUT_WIRED_HEADSET}, 2965 * {@link #DEVICE_OUT_WIRED_HEADPHONE}, 2966 * {@link #DEVICE_OUT_BLUETOOTH_SCO}, 2967 * {@link #DEVICE_OUT_BLUETOOTH_SCO_HEADSET}, 2968 * {@link #DEVICE_OUT_BLUETOOTH_SCO_CARKIT}, 2969 * {@link #DEVICE_OUT_BLUETOOTH_A2DP}, 2970 * {@link #DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES}, 2971 * {@link #DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER}, 2972 * {@link #DEVICE_OUT_HDMI}, 2973 * {@link #DEVICE_OUT_ANLG_DOCK_HEADSET}, 2974 * {@link #DEVICE_OUT_DGTL_DOCK_HEADSET}. 2975 * {@link #DEVICE_OUT_USB_ACCESSORY}. 2976 * {@link #DEVICE_OUT_USB_DEVICE}. 2977 * {@link #DEVICE_OUT_REMOTE_SUBMIX}. 2978 * {@link #DEVICE_OUT_TELEPHONY_TX}. 2979 * {@link #DEVICE_OUT_LINE}. 2980 * {@link #DEVICE_OUT_HDMI_ARC}. 2981 * {@link #DEVICE_OUT_SPDIF}. 2982 * {@link #DEVICE_OUT_FM}. 2983 * {@link #DEVICE_OUT_DEFAULT} is not used here. 2984 * 2985 * The implementation may support additional device codes beyond those listed, so 2986 * the application should ignore any bits which it does not recognize. 2987 * Note that the information may be imprecise when the implementation 2988 * cannot distinguish whether a particular device is enabled. 2989 * 2990 * {@hide} 2991 */ 2992 public int getDevicesForStream(int streamType) { 2993 switch (streamType) { 2994 case STREAM_VOICE_CALL: 2995 case STREAM_SYSTEM: 2996 case STREAM_RING: 2997 case STREAM_MUSIC: 2998 case STREAM_ALARM: 2999 case STREAM_NOTIFICATION: 3000 case STREAM_DTMF: 3001 return AudioSystem.getDevicesForStream(streamType); 3002 default: 3003 return 0; 3004 } 3005 } 3006 3007 /** 3008 * Indicate wired accessory connection state change. 3009 * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx) 3010 * @param state new connection state: 1 connected, 0 disconnected 3011 * @param name device name 3012 * {@hide} 3013 */ 3014 public void setWiredDeviceConnectionState(int device, int state, String name) { 3015 IAudioService service = getService(); 3016 try { 3017 service.setWiredDeviceConnectionState(device, state, name); 3018 } catch (RemoteException e) { 3019 Log.e(TAG, "Dead object in setWiredDeviceConnectionState "+e); 3020 } 3021 } 3022 3023 /** 3024 * Indicate A2DP source or sink connection state change. 3025 * @param device Bluetooth device connected/disconnected 3026 * @param state new connection state (BluetoothProfile.STATE_xxx) 3027 * @param profile profile for the A2DP device 3028 * (either {@link android.bluetooth.BluetoothProfile.A2DP} or 3029 * {@link android.bluetooth.BluetoothProfile.A2DP_SINK}) 3030 * @return a delay in ms that the caller should wait before broadcasting 3031 * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent. 3032 * {@hide} 3033 */ 3034 public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, 3035 int profile) { 3036 IAudioService service = getService(); 3037 int delay = 0; 3038 try { 3039 delay = service.setBluetoothA2dpDeviceConnectionState(device, state, profile); 3040 } catch (RemoteException e) { 3041 Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e); 3042 } finally { 3043 return delay; 3044 } 3045 } 3046 3047 /** {@hide} */ 3048 public IRingtonePlayer getRingtonePlayer() { 3049 try { 3050 return getService().getRingtonePlayer(); 3051 } catch (RemoteException e) { 3052 return null; 3053 } 3054 } 3055 3056 /** 3057 * Used as a key for {@link #getProperty} to request the native or optimal output sample rate 3058 * for this device's primary output stream, in decimal Hz. 3059 */ 3060 public static final String PROPERTY_OUTPUT_SAMPLE_RATE = 3061 "android.media.property.OUTPUT_SAMPLE_RATE"; 3062 3063 /** 3064 * Used as a key for {@link #getProperty} to request the native or optimal output buffer size 3065 * for this device's primary output stream, in decimal PCM frames. 3066 */ 3067 public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = 3068 "android.media.property.OUTPUT_FRAMES_PER_BUFFER"; 3069 3070 /** 3071 * Returns the value of the property with the specified key. 3072 * @param key One of the strings corresponding to a property key: either 3073 * {@link #PROPERTY_OUTPUT_SAMPLE_RATE} or 3074 * {@link #PROPERTY_OUTPUT_FRAMES_PER_BUFFER} 3075 * @return A string representing the associated value for that property key, 3076 * or null if there is no value for that key. 3077 */ 3078 public String getProperty(String key) { 3079 if (PROPERTY_OUTPUT_SAMPLE_RATE.equals(key)) { 3080 int outputSampleRate = AudioSystem.getPrimaryOutputSamplingRate(); 3081 return outputSampleRate > 0 ? Integer.toString(outputSampleRate) : null; 3082 } else if (PROPERTY_OUTPUT_FRAMES_PER_BUFFER.equals(key)) { 3083 int outputFramesPerBuffer = AudioSystem.getPrimaryOutputFrameCount(); 3084 return outputFramesPerBuffer > 0 ? Integer.toString(outputFramesPerBuffer) : null; 3085 } else { 3086 // null or unknown key 3087 return null; 3088 } 3089 } 3090 3091 /** 3092 * Returns the estimated latency for the given stream type in milliseconds. 3093 * 3094 * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need 3095 * a better solution. 3096 * @hide 3097 */ 3098 public int getOutputLatency(int streamType) { 3099 return AudioSystem.getOutputLatency(streamType); 3100 } 3101 3102 /** 3103 * Registers a global volume controller interface. Currently limited to SystemUI. 3104 * 3105 * @hide 3106 */ 3107 public void setVolumeController(IVolumeController controller) { 3108 try { 3109 getService().setVolumeController(controller); 3110 } catch (RemoteException e) { 3111 Log.w(TAG, "Error setting volume controller", e); 3112 } 3113 } 3114 3115 /** 3116 * Notify audio manager about volume controller visibility changes. 3117 * Currently limited to SystemUI. 3118 * 3119 * @hide 3120 */ 3121 public void notifyVolumeControllerVisible(IVolumeController controller, boolean visible) { 3122 try { 3123 getService().notifyVolumeControllerVisible(controller, visible); 3124 } catch (RemoteException e) { 3125 Log.w(TAG, "Error notifying about volume controller visibility", e); 3126 } 3127 } 3128 3129 /** 3130 * Only useful for volume controllers. 3131 * @hide 3132 */ 3133 public boolean isStreamAffectedByRingerMode(int streamType) { 3134 try { 3135 return getService().isStreamAffectedByRingerMode(streamType); 3136 } catch (RemoteException e) { 3137 Log.w(TAG, "Error calling isStreamAffectedByRingerMode", e); 3138 return false; 3139 } 3140 } 3141 3142 /** 3143 * Only useful for volume controllers. 3144 * @hide 3145 */ 3146 public void disableSafeMediaVolume() { 3147 try { 3148 getService().disableSafeMediaVolume(); 3149 } catch (RemoteException e) { 3150 Log.w(TAG, "Error disabling safe media volume", e); 3151 } 3152 } 3153 3154 /** 3155 * Set Hdmi Cec system audio mode. 3156 * 3157 * @param on whether to be on system audio mode 3158 * @return output device type. 0 (DEVICE_NONE) if failed to set device. 3159 * @hide 3160 */ 3161 public int setHdmiSystemAudioSupported(boolean on) { 3162 try { 3163 return getService().setHdmiSystemAudioSupported(on); 3164 } catch (RemoteException e) { 3165 Log.w(TAG, "Error setting system audio mode", e); 3166 return AudioSystem.DEVICE_NONE; 3167 } 3168 } 3169 3170 /** 3171 * Returns true if Hdmi Cec system audio mode is supported. 3172 * 3173 * @hide 3174 */ 3175 @SystemApi 3176 public boolean isHdmiSystemAudioSupported() { 3177 try { 3178 return getService().isHdmiSystemAudioSupported(); 3179 } catch (RemoteException e) { 3180 Log.w(TAG, "Error querying system audio mode", e); 3181 return false; 3182 } 3183 } 3184 3185 /** 3186 * Return codes for listAudioPorts(), createAudioPatch() ... 3187 */ 3188 3189 /** @hide 3190 * CANDIDATE FOR PUBLIC API 3191 */ 3192 public static final int SUCCESS = AudioSystem.SUCCESS; 3193 /** 3194 * A default error code. 3195 */ 3196 public static final int ERROR = AudioSystem.ERROR; 3197 /** @hide 3198 * CANDIDATE FOR PUBLIC API 3199 */ 3200 public static final int ERROR_BAD_VALUE = AudioSystem.BAD_VALUE; 3201 /** @hide 3202 */ 3203 public static final int ERROR_INVALID_OPERATION = AudioSystem.INVALID_OPERATION; 3204 /** @hide 3205 */ 3206 public static final int ERROR_PERMISSION_DENIED = AudioSystem.PERMISSION_DENIED; 3207 /** @hide 3208 */ 3209 public static final int ERROR_NO_INIT = AudioSystem.NO_INIT; 3210 /** 3211 * An error code indicating that the object reporting it is no longer valid and needs to 3212 * be recreated. 3213 */ 3214 public static final int ERROR_DEAD_OBJECT = AudioSystem.DEAD_OBJECT; 3215 3216 /** 3217 * Returns a list of descriptors for all audio ports managed by the audio framework. 3218 * Audio ports are nodes in the audio framework or audio hardware that can be configured 3219 * or connected and disconnected with createAudioPatch() or releaseAudioPatch(). 3220 * See AudioPort for a list of attributes of each audio port. 3221 * @param ports An AudioPort ArrayList where the list will be returned. 3222 * @hide 3223 */ 3224 public int listAudioPorts(ArrayList<AudioPort> ports) { 3225 return updateAudioPortCache(ports, null); 3226 } 3227 3228 /** 3229 * Specialized version of listAudioPorts() listing only audio devices (AudioDevicePort) 3230 * @see listAudioPorts(ArrayList<AudioPort>) 3231 * @hide 3232 */ 3233 public int listAudioDevicePorts(ArrayList<AudioPort> devices) { 3234 ArrayList<AudioPort> ports = new ArrayList<AudioPort>(); 3235 int status = updateAudioPortCache(ports, null); 3236 if (status == SUCCESS) { 3237 devices.clear(); 3238 for (int i = 0; i < ports.size(); i++) { 3239 if (ports.get(i) instanceof AudioDevicePort) { 3240 devices.add(ports.get(i)); 3241 } 3242 } 3243 } 3244 return status; 3245 } 3246 3247 /** 3248 * Create a connection between two or more devices. The framework will reject the request if 3249 * device types are not compatible or the implementation does not support the requested 3250 * configuration. 3251 * NOTE: current implementation is limited to one source and one sink per patch. 3252 * @param patch AudioPatch array where the newly created patch will be returned. 3253 * As input, if patch[0] is not null, the specified patch will be replaced by the 3254 * new patch created. This avoids calling releaseAudioPatch() when modifying a 3255 * patch and allows the implementation to optimize transitions. 3256 * @param sources List of source audio ports. All must be AudioPort.ROLE_SOURCE. 3257 * @param sinks List of sink audio ports. All must be AudioPort.ROLE_SINK. 3258 * 3259 * @return - {@link #SUCCESS} if connection is successful. 3260 * - {@link #ERROR_BAD_VALUE} if incompatible device types are passed. 3261 * - {@link #ERROR_INVALID_OPERATION} if the requested connection is not supported. 3262 * - {@link #ERROR_PERMISSION_DENIED} if the client does not have permission to create 3263 * a patch. 3264 * - {@link #ERROR_DEAD_OBJECT} if the server process is dead 3265 * - {@link #ERROR} if patch cannot be connected for any other reason. 3266 * 3267 * patch[0] contains the newly created patch 3268 * @hide 3269 */ 3270 public int createAudioPatch(AudioPatch[] patch, 3271 AudioPortConfig[] sources, 3272 AudioPortConfig[] sinks) { 3273 return AudioSystem.createAudioPatch(patch, sources, sinks); 3274 } 3275 3276 /** 3277 * Releases an existing audio patch connection. 3278 * @param patch The audio patch to disconnect. 3279 * @return - {@link #SUCCESS} if disconnection is successful. 3280 * - {@link #ERROR_BAD_VALUE} if the specified patch does not exist. 3281 * - {@link #ERROR_PERMISSION_DENIED} if the client does not have permission to release 3282 * a patch. 3283 * - {@link #ERROR_DEAD_OBJECT} if the server process is dead 3284 * - {@link #ERROR} if patch cannot be released for any other reason. 3285 * @hide 3286 */ 3287 public int releaseAudioPatch(AudioPatch patch) { 3288 return AudioSystem.releaseAudioPatch(patch); 3289 } 3290 3291 /** 3292 * List all existing connections between audio ports. 3293 * @param patches An AudioPatch array where the list will be returned. 3294 * @hide 3295 */ 3296 public int listAudioPatches(ArrayList<AudioPatch> patches) { 3297 return updateAudioPortCache(null, patches); 3298 } 3299 3300 /** 3301 * Set the gain on the specified AudioPort. The AudioGainConfig config is build by 3302 * AudioGain.buildConfig() 3303 * @hide 3304 */ 3305 public int setAudioPortGain(AudioPort port, AudioGainConfig gain) { 3306 if (port == null || gain == null) { 3307 return ERROR_BAD_VALUE; 3308 } 3309 AudioPortConfig activeConfig = port.activeConfig(); 3310 AudioPortConfig config = new AudioPortConfig(port, activeConfig.samplingRate(), 3311 activeConfig.channelMask(), activeConfig.format(), gain); 3312 config.mConfigMask = AudioPortConfig.GAIN; 3313 return AudioSystem.setAudioPortConfig(config); 3314 } 3315 3316 /** 3317 * Listener registered by client to be notified upon new audio port connections, 3318 * disconnections or attributes update. 3319 * @hide 3320 */ 3321 public interface OnAudioPortUpdateListener { 3322 /** 3323 * Callback method called upon audio port list update. 3324 * @param portList the updated list of audio ports 3325 */ 3326 public void onAudioPortListUpdate(AudioPort[] portList); 3327 3328 /** 3329 * Callback method called upon audio patch list update. 3330 * @param patchList the updated list of audio patches 3331 */ 3332 public void onAudioPatchListUpdate(AudioPatch[] patchList); 3333 3334 /** 3335 * Callback method called when the mediaserver dies 3336 */ 3337 public void onServiceDied(); 3338 } 3339 3340 /** 3341 * Register an audio port list update listener. 3342 * @hide 3343 */ 3344 public void registerAudioPortUpdateListener(OnAudioPortUpdateListener l) { 3345 mAudioPortEventHandler.registerListener(l); 3346 } 3347 3348 /** 3349 * Unregister an audio port list update listener. 3350 * @hide 3351 */ 3352 public void unregisterAudioPortUpdateListener(OnAudioPortUpdateListener l) { 3353 mAudioPortEventHandler.unregisterListener(l); 3354 } 3355 3356 // 3357 // AudioPort implementation 3358 // 3359 3360 static final int AUDIOPORT_GENERATION_INIT = 0; 3361 Integer mAudioPortGeneration = new Integer(AUDIOPORT_GENERATION_INIT); 3362 ArrayList<AudioPort> mAudioPortsCached = new ArrayList<AudioPort>(); 3363 ArrayList<AudioPatch> mAudioPatchesCached = new ArrayList<AudioPatch>(); 3364 3365 int resetAudioPortGeneration() { 3366 int generation; 3367 synchronized (mAudioPortGeneration) { 3368 generation = mAudioPortGeneration; 3369 mAudioPortGeneration = AUDIOPORT_GENERATION_INIT; 3370 } 3371 return generation; 3372 } 3373 3374 int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches) { 3375 synchronized (mAudioPortGeneration) { 3376 3377 if (mAudioPortGeneration == AUDIOPORT_GENERATION_INIT) { 3378 int[] patchGeneration = new int[1]; 3379 int[] portGeneration = new int[1]; 3380 int status; 3381 ArrayList<AudioPort> newPorts = new ArrayList<AudioPort>(); 3382 ArrayList<AudioPatch> newPatches = new ArrayList<AudioPatch>(); 3383 3384 do { 3385 newPorts.clear(); 3386 status = AudioSystem.listAudioPorts(newPorts, portGeneration); 3387 if (status != SUCCESS) { 3388 return status; 3389 } 3390 newPatches.clear(); 3391 status = AudioSystem.listAudioPatches(newPatches, patchGeneration); 3392 if (status != SUCCESS) { 3393 return status; 3394 } 3395 } while (patchGeneration[0] != portGeneration[0]); 3396 3397 for (int i = 0; i < newPatches.size(); i++) { 3398 for (int j = 0; j < newPatches.get(i).sources().length; j++) { 3399 AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sources()[j], 3400 newPorts); 3401 if (portCfg == null) { 3402 return ERROR; 3403 } 3404 newPatches.get(i).sources()[j] = portCfg; 3405 } 3406 for (int j = 0; j < newPatches.get(i).sinks().length; j++) { 3407 AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sinks()[j], 3408 newPorts); 3409 if (portCfg == null) { 3410 return ERROR; 3411 } 3412 newPatches.get(i).sinks()[j] = portCfg; 3413 } 3414 } 3415 3416 mAudioPortsCached = newPorts; 3417 mAudioPatchesCached = newPatches; 3418 mAudioPortGeneration = portGeneration[0]; 3419 } 3420 if (ports != null) { 3421 ports.clear(); 3422 ports.addAll(mAudioPortsCached); 3423 } 3424 if (patches != null) { 3425 patches.clear(); 3426 patches.addAll(mAudioPatchesCached); 3427 } 3428 } 3429 return SUCCESS; 3430 } 3431 3432 AudioPortConfig updatePortConfig(AudioPortConfig portCfg, ArrayList<AudioPort> ports) { 3433 AudioPort port = portCfg.port(); 3434 int k; 3435 for (k = 0; k < ports.size(); k++) { 3436 // compare handles because the port returned by JNI is not of the correct 3437 // subclass 3438 if (ports.get(k).handle().equals(port.handle())) { 3439 port = ports.get(k); 3440 break; 3441 } 3442 } 3443 if (k == ports.size()) { 3444 // this hould never happen 3445 Log.e(TAG, "updatePortConfig port not found for handle: "+port.handle().id()); 3446 return null; 3447 } 3448 AudioGainConfig gainCfg = portCfg.gain(); 3449 if (gainCfg != null) { 3450 AudioGain gain = port.gain(gainCfg.index()); 3451 gainCfg = gain.buildConfig(gainCfg.mode(), 3452 gainCfg.channelMask(), 3453 gainCfg.values(), 3454 gainCfg.rampDurationMs()); 3455 } 3456 return port.buildConfig(portCfg.samplingRate(), 3457 portCfg.channelMask(), 3458 portCfg.format(), 3459 gainCfg); 3460 } 3461 } 3462