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.annotation.SdkConstant; 20 import android.annotation.SdkConstant.SdkConstantType; 21 import android.app.PendingIntent; 22 import android.bluetooth.BluetoothDevice; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.os.Binder; 27 import android.os.Build; 28 import android.os.Handler; 29 import android.os.IBinder; 30 import android.os.Looper; 31 import android.os.Message; 32 import android.os.RemoteException; 33 import android.os.SystemClock; 34 import android.os.ServiceManager; 35 import android.provider.Settings; 36 import android.util.Log; 37 import android.view.KeyEvent; 38 import android.view.VolumePanel; 39 40 import java.util.HashMap; 41 42 /** 43 * AudioManager provides access to volume and ringer mode control. 44 * <p> 45 * Use <code>Context.getSystemService(Context.AUDIO_SERVICE)</code> to get 46 * an instance of this class. 47 */ 48 public class AudioManager { 49 50 private final Context mContext; 51 private long mVolumeKeyUpTime; 52 private final boolean mUseMasterVolume; 53 private final boolean mUseVolumeKeySounds; 54 private final Binder mToken = new Binder(); 55 private static String TAG = "AudioManager"; 56 57 /** 58 * Broadcast intent, a hint for applications that audio is about to become 59 * 'noisy' due to a change in audio outputs. For example, this intent may 60 * be sent when a wired headset is unplugged, or when an A2DP audio 61 * sink is disconnected, and the audio system is about to automatically 62 * switch audio route to the speaker. Applications that are controlling 63 * audio streams may consider pausing, reducing volume or some other action 64 * on receipt of this intent so as not to surprise the user with audio 65 * from the speaker. 66 */ 67 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 68 public static final String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY"; 69 70 /** 71 * Sticky broadcast intent action indicating that the ringer mode has 72 * changed. Includes the new ringer mode. 73 * 74 * @see #EXTRA_RINGER_MODE 75 */ 76 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 77 public static final String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED"; 78 79 /** 80 * The new ringer mode. 81 * 82 * @see #RINGER_MODE_CHANGED_ACTION 83 * @see #RINGER_MODE_NORMAL 84 * @see #RINGER_MODE_SILENT 85 * @see #RINGER_MODE_VIBRATE 86 */ 87 public static final String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE"; 88 89 /** 90 * Broadcast intent action indicating that the vibrate setting has 91 * changed. Includes the vibrate type and its new setting. 92 * 93 * @see #EXTRA_VIBRATE_TYPE 94 * @see #EXTRA_VIBRATE_SETTING 95 * @deprecated Applications should maintain their own vibrate policy based on 96 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 97 */ 98 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 99 public static final String VIBRATE_SETTING_CHANGED_ACTION = 100 "android.media.VIBRATE_SETTING_CHANGED"; 101 102 /** 103 * @hide Broadcast intent when the volume for a particular stream type changes. 104 * Includes the stream, the new volume and previous volumes. 105 * Notes: 106 * - for internal platform use only, do not make public, 107 * - never used for "remote" volume changes 108 * 109 * @see #EXTRA_VOLUME_STREAM_TYPE 110 * @see #EXTRA_VOLUME_STREAM_VALUE 111 * @see #EXTRA_PREV_VOLUME_STREAM_VALUE 112 */ 113 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 114 public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION"; 115 116 /** 117 * @hide Broadcast intent when the master volume changes. 118 * Includes the new volume 119 * 120 * @see #EXTRA_MASTER_VOLUME_VALUE 121 * @see #EXTRA_PREV_MASTER_VOLUME_VALUE 122 */ 123 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 124 public static final String MASTER_VOLUME_CHANGED_ACTION = 125 "android.media.MASTER_VOLUME_CHANGED_ACTION"; 126 127 /** 128 * @hide Broadcast intent when the master mute state changes. 129 * Includes the the new volume 130 * 131 * @see #EXTRA_MASTER_VOLUME_MUTED 132 */ 133 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 134 public static final String MASTER_MUTE_CHANGED_ACTION = 135 "android.media.MASTER_MUTE_CHANGED_ACTION"; 136 137 /** 138 * The new vibrate setting for a particular type. 139 * 140 * @see #VIBRATE_SETTING_CHANGED_ACTION 141 * @see #EXTRA_VIBRATE_TYPE 142 * @see #VIBRATE_SETTING_ON 143 * @see #VIBRATE_SETTING_OFF 144 * @see #VIBRATE_SETTING_ONLY_SILENT 145 * @deprecated Applications should maintain their own vibrate policy based on 146 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 147 */ 148 public static final String EXTRA_VIBRATE_SETTING = "android.media.EXTRA_VIBRATE_SETTING"; 149 150 /** 151 * The vibrate type whose setting has changed. 152 * 153 * @see #VIBRATE_SETTING_CHANGED_ACTION 154 * @see #VIBRATE_TYPE_NOTIFICATION 155 * @see #VIBRATE_TYPE_RINGER 156 * @deprecated Applications should maintain their own vibrate policy based on 157 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 158 */ 159 public static final String EXTRA_VIBRATE_TYPE = "android.media.EXTRA_VIBRATE_TYPE"; 160 161 /** 162 * @hide The stream type for the volume changed intent. 163 */ 164 public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE"; 165 166 /** 167 * @hide The volume associated with the stream for the volume changed intent. 168 */ 169 public static final String EXTRA_VOLUME_STREAM_VALUE = 170 "android.media.EXTRA_VOLUME_STREAM_VALUE"; 171 172 /** 173 * @hide The previous volume associated with the stream for the volume changed intent. 174 */ 175 public static final String EXTRA_PREV_VOLUME_STREAM_VALUE = 176 "android.media.EXTRA_PREV_VOLUME_STREAM_VALUE"; 177 178 /** 179 * @hide The new master volume value for the master volume changed intent. 180 * Value is integer between 0 and 100 inclusive. 181 */ 182 public static final String EXTRA_MASTER_VOLUME_VALUE = 183 "android.media.EXTRA_MASTER_VOLUME_VALUE"; 184 185 /** 186 * @hide The previous master volume value for the master volume changed intent. 187 * Value is integer between 0 and 100 inclusive. 188 */ 189 public static final String EXTRA_PREV_MASTER_VOLUME_VALUE = 190 "android.media.EXTRA_PREV_MASTER_VOLUME_VALUE"; 191 192 /** 193 * @hide The new master volume mute state for the master mute changed intent. 194 * Value is boolean 195 */ 196 public static final String EXTRA_MASTER_VOLUME_MUTED = 197 "android.media.EXTRA_MASTER_VOLUME_MUTED"; 198 199 /** The audio stream for phone calls */ 200 public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL; 201 /** The audio stream for system sounds */ 202 public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM; 203 /** The audio stream for the phone ring */ 204 public static final int STREAM_RING = AudioSystem.STREAM_RING; 205 /** The audio stream for music playback */ 206 public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC; 207 /** The audio stream for alarms */ 208 public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM; 209 /** The audio stream for notifications */ 210 public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION; 211 /** @hide The audio stream for phone calls when connected to bluetooth */ 212 public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO; 213 /** @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */ 214 public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED; 215 /** The audio stream for DTMF Tones */ 216 public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF; 217 /** @hide The audio stream for text to speech (TTS) */ 218 public static final int STREAM_TTS = AudioSystem.STREAM_TTS; 219 /** Number of audio streams */ 220 /** 221 * @deprecated Use AudioSystem.getNumStreamTypes() instead 222 */ 223 @Deprecated public static final int NUM_STREAMS = AudioSystem.NUM_STREAMS; 224 225 226 /** @hide Default volume index values for audio streams */ 227 public static final int[] DEFAULT_STREAM_VOLUME = new int[] { 228 4, // STREAM_VOICE_CALL 229 7, // STREAM_SYSTEM 230 5, // STREAM_RING 231 11, // STREAM_MUSIC 232 6, // STREAM_ALARM 233 5, // STREAM_NOTIFICATION 234 7, // STREAM_BLUETOOTH_SCO 235 7, // STREAM_SYSTEM_ENFORCED 236 11, // STREAM_DTMF 237 11 // STREAM_TTS 238 }; 239 240 /** 241 * Increase the ringer volume. 242 * 243 * @see #adjustVolume(int, int) 244 * @see #adjustStreamVolume(int, int, int) 245 */ 246 public static final int ADJUST_RAISE = 1; 247 248 /** 249 * Decrease the ringer volume. 250 * 251 * @see #adjustVolume(int, int) 252 * @see #adjustStreamVolume(int, int, int) 253 */ 254 public static final int ADJUST_LOWER = -1; 255 256 /** 257 * Maintain the previous ringer volume. This may be useful when needing to 258 * show the volume toast without actually modifying the volume. 259 * 260 * @see #adjustVolume(int, int) 261 * @see #adjustStreamVolume(int, int, int) 262 */ 263 public static final int ADJUST_SAME = 0; 264 265 // Flags should be powers of 2! 266 267 /** 268 * Show a toast containing the current volume. 269 * 270 * @see #adjustStreamVolume(int, int, int) 271 * @see #adjustVolume(int, int) 272 * @see #setStreamVolume(int, int, int) 273 * @see #setRingerMode(int) 274 */ 275 public static final int FLAG_SHOW_UI = 1 << 0; 276 277 /** 278 * Whether to include ringer modes as possible options when changing volume. 279 * For example, if true and volume level is 0 and the volume is adjusted 280 * with {@link #ADJUST_LOWER}, then the ringer mode may switch the silent or 281 * vibrate mode. 282 * <p> 283 * By default this is on for the ring stream. If this flag is included, 284 * this behavior will be present regardless of the stream type being 285 * affected by the ringer mode. 286 * 287 * @see #adjustVolume(int, int) 288 * @see #adjustStreamVolume(int, int, int) 289 */ 290 public static final int FLAG_ALLOW_RINGER_MODES = 1 << 1; 291 292 /** 293 * Whether to play a sound when changing the volume. 294 * <p> 295 * If this is given to {@link #adjustVolume(int, int)} or 296 * {@link #adjustSuggestedStreamVolume(int, int, int)}, it may be ignored 297 * in some cases (for example, the decided stream type is not 298 * {@link AudioManager#STREAM_RING}, or the volume is being adjusted 299 * downward). 300 * 301 * @see #adjustStreamVolume(int, int, int) 302 * @see #adjustVolume(int, int) 303 * @see #setStreamVolume(int, int, int) 304 */ 305 public static final int FLAG_PLAY_SOUND = 1 << 2; 306 307 /** 308 * Removes any sounds/vibrate that may be in the queue, or are playing (related to 309 * changing volume). 310 */ 311 public static final int FLAG_REMOVE_SOUND_AND_VIBRATE = 1 << 3; 312 313 /** 314 * Whether to vibrate if going into the vibrate ringer mode. 315 */ 316 public static final int FLAG_VIBRATE = 1 << 4; 317 318 /** 319 * Indicates to VolumePanel that the volume slider should be disabled as user 320 * cannot change the stream volume 321 * @hide 322 */ 323 public static final int FLAG_FIXED_VOLUME = 1 << 5; 324 325 /** 326 * Ringer mode that will be silent and will not vibrate. (This overrides the 327 * vibrate setting.) 328 * 329 * @see #setRingerMode(int) 330 * @see #getRingerMode() 331 */ 332 public static final int RINGER_MODE_SILENT = 0; 333 334 /** 335 * Ringer mode that will be silent and will vibrate. (This will cause the 336 * phone ringer to always vibrate, but the notification vibrate to only 337 * vibrate if set.) 338 * 339 * @see #setRingerMode(int) 340 * @see #getRingerMode() 341 */ 342 public static final int RINGER_MODE_VIBRATE = 1; 343 344 /** 345 * Ringer mode that may be audible and may vibrate. It will be audible if 346 * the volume before changing out of this mode was audible. It will vibrate 347 * if the vibrate setting is on. 348 * 349 * @see #setRingerMode(int) 350 * @see #getRingerMode() 351 */ 352 public static final int RINGER_MODE_NORMAL = 2; 353 354 // maximum valid ringer mode value. Values must start from 0 and be contiguous. 355 private static final int RINGER_MODE_MAX = RINGER_MODE_NORMAL; 356 357 /** 358 * Vibrate type that corresponds to the ringer. 359 * 360 * @see #setVibrateSetting(int, int) 361 * @see #getVibrateSetting(int) 362 * @see #shouldVibrate(int) 363 * @deprecated Applications should maintain their own vibrate policy based on 364 * current ringer mode that can be queried via {@link #getRingerMode()}. 365 */ 366 public static final int VIBRATE_TYPE_RINGER = 0; 367 368 /** 369 * Vibrate type that corresponds to notifications. 370 * 371 * @see #setVibrateSetting(int, int) 372 * @see #getVibrateSetting(int) 373 * @see #shouldVibrate(int) 374 * @deprecated Applications should maintain their own vibrate policy based on 375 * current ringer mode that can be queried via {@link #getRingerMode()}. 376 */ 377 public static final int VIBRATE_TYPE_NOTIFICATION = 1; 378 379 /** 380 * Vibrate setting that suggests to never vibrate. 381 * 382 * @see #setVibrateSetting(int, int) 383 * @see #getVibrateSetting(int) 384 * @deprecated Applications should maintain their own vibrate policy based on 385 * current ringer mode that can be queried via {@link #getRingerMode()}. 386 */ 387 public static final int VIBRATE_SETTING_OFF = 0; 388 389 /** 390 * Vibrate setting that suggests to vibrate when possible. 391 * 392 * @see #setVibrateSetting(int, int) 393 * @see #getVibrateSetting(int) 394 * @deprecated Applications should maintain their own vibrate policy based on 395 * current ringer mode that can be queried via {@link #getRingerMode()}. 396 */ 397 public static final int VIBRATE_SETTING_ON = 1; 398 399 /** 400 * Vibrate setting that suggests to only vibrate when in the vibrate ringer 401 * mode. 402 * 403 * @see #setVibrateSetting(int, int) 404 * @see #getVibrateSetting(int) 405 * @deprecated Applications should maintain their own vibrate policy based on 406 * current ringer mode that can be queried via {@link #getRingerMode()}. 407 */ 408 public static final int VIBRATE_SETTING_ONLY_SILENT = 2; 409 410 /** 411 * Suggests using the default stream type. This may not be used in all 412 * places a stream type is needed. 413 */ 414 public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE; 415 416 private static IAudioService sService; 417 418 /** 419 * @hide 420 */ AudioManager(Context context)421 public AudioManager(Context context) { 422 mContext = context; 423 mUseMasterVolume = mContext.getResources().getBoolean( 424 com.android.internal.R.bool.config_useMasterVolume); 425 mUseVolumeKeySounds = mContext.getResources().getBoolean( 426 com.android.internal.R.bool.config_useVolumeKeySounds); 427 } 428 getService()429 private static IAudioService getService() 430 { 431 if (sService != null) { 432 return sService; 433 } 434 IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); 435 sService = IAudioService.Stub.asInterface(b); 436 return sService; 437 } 438 439 /** 440 * @hide 441 */ preDispatchKeyEvent(KeyEvent event, int stream)442 public void preDispatchKeyEvent(KeyEvent event, int stream) { 443 /* 444 * If the user hits another key within the play sound delay, then 445 * cancel the sound 446 */ 447 int keyCode = event.getKeyCode(); 448 if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP 449 && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE 450 && mVolumeKeyUpTime + VolumePanel.PLAY_SOUND_DELAY 451 > SystemClock.uptimeMillis()) { 452 /* 453 * The user has hit another key during the delay (e.g., 300ms) 454 * since the last volume key up, so cancel any sounds. 455 */ 456 if (mUseMasterVolume) { 457 adjustMasterVolume(ADJUST_SAME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 458 } else { 459 adjustSuggestedStreamVolume(ADJUST_SAME, 460 stream, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 461 } 462 } 463 } 464 465 /** 466 * @hide 467 */ handleKeyDown(KeyEvent event, int stream)468 public void handleKeyDown(KeyEvent event, int stream) { 469 int keyCode = event.getKeyCode(); 470 switch (keyCode) { 471 case KeyEvent.KEYCODE_VOLUME_UP: 472 case KeyEvent.KEYCODE_VOLUME_DOWN: 473 /* 474 * Adjust the volume in on key down since it is more 475 * responsive to the user. 476 */ 477 int flags = FLAG_SHOW_UI | FLAG_VIBRATE; 478 479 if (mUseMasterVolume) { 480 adjustMasterVolume( 481 keyCode == KeyEvent.KEYCODE_VOLUME_UP 482 ? ADJUST_RAISE 483 : ADJUST_LOWER, 484 flags); 485 } else { 486 adjustSuggestedStreamVolume( 487 keyCode == KeyEvent.KEYCODE_VOLUME_UP 488 ? ADJUST_RAISE 489 : ADJUST_LOWER, 490 stream, 491 flags); 492 } 493 break; 494 case KeyEvent.KEYCODE_VOLUME_MUTE: 495 if (event.getRepeatCount() == 0) { 496 if (mUseMasterVolume) { 497 setMasterMute(!isMasterMute()); 498 } else { 499 // TODO: Actually handle MUTE. 500 } 501 } 502 break; 503 } 504 } 505 506 /** 507 * @hide 508 */ handleKeyUp(KeyEvent event, int stream)509 public void handleKeyUp(KeyEvent event, int stream) { 510 int keyCode = event.getKeyCode(); 511 switch (keyCode) { 512 case KeyEvent.KEYCODE_VOLUME_UP: 513 case KeyEvent.KEYCODE_VOLUME_DOWN: 514 /* 515 * Play a sound. This is done on key up since we don't want the 516 * sound to play when a user holds down volume down to mute. 517 */ 518 if (mUseVolumeKeySounds) { 519 if (mUseMasterVolume) { 520 adjustMasterVolume(ADJUST_SAME, FLAG_PLAY_SOUND); 521 } else { 522 int flags = FLAG_PLAY_SOUND; 523 adjustSuggestedStreamVolume( 524 ADJUST_SAME, 525 stream, 526 flags); 527 } 528 } 529 mVolumeKeyUpTime = SystemClock.uptimeMillis(); 530 break; 531 } 532 } 533 534 /** 535 * Adjusts the volume of a particular stream by one step in a direction. 536 * <p> 537 * This method should only be used by applications that replace the platform-wide 538 * management of audio settings or the main telephony application. 539 * 540 * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL}, 541 * {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC} or 542 * {@link #STREAM_ALARM} 543 * @param direction The direction to adjust the volume. One of 544 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 545 * {@link #ADJUST_SAME}. 546 * @param flags One or more flags. 547 * @see #adjustVolume(int, int) 548 * @see #setStreamVolume(int, int, int) 549 */ adjustStreamVolume(int streamType, int direction, int flags)550 public void adjustStreamVolume(int streamType, int direction, int flags) { 551 IAudioService service = getService(); 552 try { 553 if (mUseMasterVolume) { 554 service.adjustMasterVolume(direction, flags); 555 } else { 556 service.adjustStreamVolume(streamType, direction, flags); 557 } 558 } catch (RemoteException e) { 559 Log.e(TAG, "Dead object in adjustStreamVolume", e); 560 } 561 } 562 563 /** 564 * Adjusts the volume of the most relevant stream. For example, if a call is 565 * active, it will have the highest priority regardless of if the in-call 566 * screen is showing. Another example, if music is playing in the background 567 * and a call is not active, the music stream will be adjusted. 568 * <p> 569 * This method should only be used by applications that replace the platform-wide 570 * management of audio settings or the main telephony application. 571 * 572 * @param direction The direction to adjust the volume. One of 573 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 574 * {@link #ADJUST_SAME}. 575 * @param flags One or more flags. 576 * @see #adjustSuggestedStreamVolume(int, int, int) 577 * @see #adjustStreamVolume(int, int, int) 578 * @see #setStreamVolume(int, int, int) 579 */ adjustVolume(int direction, int flags)580 public void adjustVolume(int direction, int flags) { 581 IAudioService service = getService(); 582 try { 583 if (mUseMasterVolume) { 584 service.adjustMasterVolume(direction, flags); 585 } else { 586 service.adjustVolume(direction, flags); 587 } 588 } catch (RemoteException e) { 589 Log.e(TAG, "Dead object in adjustVolume", e); 590 } 591 } 592 593 /** 594 * Adjusts the volume of the most relevant stream, or the given fallback 595 * stream. 596 * <p> 597 * This method should only be used by applications that replace the platform-wide 598 * management of audio settings or the main telephony application. 599 * 600 * @param direction The direction to adjust the volume. One of 601 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 602 * {@link #ADJUST_SAME}. 603 * @param suggestedStreamType The stream type that will be used if there 604 * isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is valid here. 605 * @param flags One or more flags. 606 * @see #adjustVolume(int, int) 607 * @see #adjustStreamVolume(int, int, int) 608 * @see #setStreamVolume(int, int, int) 609 */ adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags)610 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) { 611 IAudioService service = getService(); 612 try { 613 if (mUseMasterVolume) { 614 service.adjustMasterVolume(direction, flags); 615 } else { 616 service.adjustSuggestedStreamVolume(direction, suggestedStreamType, flags); 617 } 618 } catch (RemoteException e) { 619 Log.e(TAG, "Dead object in adjustSuggestedStreamVolume", e); 620 } 621 } 622 623 /** 624 * Adjusts the master volume for the device's audio amplifier. 625 * <p> 626 * 627 * @param steps The number of volume steps to adjust. A positive 628 * value will raise the volume. 629 * @param flags One or more flags. 630 * @hide 631 */ adjustMasterVolume(int steps, int flags)632 public void adjustMasterVolume(int steps, int flags) { 633 IAudioService service = getService(); 634 try { 635 service.adjustMasterVolume(steps, flags); 636 } catch (RemoteException e) { 637 Log.e(TAG, "Dead object in adjustMasterVolume", e); 638 } 639 } 640 641 /** 642 * Returns the current ringtone mode. 643 * 644 * @return The current ringtone mode, one of {@link #RINGER_MODE_NORMAL}, 645 * {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}. 646 * @see #setRingerMode(int) 647 */ getRingerMode()648 public int getRingerMode() { 649 IAudioService service = getService(); 650 try { 651 return service.getRingerMode(); 652 } catch (RemoteException e) { 653 Log.e(TAG, "Dead object in getRingerMode", e); 654 return RINGER_MODE_NORMAL; 655 } 656 } 657 658 /** 659 * Checks valid ringer mode values. 660 * 661 * @return true if the ringer mode indicated is valid, false otherwise. 662 * 663 * @see #setRingerMode(int) 664 * @hide 665 */ isValidRingerMode(int ringerMode)666 public static boolean isValidRingerMode(int ringerMode) { 667 if (ringerMode < 0 || ringerMode > RINGER_MODE_MAX) { 668 return false; 669 } 670 return true; 671 } 672 673 /** 674 * Returns the maximum volume index for a particular stream. 675 * 676 * @param streamType The stream type whose maximum volume index is returned. 677 * @return The maximum valid volume index for the stream. 678 * @see #getStreamVolume(int) 679 */ getStreamMaxVolume(int streamType)680 public int getStreamMaxVolume(int streamType) { 681 IAudioService service = getService(); 682 try { 683 if (mUseMasterVolume) { 684 return service.getMasterMaxVolume(); 685 } else { 686 return service.getStreamMaxVolume(streamType); 687 } 688 } catch (RemoteException e) { 689 Log.e(TAG, "Dead object in getStreamMaxVolume", e); 690 return 0; 691 } 692 } 693 694 /** 695 * Returns the current volume index for a particular stream. 696 * 697 * @param streamType The stream type whose volume index is returned. 698 * @return The current volume index for the stream. 699 * @see #getStreamMaxVolume(int) 700 * @see #setStreamVolume(int, int, int) 701 */ getStreamVolume(int streamType)702 public int getStreamVolume(int streamType) { 703 IAudioService service = getService(); 704 try { 705 if (mUseMasterVolume) { 706 return service.getMasterVolume(); 707 } else { 708 return service.getStreamVolume(streamType); 709 } 710 } catch (RemoteException e) { 711 Log.e(TAG, "Dead object in getStreamVolume", e); 712 return 0; 713 } 714 } 715 716 /** 717 * Get last audible volume before stream was muted. 718 * 719 * @hide 720 */ getLastAudibleStreamVolume(int streamType)721 public int getLastAudibleStreamVolume(int streamType) { 722 IAudioService service = getService(); 723 try { 724 if (mUseMasterVolume) { 725 return service.getLastAudibleMasterVolume(); 726 } else { 727 return service.getLastAudibleStreamVolume(streamType); 728 } 729 } catch (RemoteException e) { 730 Log.e(TAG, "Dead object in getLastAudibleStreamVolume", e); 731 return 0; 732 } 733 } 734 735 /** 736 * Get the stream type whose volume is driving the UI sounds volume. 737 * UI sounds are screen lock/unlock, camera shutter, key clicks... 738 * @hide 739 */ getMasterStreamType()740 public int getMasterStreamType() { 741 IAudioService service = getService(); 742 try { 743 return service.getMasterStreamType(); 744 } catch (RemoteException e) { 745 Log.e(TAG, "Dead object in getMasterStreamType", e); 746 return STREAM_RING; 747 } 748 } 749 750 /** 751 * Sets the ringer mode. 752 * <p> 753 * Silent mode will mute the volume and will not vibrate. Vibrate mode will 754 * mute the volume and vibrate. Normal mode will be audible and may vibrate 755 * according to user settings. 756 * 757 * @param ringerMode The ringer mode, one of {@link #RINGER_MODE_NORMAL}, 758 * {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}. 759 * @see #getRingerMode() 760 */ setRingerMode(int ringerMode)761 public void setRingerMode(int ringerMode) { 762 if (!isValidRingerMode(ringerMode)) { 763 return; 764 } 765 IAudioService service = getService(); 766 try { 767 service.setRingerMode(ringerMode); 768 } catch (RemoteException e) { 769 Log.e(TAG, "Dead object in setRingerMode", e); 770 } 771 } 772 773 /** 774 * Sets the volume index for a particular stream. 775 * 776 * @param streamType The stream whose volume index should be set. 777 * @param index The volume index to set. See 778 * {@link #getStreamMaxVolume(int)} for the largest valid value. 779 * @param flags One or more flags. 780 * @see #getStreamMaxVolume(int) 781 * @see #getStreamVolume(int) 782 */ setStreamVolume(int streamType, int index, int flags)783 public void setStreamVolume(int streamType, int index, int flags) { 784 IAudioService service = getService(); 785 try { 786 if (mUseMasterVolume) { 787 service.setMasterVolume(index, flags); 788 } else { 789 service.setStreamVolume(streamType, index, flags); 790 } 791 } catch (RemoteException e) { 792 Log.e(TAG, "Dead object in setStreamVolume", e); 793 } 794 } 795 796 /** 797 * Returns the maximum volume index for master volume. 798 * 799 * @hide 800 */ getMasterMaxVolume()801 public int getMasterMaxVolume() { 802 IAudioService service = getService(); 803 try { 804 return service.getMasterMaxVolume(); 805 } catch (RemoteException e) { 806 Log.e(TAG, "Dead object in getMasterMaxVolume", e); 807 return 0; 808 } 809 } 810 811 /** 812 * Returns the current volume index for master volume. 813 * 814 * @return The current volume index for master volume. 815 * @hide 816 */ getMasterVolume()817 public int getMasterVolume() { 818 IAudioService service = getService(); 819 try { 820 return service.getMasterVolume(); 821 } catch (RemoteException e) { 822 Log.e(TAG, "Dead object in getMasterVolume", e); 823 return 0; 824 } 825 } 826 827 /** 828 * Get last audible volume before master volume was muted. 829 * 830 * @hide 831 */ getLastAudibleMasterVolume()832 public int getLastAudibleMasterVolume() { 833 IAudioService service = getService(); 834 try { 835 return service.getLastAudibleMasterVolume(); 836 } catch (RemoteException e) { 837 Log.e(TAG, "Dead object in getLastAudibleMasterVolume", e); 838 return 0; 839 } 840 } 841 842 /** 843 * Sets the volume index for master volume. 844 * 845 * @param index The volume index to set. See 846 * {@link #getMasterMaxVolume(int)} for the largest valid value. 847 * @param flags One or more flags. 848 * @see #getMasterMaxVolume(int) 849 * @see #getMasterVolume(int) 850 * @hide 851 */ setMasterVolume(int index, int flags)852 public void setMasterVolume(int index, int flags) { 853 IAudioService service = getService(); 854 try { 855 service.setMasterVolume(index, flags); 856 } catch (RemoteException e) { 857 Log.e(TAG, "Dead object in setMasterVolume", e); 858 } 859 } 860 861 /** 862 * Solo or unsolo a particular stream. All other streams are muted. 863 * <p> 864 * The solo command is protected against client process death: if a process 865 * with an active solo request on a stream dies, all streams that were muted 866 * because of this request will be unmuted automatically. 867 * <p> 868 * The solo requests for a given stream are cumulative: the AudioManager 869 * can receive several solo requests from one or more clients and the stream 870 * will be unsoloed only when the same number of unsolo requests are received. 871 * <p> 872 * For a better user experience, applications MUST unsolo a soloed stream 873 * in onPause() and solo is again in onResume() if appropriate. 874 * 875 * @param streamType The stream to be soloed/unsoloed. 876 * @param state The required solo state: true for solo ON, false for solo OFF 877 */ setStreamSolo(int streamType, boolean state)878 public void setStreamSolo(int streamType, boolean state) { 879 IAudioService service = getService(); 880 try { 881 service.setStreamSolo(streamType, state, mICallBack); 882 } catch (RemoteException e) { 883 Log.e(TAG, "Dead object in setStreamSolo", e); 884 } 885 } 886 887 /** 888 * Mute or unmute an audio stream. 889 * <p> 890 * The mute command is protected against client process death: if a process 891 * with an active mute request on a stream dies, this stream will be unmuted 892 * automatically. 893 * <p> 894 * The mute requests for a given stream are cumulative: the AudioManager 895 * can receive several mute requests from one or more clients and the stream 896 * will be unmuted only when the same number of unmute requests are received. 897 * <p> 898 * For a better user experience, applications MUST unmute a muted stream 899 * in onPause() and mute is again in onResume() if appropriate. 900 * <p> 901 * This method should only be used by applications that replace the platform-wide 902 * management of audio settings or the main telephony application. 903 * 904 * @param streamType The stream to be muted/unmuted. 905 * @param state The required mute state: true for mute ON, false for mute OFF 906 */ setStreamMute(int streamType, boolean state)907 public void setStreamMute(int streamType, boolean state) { 908 IAudioService service = getService(); 909 try { 910 service.setStreamMute(streamType, state, mICallBack); 911 } catch (RemoteException e) { 912 Log.e(TAG, "Dead object in setStreamMute", e); 913 } 914 } 915 916 /** 917 * get stream mute state. 918 * 919 * @hide 920 */ isStreamMute(int streamType)921 public boolean isStreamMute(int streamType) { 922 IAudioService service = getService(); 923 try { 924 return service.isStreamMute(streamType); 925 } catch (RemoteException e) { 926 Log.e(TAG, "Dead object in isStreamMute", e); 927 return false; 928 } 929 } 930 931 /** 932 * set master mute state. 933 * 934 * @hide 935 */ setMasterMute(boolean state)936 public void setMasterMute(boolean state) { 937 setMasterMute(state, FLAG_SHOW_UI); 938 } 939 940 /** 941 * set master mute state with optional flags. 942 * 943 * @hide 944 */ setMasterMute(boolean state, int flags)945 public void setMasterMute(boolean state, int flags) { 946 IAudioService service = getService(); 947 try { 948 service.setMasterMute(state, flags, mICallBack); 949 } catch (RemoteException e) { 950 Log.e(TAG, "Dead object in setMasterMute", e); 951 } 952 } 953 954 /** 955 * get master mute state. 956 * 957 * @hide 958 */ isMasterMute()959 public boolean isMasterMute() { 960 IAudioService service = getService(); 961 try { 962 return service.isMasterMute(); 963 } catch (RemoteException e) { 964 Log.e(TAG, "Dead object in isMasterMute", e); 965 return false; 966 } 967 } 968 969 /** 970 * forces the stream controlled by hard volume keys 971 * specifying streamType == -1 releases control to the 972 * logic. 973 * 974 * @hide 975 */ forceVolumeControlStream(int streamType)976 public void forceVolumeControlStream(int streamType) { 977 IAudioService service = getService(); 978 try { 979 service.forceVolumeControlStream(streamType, mICallBack); 980 } catch (RemoteException e) { 981 Log.e(TAG, "Dead object in forceVolumeControlStream", e); 982 } 983 } 984 985 /** 986 * Returns whether a particular type should vibrate according to user 987 * settings and the current ringer mode. 988 * <p> 989 * This shouldn't be needed by most clients that use notifications to 990 * vibrate. The notification manager will not vibrate if the policy doesn't 991 * allow it, so the client should always set a vibrate pattern and let the 992 * notification manager control whether or not to actually vibrate. 993 * 994 * @param vibrateType The type of vibrate. One of 995 * {@link #VIBRATE_TYPE_NOTIFICATION} or 996 * {@link #VIBRATE_TYPE_RINGER}. 997 * @return Whether the type should vibrate at the instant this method is 998 * called. 999 * @see #setVibrateSetting(int, int) 1000 * @see #getVibrateSetting(int) 1001 * @deprecated Applications should maintain their own vibrate policy based on 1002 * current ringer mode that can be queried via {@link #getRingerMode()}. 1003 */ shouldVibrate(int vibrateType)1004 public boolean shouldVibrate(int vibrateType) { 1005 IAudioService service = getService(); 1006 try { 1007 return service.shouldVibrate(vibrateType); 1008 } catch (RemoteException e) { 1009 Log.e(TAG, "Dead object in shouldVibrate", e); 1010 return false; 1011 } 1012 } 1013 1014 /** 1015 * Returns whether the user's vibrate setting for a vibrate type. 1016 * <p> 1017 * This shouldn't be needed by most clients that want to vibrate, instead 1018 * see {@link #shouldVibrate(int)}. 1019 * 1020 * @param vibrateType The type of vibrate. One of 1021 * {@link #VIBRATE_TYPE_NOTIFICATION} or 1022 * {@link #VIBRATE_TYPE_RINGER}. 1023 * @return The vibrate setting, one of {@link #VIBRATE_SETTING_ON}, 1024 * {@link #VIBRATE_SETTING_OFF}, or 1025 * {@link #VIBRATE_SETTING_ONLY_SILENT}. 1026 * @see #setVibrateSetting(int, int) 1027 * @see #shouldVibrate(int) 1028 * @deprecated Applications should maintain their own vibrate policy based on 1029 * current ringer mode that can be queried via {@link #getRingerMode()}. 1030 */ getVibrateSetting(int vibrateType)1031 public int getVibrateSetting(int vibrateType) { 1032 IAudioService service = getService(); 1033 try { 1034 return service.getVibrateSetting(vibrateType); 1035 } catch (RemoteException e) { 1036 Log.e(TAG, "Dead object in getVibrateSetting", e); 1037 return VIBRATE_SETTING_OFF; 1038 } 1039 } 1040 1041 /** 1042 * Sets the setting for when the vibrate type should vibrate. 1043 * <p> 1044 * This method should only be used by applications that replace the platform-wide 1045 * management of audio settings or the main telephony application. 1046 * 1047 * @param vibrateType The type of vibrate. One of 1048 * {@link #VIBRATE_TYPE_NOTIFICATION} or 1049 * {@link #VIBRATE_TYPE_RINGER}. 1050 * @param vibrateSetting The vibrate setting, one of 1051 * {@link #VIBRATE_SETTING_ON}, 1052 * {@link #VIBRATE_SETTING_OFF}, or 1053 * {@link #VIBRATE_SETTING_ONLY_SILENT}. 1054 * @see #getVibrateSetting(int) 1055 * @see #shouldVibrate(int) 1056 * @deprecated Applications should maintain their own vibrate policy based on 1057 * current ringer mode that can be queried via {@link #getRingerMode()}. 1058 */ setVibrateSetting(int vibrateType, int vibrateSetting)1059 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 1060 IAudioService service = getService(); 1061 try { 1062 service.setVibrateSetting(vibrateType, vibrateSetting); 1063 } catch (RemoteException e) { 1064 Log.e(TAG, "Dead object in setVibrateSetting", e); 1065 } 1066 } 1067 1068 /** 1069 * Sets the speakerphone on or off. 1070 * <p> 1071 * This method should only be used by applications that replace the platform-wide 1072 * management of audio settings or the main telephony application. 1073 * 1074 * @param on set <var>true</var> to turn on speakerphone; 1075 * <var>false</var> to turn it off 1076 */ setSpeakerphoneOn(boolean on)1077 public void setSpeakerphoneOn(boolean on){ 1078 IAudioService service = getService(); 1079 try { 1080 service.setSpeakerphoneOn(on); 1081 } catch (RemoteException e) { 1082 Log.e(TAG, "Dead object in setSpeakerphoneOn", e); 1083 } 1084 } 1085 1086 /** 1087 * Checks whether the speakerphone is on or off. 1088 * 1089 * @return true if speakerphone is on, false if it's off 1090 */ isSpeakerphoneOn()1091 public boolean isSpeakerphoneOn() { 1092 IAudioService service = getService(); 1093 try { 1094 return service.isSpeakerphoneOn(); 1095 } catch (RemoteException e) { 1096 Log.e(TAG, "Dead object in isSpeakerphoneOn", e); 1097 return false; 1098 } 1099 } 1100 1101 //==================================================================== 1102 // Bluetooth SCO control 1103 /** 1104 * Sticky broadcast intent action indicating that the bluetoooth SCO audio 1105 * connection state has changed. The intent contains on extra {@link #EXTRA_SCO_AUDIO_STATE} 1106 * indicating the new state which is either {@link #SCO_AUDIO_STATE_DISCONNECTED} 1107 * or {@link #SCO_AUDIO_STATE_CONNECTED} 1108 * 1109 * @see #startBluetoothSco() 1110 * @deprecated Use {@link #ACTION_SCO_AUDIO_STATE_UPDATED} instead 1111 */ 1112 @Deprecated 1113 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1114 public static final String ACTION_SCO_AUDIO_STATE_CHANGED = 1115 "android.media.SCO_AUDIO_STATE_CHANGED"; 1116 1117 /** 1118 * Sticky broadcast intent action indicating that the bluetoooth SCO audio 1119 * connection state has been updated. 1120 * <p>This intent has two extras: 1121 * <ul> 1122 * <li> {@link #EXTRA_SCO_AUDIO_STATE} - The new SCO audio state. </li> 1123 * <li> {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE}- The previous SCO audio state. </li> 1124 * </ul> 1125 * <p> EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE can be any of: 1126 * <ul> 1127 * <li> {@link #SCO_AUDIO_STATE_DISCONNECTED}, </li> 1128 * <li> {@link #SCO_AUDIO_STATE_CONNECTING} or </li> 1129 * <li> {@link #SCO_AUDIO_STATE_CONNECTED}, </li> 1130 * </ul> 1131 * @see #startBluetoothSco() 1132 */ 1133 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1134 public static final String ACTION_SCO_AUDIO_STATE_UPDATED = 1135 "android.media.ACTION_SCO_AUDIO_STATE_UPDATED"; 1136 1137 /** 1138 * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_CHANGED} or 1139 * {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the new bluetooth SCO connection state. 1140 */ 1141 public static final String EXTRA_SCO_AUDIO_STATE = 1142 "android.media.extra.SCO_AUDIO_STATE"; 1143 1144 /** 1145 * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the previous 1146 * bluetooth SCO connection state. 1147 */ 1148 public static final String EXTRA_SCO_AUDIO_PREVIOUS_STATE = 1149 "android.media.extra.SCO_AUDIO_PREVIOUS_STATE"; 1150 1151 /** 1152 * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE 1153 * indicating that the SCO audio channel is not established 1154 */ 1155 public static final int SCO_AUDIO_STATE_DISCONNECTED = 0; 1156 /** 1157 * Value for extra {@link #EXTRA_SCO_AUDIO_STATE} or {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE} 1158 * indicating that the SCO audio channel is established 1159 */ 1160 public static final int SCO_AUDIO_STATE_CONNECTED = 1; 1161 /** 1162 * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE 1163 * indicating that the SCO audio channel is being established 1164 */ 1165 public static final int SCO_AUDIO_STATE_CONNECTING = 2; 1166 /** 1167 * Value for extra EXTRA_SCO_AUDIO_STATE indicating that 1168 * there was an error trying to obtain the state 1169 */ 1170 public static final int SCO_AUDIO_STATE_ERROR = -1; 1171 1172 1173 /** 1174 * Indicates if current platform supports use of SCO for off call use cases. 1175 * Application wanted to use bluetooth SCO audio when the phone is not in call 1176 * must first call this method to make sure that the platform supports this 1177 * feature. 1178 * @return true if bluetooth SCO can be used for audio when not in call 1179 * false otherwise 1180 * @see #startBluetoothSco() 1181 */ isBluetoothScoAvailableOffCall()1182 public boolean isBluetoothScoAvailableOffCall() { 1183 return mContext.getResources().getBoolean( 1184 com.android.internal.R.bool.config_bluetooth_sco_off_call); 1185 } 1186 1187 /** 1188 * Start bluetooth SCO audio connection. 1189 * <p>Requires Permission: 1190 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1191 * <p>This method can be used by applications wanting to send and received audio 1192 * to/from a bluetooth SCO headset while the phone is not in call. 1193 * <p>As the SCO connection establishment can take several seconds, 1194 * applications should not rely on the connection to be available when the method 1195 * returns but instead register to receive the intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} 1196 * and wait for the state to be {@link #SCO_AUDIO_STATE_CONNECTED}. 1197 * <p>As the ACTION_SCO_AUDIO_STATE_UPDATED intent is sticky, the application can check the SCO 1198 * audio state before calling startBluetoothSco() by reading the intent returned by the receiver 1199 * registration. If the state is already CONNECTED, no state change will be received via the 1200 * intent after calling startBluetoothSco(). It is however useful to call startBluetoothSco() 1201 * so that the connection stays active in case the current initiator stops the connection. 1202 * <p>Unless the connection is already active as described above, the state will always 1203 * transition from DISCONNECTED to CONNECTING and then either to CONNECTED if the connection 1204 * succeeds or back to DISCONNECTED if the connection fails (e.g no headset is connected). 1205 * <p>When finished with the SCO connection or if the establishment fails, the application must 1206 * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection. 1207 * <p>Even if a SCO connection is established, the following restrictions apply on audio 1208 * output streams so that they can be routed to SCO headset: 1209 * <p>NOTE: up to and including API version 1210 * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual 1211 * voice call to the bluetooth headset. 1212 * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio 1213 * connection is established. 1214 * <ul> 1215 * <li> the stream type must be {@link #STREAM_VOICE_CALL} </li> 1216 * <li> the format must be mono </li> 1217 * <li> the sampling must be 16kHz or 8kHz </li> 1218 * </ul> 1219 * <p>The following restrictions apply on input streams: 1220 * <ul> 1221 * <li> the format must be mono </li> 1222 * <li> the sampling must be 8kHz </li> 1223 * </ul> 1224 * <p>Note that the phone application always has the priority on the usage of the SCO 1225 * connection for telephony. If this method is called while the phone is in call 1226 * it will be ignored. Similarly, if a call is received or sent while an application 1227 * is using the SCO connection, the connection will be lost for the application and NOT 1228 * returned automatically when the call ends. 1229 * @see #stopBluetoothSco() 1230 * @see #ACTION_SCO_AUDIO_STATE_UPDATED 1231 */ startBluetoothSco()1232 public void startBluetoothSco(){ 1233 IAudioService service = getService(); 1234 try { 1235 service.startBluetoothSco(mICallBack, mContext.getApplicationInfo().targetSdkVersion); 1236 } catch (RemoteException e) { 1237 Log.e(TAG, "Dead object in startBluetoothSco", e); 1238 } 1239 } 1240 1241 /** 1242 * Stop bluetooth SCO audio connection. 1243 * <p>Requires Permission: 1244 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1245 * <p>This method must be called by applications having requested the use of 1246 * bluetooth SCO audio with {@link #startBluetoothSco()} 1247 * when finished with the SCO connection or if connection fails. 1248 * @see #startBluetoothSco() 1249 */ stopBluetoothSco()1250 public void stopBluetoothSco(){ 1251 IAudioService service = getService(); 1252 try { 1253 service.stopBluetoothSco(mICallBack); 1254 } catch (RemoteException e) { 1255 Log.e(TAG, "Dead object in stopBluetoothSco", e); 1256 } 1257 } 1258 1259 /** 1260 * Request use of Bluetooth SCO headset for communications. 1261 * <p> 1262 * This method should only be used by applications that replace the platform-wide 1263 * management of audio settings or the main telephony application. 1264 * 1265 * @param on set <var>true</var> to use bluetooth SCO for communications; 1266 * <var>false</var> to not use bluetooth SCO for communications 1267 */ setBluetoothScoOn(boolean on)1268 public void setBluetoothScoOn(boolean on){ 1269 IAudioService service = getService(); 1270 try { 1271 service.setBluetoothScoOn(on); 1272 } catch (RemoteException e) { 1273 Log.e(TAG, "Dead object in setBluetoothScoOn", e); 1274 } 1275 } 1276 1277 /** 1278 * Checks whether communications use Bluetooth SCO. 1279 * 1280 * @return true if SCO is used for communications; 1281 * false if otherwise 1282 */ isBluetoothScoOn()1283 public boolean isBluetoothScoOn() { 1284 IAudioService service = getService(); 1285 try { 1286 return service.isBluetoothScoOn(); 1287 } catch (RemoteException e) { 1288 Log.e(TAG, "Dead object in isBluetoothScoOn", e); 1289 return false; 1290 } 1291 } 1292 1293 /** 1294 * @param on set <var>true</var> to route A2DP audio to/from Bluetooth 1295 * headset; <var>false</var> disable A2DP audio 1296 * @deprecated Do not use. 1297 */ setBluetoothA2dpOn(boolean on)1298 @Deprecated public void setBluetoothA2dpOn(boolean on){ 1299 } 1300 1301 /** 1302 * Checks whether A2DP audio routing to the Bluetooth headset is on or off. 1303 * 1304 * @return true if A2DP audio is being routed to/from Bluetooth headset; 1305 * false if otherwise 1306 */ isBluetoothA2dpOn()1307 public boolean isBluetoothA2dpOn() { 1308 if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"") 1309 == AudioSystem.DEVICE_STATE_UNAVAILABLE) { 1310 return false; 1311 } else { 1312 return true; 1313 } 1314 } 1315 1316 /** 1317 * @hide 1318 * Signals whether remote submix audio rerouting is enabled. 1319 */ setRemoteSubmixOn(boolean on, int address)1320 public void setRemoteSubmixOn(boolean on, int address) { 1321 IAudioService service = getService(); 1322 try { 1323 service.setRemoteSubmixOn(on, address); 1324 } catch (RemoteException e) { 1325 Log.e(TAG, "Dead object in setRemoteSubmixOn", e); 1326 } 1327 } 1328 1329 /** 1330 * Sets audio routing to the wired headset on or off. 1331 * 1332 * @param on set <var>true</var> to route audio to/from wired 1333 * headset; <var>false</var> disable wired headset audio 1334 * @deprecated Do not use. 1335 */ setWiredHeadsetOn(boolean on)1336 @Deprecated public void setWiredHeadsetOn(boolean on){ 1337 } 1338 1339 /** 1340 * Checks whether a wired headset is connected or not. 1341 * <p>This is not a valid indication that audio playback is 1342 * actually over the wired headset as audio routing depends on other conditions. 1343 * 1344 * @return true if a wired headset is connected. 1345 * false if otherwise 1346 * @deprecated Use only to check is a headset is connected or not. 1347 */ isWiredHeadsetOn()1348 public boolean isWiredHeadsetOn() { 1349 if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"") 1350 == AudioSystem.DEVICE_STATE_UNAVAILABLE && 1351 AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"") 1352 == AudioSystem.DEVICE_STATE_UNAVAILABLE) { 1353 return false; 1354 } else { 1355 return true; 1356 } 1357 } 1358 1359 /** 1360 * Sets the microphone mute on or off. 1361 * <p> 1362 * This method should only be used by applications that replace the platform-wide 1363 * management of audio settings or the main telephony application. 1364 * 1365 * @param on set <var>true</var> to mute the microphone; 1366 * <var>false</var> to turn mute off 1367 */ setMicrophoneMute(boolean on)1368 public void setMicrophoneMute(boolean on){ 1369 AudioSystem.muteMicrophone(on); 1370 } 1371 1372 /** 1373 * Checks whether the microphone mute is on or off. 1374 * 1375 * @return true if microphone is muted, false if it's not 1376 */ isMicrophoneMute()1377 public boolean isMicrophoneMute() { 1378 return AudioSystem.isMicrophoneMuted(); 1379 } 1380 1381 /** 1382 * Sets the audio mode. 1383 * <p> 1384 * The audio mode encompasses audio routing AND the behavior of 1385 * the telephony layer. Therefore this method should only be used by applications that 1386 * replace the platform-wide management of audio settings or the main telephony application. 1387 * In particular, the {@link #MODE_IN_CALL} mode should only be used by the telephony 1388 * application when it places a phone call, as it will cause signals from the radio layer 1389 * to feed the platform mixer. 1390 * 1391 * @param mode the requested audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, 1392 * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). 1393 * Informs the HAL about the current audio state so that 1394 * it can route the audio appropriately. 1395 */ setMode(int mode)1396 public void setMode(int mode) { 1397 IAudioService service = getService(); 1398 try { 1399 service.setMode(mode, mICallBack); 1400 } catch (RemoteException e) { 1401 Log.e(TAG, "Dead object in setMode", e); 1402 } 1403 } 1404 1405 /** 1406 * Returns the current audio mode. 1407 * 1408 * @return the current audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, 1409 * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). 1410 * Returns the current current audio state from the HAL. 1411 */ getMode()1412 public int getMode() { 1413 IAudioService service = getService(); 1414 try { 1415 return service.getMode(); 1416 } catch (RemoteException e) { 1417 Log.e(TAG, "Dead object in getMode", e); 1418 return MODE_INVALID; 1419 } 1420 } 1421 1422 /* modes for setMode/getMode/setRoute/getRoute */ 1423 /** 1424 * Audio harware modes. 1425 */ 1426 /** 1427 * Invalid audio mode. 1428 */ 1429 public static final int MODE_INVALID = AudioSystem.MODE_INVALID; 1430 /** 1431 * Current audio mode. Used to apply audio routing to current mode. 1432 */ 1433 public static final int MODE_CURRENT = AudioSystem.MODE_CURRENT; 1434 /** 1435 * Normal audio mode: not ringing and no call established. 1436 */ 1437 public static final int MODE_NORMAL = AudioSystem.MODE_NORMAL; 1438 /** 1439 * Ringing audio mode. An incoming is being signaled. 1440 */ 1441 public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE; 1442 /** 1443 * In call audio mode. A telephony call is established. 1444 */ 1445 public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL; 1446 /** 1447 * In communication audio mode. An audio/video chat or VoIP call is established. 1448 */ 1449 public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION; 1450 1451 /* Routing bits for setRouting/getRouting API */ 1452 /** 1453 * Routing audio output to earpiece 1454 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1455 * setBluetoothScoOn() methods instead. 1456 */ 1457 @Deprecated public static final int ROUTE_EARPIECE = AudioSystem.ROUTE_EARPIECE; 1458 /** 1459 * Routing audio output to speaker 1460 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1461 * setBluetoothScoOn() methods instead. 1462 */ 1463 @Deprecated public static final int ROUTE_SPEAKER = AudioSystem.ROUTE_SPEAKER; 1464 /** 1465 * @deprecated use {@link #ROUTE_BLUETOOTH_SCO} 1466 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1467 * setBluetoothScoOn() methods instead. 1468 */ 1469 @Deprecated public static final int ROUTE_BLUETOOTH = AudioSystem.ROUTE_BLUETOOTH_SCO; 1470 /** 1471 * Routing audio output to bluetooth SCO 1472 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1473 * setBluetoothScoOn() methods instead. 1474 */ 1475 @Deprecated public static final int ROUTE_BLUETOOTH_SCO = AudioSystem.ROUTE_BLUETOOTH_SCO; 1476 /** 1477 * Routing audio output to headset 1478 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1479 * setBluetoothScoOn() methods instead. 1480 */ 1481 @Deprecated public static final int ROUTE_HEADSET = AudioSystem.ROUTE_HEADSET; 1482 /** 1483 * Routing audio output to bluetooth A2DP 1484 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1485 * setBluetoothScoOn() methods instead. 1486 */ 1487 @Deprecated public static final int ROUTE_BLUETOOTH_A2DP = AudioSystem.ROUTE_BLUETOOTH_A2DP; 1488 /** 1489 * Used for mask parameter of {@link #setRouting(int,int,int)}. 1490 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1491 * setBluetoothScoOn() methods instead. 1492 */ 1493 @Deprecated public static final int ROUTE_ALL = AudioSystem.ROUTE_ALL; 1494 1495 /** 1496 * Sets the audio routing for a specified mode 1497 * 1498 * @param mode audio mode to change route. E.g., MODE_RINGTONE. 1499 * @param routes bit vector of routes requested, created from one or 1500 * more of ROUTE_xxx types. Set bits indicate that route should be on 1501 * @param mask bit vector of routes to change, created from one or more of 1502 * ROUTE_xxx types. Unset bits indicate the route should be left unchanged 1503 * 1504 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1505 * setBluetoothScoOn() methods instead. 1506 */ 1507 @Deprecated setRouting(int mode, int routes, int mask)1508 public void setRouting(int mode, int routes, int mask) { 1509 } 1510 1511 /** 1512 * Returns the current audio routing bit vector for a specified mode. 1513 * 1514 * @param mode audio mode to get route (e.g., MODE_RINGTONE) 1515 * @return an audio route bit vector that can be compared with ROUTE_xxx 1516 * bits 1517 * @deprecated Do not query audio routing directly, use isSpeakerphoneOn(), 1518 * isBluetoothScoOn(), isBluetoothA2dpOn() and isWiredHeadsetOn() methods instead. 1519 */ 1520 @Deprecated getRouting(int mode)1521 public int getRouting(int mode) { 1522 return -1; 1523 } 1524 1525 /** 1526 * Checks whether any music is active. 1527 * 1528 * @return true if any music tracks are active. 1529 */ isMusicActive()1530 public boolean isMusicActive() { 1531 return AudioSystem.isStreamActive(STREAM_MUSIC, 0); 1532 } 1533 1534 /** 1535 * @hide 1536 * Checks whether any music or media is actively playing on a remote device (e.g. wireless 1537 * display). Note that BT audio sinks are not considered remote devices. 1538 * @return true if {@link AudioManager#STREAM_MUSIC} is active on a remote device 1539 */ isMusicActiveRemotely()1540 public boolean isMusicActiveRemotely() { 1541 return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0); 1542 } 1543 1544 /** 1545 * @hide 1546 * Checks whether speech recognition is active 1547 * @return true if a recording with source {@link MediaRecorder.AudioSource#VOICE_RECOGNITION} 1548 * is underway. 1549 */ isSpeechRecognitionActive()1550 public boolean isSpeechRecognitionActive() { 1551 return AudioSystem.isSourceActive(MediaRecorder.AudioSource.VOICE_RECOGNITION); 1552 } 1553 1554 /** 1555 * @hide 1556 * If the stream is active locally or remotely, adjust its volume according to the enforced 1557 * priority rules. 1558 * Note: only AudioManager.STREAM_MUSIC is supported at the moment 1559 */ adjustLocalOrRemoteStreamVolume(int streamType, int direction)1560 public void adjustLocalOrRemoteStreamVolume(int streamType, int direction) { 1561 if (streamType != STREAM_MUSIC) { 1562 Log.w(TAG, "adjustLocalOrRemoteStreamVolume() doesn't support stream " + streamType); 1563 } 1564 IAudioService service = getService(); 1565 try { 1566 service.adjustLocalOrRemoteStreamVolume(streamType, direction); 1567 } catch (RemoteException e) { 1568 Log.e(TAG, "Dead object in adjustLocalOrRemoteStreamVolume", e); 1569 } 1570 } 1571 1572 /* 1573 * Sets a generic audio configuration parameter. The use of these parameters 1574 * are platform dependant, see libaudio 1575 * 1576 * ** Temporary interface - DO NOT USE 1577 * 1578 * TODO: Replace with a more generic key:value get/set mechanism 1579 * 1580 * param key name of parameter to set. Must not be null. 1581 * param value value of parameter. Must not be null. 1582 */ 1583 /** 1584 * @hide 1585 * @deprecated Use {@link #setPrameters(String)} instead 1586 */ setParameter(String key, String value)1587 @Deprecated public void setParameter(String key, String value) { 1588 setParameters(key+"="+value); 1589 } 1590 1591 /** 1592 * Sets a variable number of parameter values to audio hardware. 1593 * 1594 * @param keyValuePairs list of parameters key value pairs in the form: 1595 * key1=value1;key2=value2;... 1596 * 1597 */ setParameters(String keyValuePairs)1598 public void setParameters(String keyValuePairs) { 1599 AudioSystem.setParameters(keyValuePairs); 1600 } 1601 1602 /** 1603 * Gets a variable number of parameter values from audio hardware. 1604 * 1605 * @param keys list of parameters 1606 * @return list of parameters key value pairs in the form: 1607 * key1=value1;key2=value2;... 1608 */ getParameters(String keys)1609 public String getParameters(String keys) { 1610 return AudioSystem.getParameters(keys); 1611 } 1612 1613 /* Sound effect identifiers */ 1614 /** 1615 * Keyboard and direction pad click sound 1616 * @see #playSoundEffect(int) 1617 */ 1618 public static final int FX_KEY_CLICK = 0; 1619 /** 1620 * Focus has moved up 1621 * @see #playSoundEffect(int) 1622 */ 1623 public static final int FX_FOCUS_NAVIGATION_UP = 1; 1624 /** 1625 * Focus has moved down 1626 * @see #playSoundEffect(int) 1627 */ 1628 public static final int FX_FOCUS_NAVIGATION_DOWN = 2; 1629 /** 1630 * Focus has moved left 1631 * @see #playSoundEffect(int) 1632 */ 1633 public static final int FX_FOCUS_NAVIGATION_LEFT = 3; 1634 /** 1635 * Focus has moved right 1636 * @see #playSoundEffect(int) 1637 */ 1638 public static final int FX_FOCUS_NAVIGATION_RIGHT = 4; 1639 /** 1640 * IME standard keypress sound 1641 * @see #playSoundEffect(int) 1642 */ 1643 public static final int FX_KEYPRESS_STANDARD = 5; 1644 /** 1645 * IME spacebar keypress sound 1646 * @see #playSoundEffect(int) 1647 */ 1648 public static final int FX_KEYPRESS_SPACEBAR = 6; 1649 /** 1650 * IME delete keypress sound 1651 * @see #playSoundEffect(int) 1652 */ 1653 public static final int FX_KEYPRESS_DELETE = 7; 1654 /** 1655 * IME return_keypress sound 1656 * @see #playSoundEffect(int) 1657 */ 1658 public static final int FX_KEYPRESS_RETURN = 8; 1659 /** 1660 * @hide Number of sound effects 1661 */ 1662 public static final int NUM_SOUND_EFFECTS = 9; 1663 1664 /** 1665 * Plays a sound effect (Key clicks, lid open/close...) 1666 * @param effectType The type of sound effect. One of 1667 * {@link #FX_KEY_CLICK}, 1668 * {@link #FX_FOCUS_NAVIGATION_UP}, 1669 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 1670 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 1671 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 1672 * {@link #FX_KEYPRESS_STANDARD}, 1673 * {@link #FX_KEYPRESS_SPACEBAR}, 1674 * {@link #FX_KEYPRESS_DELETE}, 1675 * {@link #FX_KEYPRESS_RETURN}, 1676 * NOTE: This version uses the UI settings to determine 1677 * whether sounds are heard or not. 1678 */ playSoundEffect(int effectType)1679 public void playSoundEffect(int effectType) { 1680 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 1681 return; 1682 } 1683 1684 if (!querySoundEffectsEnabled()) { 1685 return; 1686 } 1687 1688 IAudioService service = getService(); 1689 try { 1690 service.playSoundEffect(effectType); 1691 } catch (RemoteException e) { 1692 Log.e(TAG, "Dead object in playSoundEffect"+e); 1693 } 1694 } 1695 1696 /** 1697 * Plays a sound effect (Key clicks, lid open/close...) 1698 * @param effectType The type of sound effect. One of 1699 * {@link #FX_KEY_CLICK}, 1700 * {@link #FX_FOCUS_NAVIGATION_UP}, 1701 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 1702 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 1703 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 1704 * {@link #FX_KEYPRESS_STANDARD}, 1705 * {@link #FX_KEYPRESS_SPACEBAR}, 1706 * {@link #FX_KEYPRESS_DELETE}, 1707 * {@link #FX_KEYPRESS_RETURN}, 1708 * @param volume Sound effect volume. 1709 * The volume value is a raw scalar so UI controls should be scaled logarithmically. 1710 * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used. 1711 * NOTE: This version is for applications that have their own 1712 * settings panel for enabling and controlling volume. 1713 */ playSoundEffect(int effectType, float volume)1714 public void playSoundEffect(int effectType, float volume) { 1715 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 1716 return; 1717 } 1718 1719 IAudioService service = getService(); 1720 try { 1721 service.playSoundEffectVolume(effectType, volume); 1722 } catch (RemoteException e) { 1723 Log.e(TAG, "Dead object in playSoundEffect"+e); 1724 } 1725 } 1726 1727 /** 1728 * Settings has an in memory cache, so this is fast. 1729 */ querySoundEffectsEnabled()1730 private boolean querySoundEffectsEnabled() { 1731 return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0; 1732 } 1733 1734 1735 /** 1736 * Load Sound effects. 1737 * This method must be called when sound effects are enabled. 1738 */ loadSoundEffects()1739 public void loadSoundEffects() { 1740 IAudioService service = getService(); 1741 try { 1742 service.loadSoundEffects(); 1743 } catch (RemoteException e) { 1744 Log.e(TAG, "Dead object in loadSoundEffects"+e); 1745 } 1746 } 1747 1748 /** 1749 * Unload Sound effects. 1750 * This method can be called to free some memory when 1751 * sound effects are disabled. 1752 */ unloadSoundEffects()1753 public void unloadSoundEffects() { 1754 IAudioService service = getService(); 1755 try { 1756 service.unloadSoundEffects(); 1757 } catch (RemoteException e) { 1758 Log.e(TAG, "Dead object in unloadSoundEffects"+e); 1759 } 1760 } 1761 1762 /** 1763 * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration. 1764 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1765 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1766 */ 1767 public static final int AUDIOFOCUS_GAIN = 1; 1768 /** 1769 * Used to indicate a temporary gain or request of audio focus, anticipated to last a short 1770 * amount of time. Examples of temporary changes are the playback of driving directions, or an 1771 * event notification. 1772 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1773 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1774 */ 1775 public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2; 1776 /** 1777 * Used to indicate a temporary request of audio focus, anticipated to last a short 1778 * amount of time, and where it is acceptable for other audio applications to keep playing 1779 * after having lowered their output level (also referred to as "ducking"). 1780 * Examples of temporary changes are the playback of driving directions where playback of music 1781 * in the background is acceptable. 1782 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1783 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1784 */ 1785 public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3; 1786 /** 1787 * Used to indicate a loss of audio focus of unknown duration. 1788 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1789 */ 1790 public static final int AUDIOFOCUS_LOSS = -1 * AUDIOFOCUS_GAIN; 1791 /** 1792 * Used to indicate a transient loss of audio focus. 1793 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1794 */ 1795 public static final int AUDIOFOCUS_LOSS_TRANSIENT = -1 * AUDIOFOCUS_GAIN_TRANSIENT; 1796 /** 1797 * Used to indicate a transient loss of audio focus where the loser of the audio focus can 1798 * lower its output volume if it wants to continue playing (also referred to as "ducking"), as 1799 * the new focus owner doesn't require others to be silent. 1800 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1801 */ 1802 public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = 1803 -1 * AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK; 1804 1805 /** 1806 * Interface definition for a callback to be invoked when the audio focus of the system is 1807 * updated. 1808 */ 1809 public interface OnAudioFocusChangeListener { 1810 /** 1811 * Called on the listener to notify it the audio focus for this listener has been changed. 1812 * The focusChange value indicates whether the focus was gained, 1813 * whether the focus was lost, and whether that loss is transient, or whether the new focus 1814 * holder will hold it for an unknown amount of time. 1815 * When losing focus, listeners can use the focus change information to decide what 1816 * behavior to adopt when losing focus. A music player could for instance elect to lower 1817 * the volume of its music stream (duck) for transient focus losses, and pause otherwise. 1818 * @param focusChange the type of focus change, one of {@link AudioManager#AUDIOFOCUS_GAIN}, 1819 * {@link AudioManager#AUDIOFOCUS_LOSS}, {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT} 1820 * and {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}. 1821 */ onAudioFocusChange(int focusChange)1822 public void onAudioFocusChange(int focusChange); 1823 } 1824 1825 /** 1826 * Map to convert focus event listener IDs, as used in the AudioService audio focus stack, 1827 * to actual listener objects. 1828 */ 1829 private final HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap = 1830 new HashMap<String, OnAudioFocusChangeListener>(); 1831 /** 1832 * Lock to prevent concurrent changes to the list of focus listeners for this AudioManager 1833 * instance. 1834 */ 1835 private final Object mFocusListenerLock = new Object(); 1836 findFocusListener(String id)1837 private OnAudioFocusChangeListener findFocusListener(String id) { 1838 return mAudioFocusIdListenerMap.get(id); 1839 } 1840 1841 /** 1842 * Handler for audio focus events coming from the audio service. 1843 */ 1844 private final FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate = 1845 new FocusEventHandlerDelegate(); 1846 1847 /** 1848 * Helper class to handle the forwarding of audio focus events to the appropriate listener 1849 */ 1850 private class FocusEventHandlerDelegate { 1851 private final Handler mHandler; 1852 FocusEventHandlerDelegate()1853 FocusEventHandlerDelegate() { 1854 Looper looper; 1855 if ((looper = Looper.myLooper()) == null) { 1856 looper = Looper.getMainLooper(); 1857 } 1858 1859 if (looper != null) { 1860 // implement the event handler delegate to receive audio focus events 1861 mHandler = new Handler(looper) { 1862 @Override 1863 public void handleMessage(Message msg) { 1864 OnAudioFocusChangeListener listener = null; 1865 synchronized(mFocusListenerLock) { 1866 listener = findFocusListener((String)msg.obj); 1867 } 1868 if (listener != null) { 1869 listener.onAudioFocusChange(msg.what); 1870 } 1871 } 1872 }; 1873 } else { 1874 mHandler = null; 1875 } 1876 } 1877 getHandler()1878 Handler getHandler() { 1879 return mHandler; 1880 } 1881 } 1882 1883 private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() { 1884 1885 public void dispatchAudioFocusChange(int focusChange, String id) { 1886 Message m = mAudioFocusEventHandlerDelegate.getHandler().obtainMessage(focusChange, id); 1887 mAudioFocusEventHandlerDelegate.getHandler().sendMessage(m); 1888 } 1889 1890 }; 1891 getIdForAudioFocusListener(OnAudioFocusChangeListener l)1892 private String getIdForAudioFocusListener(OnAudioFocusChangeListener l) { 1893 if (l == null) { 1894 return new String(this.toString()); 1895 } else { 1896 return new String(this.toString() + l.toString()); 1897 } 1898 } 1899 1900 /** 1901 * @hide 1902 * Registers a listener to be called when audio focus changes. Calling this method is optional 1903 * before calling {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, as it 1904 * will register the listener as well if it wasn't registered already. 1905 * @param l the listener to be notified of audio focus changes. 1906 */ registerAudioFocusListener(OnAudioFocusChangeListener l)1907 public void registerAudioFocusListener(OnAudioFocusChangeListener l) { 1908 synchronized(mFocusListenerLock) { 1909 if (mAudioFocusIdListenerMap.containsKey(getIdForAudioFocusListener(l))) { 1910 return; 1911 } 1912 mAudioFocusIdListenerMap.put(getIdForAudioFocusListener(l), l); 1913 } 1914 } 1915 1916 /** 1917 * @hide 1918 * Causes the specified listener to not be called anymore when focus is gained or lost. 1919 * @param l the listener to unregister. 1920 */ unregisterAudioFocusListener(OnAudioFocusChangeListener l)1921 public void unregisterAudioFocusListener(OnAudioFocusChangeListener l) { 1922 1923 // remove locally 1924 synchronized(mFocusListenerLock) { 1925 mAudioFocusIdListenerMap.remove(getIdForAudioFocusListener(l)); 1926 } 1927 } 1928 1929 1930 /** 1931 * A failed focus change request. 1932 */ 1933 public static final int AUDIOFOCUS_REQUEST_FAILED = 0; 1934 /** 1935 * A successful focus change request. 1936 */ 1937 public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; 1938 1939 1940 /** 1941 * Request audio focus. 1942 * Send a request to obtain the audio focus 1943 * @param l the listener to be notified of audio focus changes 1944 * @param streamType the main audio stream type affected by the focus request 1945 * @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request 1946 * is temporary, and focus will be abandonned shortly. Examples of transient requests are 1947 * for the playback of driving directions, or notifications sounds. 1948 * Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for 1949 * the previous focus owner to keep playing if it ducks its audio output. 1950 * Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such 1951 * as the playback of a song or a video. 1952 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 1953 */ requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)1954 public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) { 1955 int status = AUDIOFOCUS_REQUEST_FAILED; 1956 if ((durationHint < AUDIOFOCUS_GAIN) || (durationHint > AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)) 1957 { 1958 Log.e(TAG, "Invalid duration hint, audio focus request denied"); 1959 return status; 1960 } 1961 registerAudioFocusListener(l); 1962 //TODO protect request by permission check? 1963 IAudioService service = getService(); 1964 try { 1965 status = service.requestAudioFocus(streamType, durationHint, mICallBack, 1966 mAudioFocusDispatcher, getIdForAudioFocusListener(l), 1967 mContext.getPackageName() /* package name */); 1968 } catch (RemoteException e) { 1969 Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e); 1970 } 1971 return status; 1972 } 1973 1974 /** 1975 * @hide 1976 * Used internally by telephony package to request audio focus. Will cause the focus request 1977 * to be associated with the "voice communication" identifier only used in AudioService 1978 * to identify this use case. 1979 * @param streamType use STREAM_RING for focus requests when ringing, VOICE_CALL for 1980 * the establishment of the call 1981 * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so 1982 * media applications resume after a call 1983 */ requestAudioFocusForCall(int streamType, int durationHint)1984 public void requestAudioFocusForCall(int streamType, int durationHint) { 1985 IAudioService service = getService(); 1986 try { 1987 service.requestAudioFocus(streamType, durationHint, mICallBack, null, 1988 AudioService.IN_VOICE_COMM_FOCUS_ID, 1989 "system" /* dump-friendly package name */); 1990 } catch (RemoteException e) { 1991 Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e); 1992 } 1993 } 1994 1995 /** 1996 * @hide 1997 * Used internally by telephony package to abandon audio focus, typically after a call or 1998 * when ringing ends and the call is rejected or not answered. 1999 * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}. 2000 */ abandonAudioFocusForCall()2001 public void abandonAudioFocusForCall() { 2002 IAudioService service = getService(); 2003 try { 2004 service.abandonAudioFocus(null, AudioService.IN_VOICE_COMM_FOCUS_ID); 2005 } catch (RemoteException e) { 2006 Log.e(TAG, "Can't call abandonAudioFocusForCall() on AudioService due to "+e); 2007 } 2008 } 2009 2010 /** 2011 * Abandon audio focus. Causes the previous focus owner, if any, to receive focus. 2012 * @param l the listener with which focus was requested. 2013 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 2014 */ abandonAudioFocus(OnAudioFocusChangeListener l)2015 public int abandonAudioFocus(OnAudioFocusChangeListener l) { 2016 int status = AUDIOFOCUS_REQUEST_FAILED; 2017 unregisterAudioFocusListener(l); 2018 IAudioService service = getService(); 2019 try { 2020 status = service.abandonAudioFocus(mAudioFocusDispatcher, 2021 getIdForAudioFocusListener(l)); 2022 } catch (RemoteException e) { 2023 Log.e(TAG, "Can't call abandonAudioFocus() on AudioService due to "+e); 2024 } 2025 return status; 2026 } 2027 2028 2029 //==================================================================== 2030 // Remote Control 2031 /** 2032 * Register a component to be the sole receiver of MEDIA_BUTTON intents. 2033 * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} 2034 * that will receive the media button intent. This broadcast receiver must be declared 2035 * in the application manifest. The package of the component must match that of 2036 * the context you're registering from. 2037 */ registerMediaButtonEventReceiver(ComponentName eventReceiver)2038 public void registerMediaButtonEventReceiver(ComponentName eventReceiver) { 2039 if (eventReceiver == null) { 2040 return; 2041 } 2042 if (!eventReceiver.getPackageName().equals(mContext.getPackageName())) { 2043 Log.e(TAG, "registerMediaButtonEventReceiver() error: " + 2044 "receiver and context package names don't match"); 2045 return; 2046 } 2047 // construct a PendingIntent for the media button and register it 2048 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 2049 // the associated intent will be handled by the component being registered 2050 mediaButtonIntent.setComponent(eventReceiver); 2051 PendingIntent pi = PendingIntent.getBroadcast(mContext, 2052 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); 2053 registerMediaButtonIntent(pi, eventReceiver); 2054 } 2055 2056 /** 2057 * Register a component to be the sole receiver of MEDIA_BUTTON intents. This is like 2058 * {@link #registerMediaButtonEventReceiver(android.content.ComponentName)}, but allows 2059 * the buttons to go to any PendingIntent. Note that you should only use this form if 2060 * you know you will continue running for the full time until unregistering the 2061 * PendingIntent. 2062 * @param eventReceiver target that will receive media button intents. The PendingIntent 2063 * will be sent as-is when a media button action occurs, with {@link Intent#EXTRA_KEY_EVENT} 2064 * added and holding the key code of the media button that was pressed. 2065 */ registerMediaButtonEventReceiver(PendingIntent eventReceiver)2066 public void registerMediaButtonEventReceiver(PendingIntent eventReceiver) { 2067 if (eventReceiver == null) { 2068 return; 2069 } 2070 registerMediaButtonIntent(eventReceiver, null); 2071 } 2072 2073 /** 2074 * @hide 2075 * no-op if (pi == null) or (eventReceiver == null) 2076 */ registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver)2077 public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) { 2078 if (pi == null) { 2079 Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null parameter"); 2080 return; 2081 } 2082 IAudioService service = getService(); 2083 try { 2084 // pi != null 2085 service.registerMediaButtonIntent(pi, eventReceiver, 2086 eventReceiver == null ? mToken : null); 2087 } catch (RemoteException e) { 2088 Log.e(TAG, "Dead object in registerMediaButtonIntent"+e); 2089 } 2090 } 2091 2092 /** 2093 * @hide 2094 * Used internally by telephony package to register an intent receiver for ACTION_MEDIA_BUTTON. 2095 * @param eventReceiver the component that will receive the media button key events, 2096 * no-op if eventReceiver is null 2097 */ registerMediaButtonEventReceiverForCalls(ComponentName eventReceiver)2098 public void registerMediaButtonEventReceiverForCalls(ComponentName eventReceiver) { 2099 if (eventReceiver == null) { 2100 return; 2101 } 2102 IAudioService service = getService(); 2103 try { 2104 // eventReceiver != null 2105 service.registerMediaButtonEventReceiverForCalls(eventReceiver); 2106 } catch (RemoteException e) { 2107 Log.e(TAG, "Dead object in registerMediaButtonEventReceiverForCalls", e); 2108 } 2109 } 2110 2111 /** 2112 * @hide 2113 */ unregisterMediaButtonEventReceiverForCalls()2114 public void unregisterMediaButtonEventReceiverForCalls() { 2115 IAudioService service = getService(); 2116 try { 2117 service.unregisterMediaButtonEventReceiverForCalls(); 2118 } catch (RemoteException e) { 2119 Log.e(TAG, "Dead object in unregisterMediaButtonEventReceiverForCalls", e); 2120 } 2121 } 2122 2123 /** 2124 * Unregister the receiver of MEDIA_BUTTON intents. 2125 * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} 2126 * that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}. 2127 */ unregisterMediaButtonEventReceiver(ComponentName eventReceiver)2128 public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) { 2129 if (eventReceiver == null) { 2130 return; 2131 } 2132 // construct a PendingIntent for the media button and unregister it 2133 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 2134 // the associated intent will be handled by the component being registered 2135 mediaButtonIntent.setComponent(eventReceiver); 2136 PendingIntent pi = PendingIntent.getBroadcast(mContext, 2137 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); 2138 unregisterMediaButtonIntent(pi); 2139 } 2140 2141 /** 2142 * Unregister the receiver of MEDIA_BUTTON intents. 2143 * @param eventReceiver same PendingIntent that was registed with 2144 * {@link #registerMediaButtonEventReceiver(PendingIntent)}. 2145 */ unregisterMediaButtonEventReceiver(PendingIntent eventReceiver)2146 public void unregisterMediaButtonEventReceiver(PendingIntent eventReceiver) { 2147 if (eventReceiver == null) { 2148 return; 2149 } 2150 unregisterMediaButtonIntent(eventReceiver); 2151 } 2152 2153 /** 2154 * @hide 2155 */ unregisterMediaButtonIntent(PendingIntent pi)2156 public void unregisterMediaButtonIntent(PendingIntent pi) { 2157 IAudioService service = getService(); 2158 try { 2159 service.unregisterMediaButtonIntent(pi); 2160 } catch (RemoteException e) { 2161 Log.e(TAG, "Dead object in unregisterMediaButtonIntent"+e); 2162 } 2163 } 2164 2165 /** 2166 * Registers the remote control client for providing information to display on the remote 2167 * controls. 2168 * @param rcClient The remote control client from which remote controls will receive 2169 * information to display. 2170 * @see RemoteControlClient 2171 */ registerRemoteControlClient(RemoteControlClient rcClient)2172 public void registerRemoteControlClient(RemoteControlClient rcClient) { 2173 if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { 2174 return; 2175 } 2176 IAudioService service = getService(); 2177 try { 2178 int rcseId = service.registerRemoteControlClient( 2179 rcClient.getRcMediaIntent(), /* mediaIntent */ 2180 rcClient.getIRemoteControlClient(),/* rcClient */ 2181 // used to match media button event receiver and audio focus 2182 mContext.getPackageName()); /* packageName */ 2183 rcClient.setRcseId(rcseId); 2184 } catch (RemoteException e) { 2185 Log.e(TAG, "Dead object in registerRemoteControlClient"+e); 2186 } 2187 } 2188 2189 /** 2190 * Unregisters the remote control client that was providing information to display on the 2191 * remote controls. 2192 * @param rcClient The remote control client to unregister. 2193 * @see #registerRemoteControlClient(RemoteControlClient) 2194 */ unregisterRemoteControlClient(RemoteControlClient rcClient)2195 public void unregisterRemoteControlClient(RemoteControlClient rcClient) { 2196 if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { 2197 return; 2198 } 2199 IAudioService service = getService(); 2200 try { 2201 service.unregisterRemoteControlClient(rcClient.getRcMediaIntent(), /* mediaIntent */ 2202 rcClient.getIRemoteControlClient()); /* rcClient */ 2203 } catch (RemoteException e) { 2204 Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e); 2205 } 2206 } 2207 2208 /** 2209 * @hide 2210 * Registers a remote control display that will be sent information by remote control clients. 2211 * Use this method if your IRemoteControlDisplay is not going to display artwork, otherwise 2212 * use {@link #registerRemoteControlDisplay(IRemoteControlDisplay, int, int)} to pass the 2213 * artwork size directly, or 2214 * {@link #remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay, int, int)} later if artwork 2215 * is not yet needed. 2216 * @param rcd the IRemoteControlDisplay 2217 */ registerRemoteControlDisplay(IRemoteControlDisplay rcd)2218 public void registerRemoteControlDisplay(IRemoteControlDisplay rcd) { 2219 // passing a negative value for art work width and height as they are unknown at this stage 2220 registerRemoteControlDisplay(rcd, /*w*/-1, /*h*/ -1); 2221 } 2222 2223 /** 2224 * @hide 2225 * Registers a remote control display that will be sent information by remote control clients. 2226 * @param rcd 2227 * @param w the maximum width of the expected bitmap. Negative values indicate it is 2228 * useless to send artwork. 2229 * @param h the maximum height of the expected bitmap. Negative values indicate it is 2230 * useless to send artwork. 2231 */ registerRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h)2232 public void registerRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h) { 2233 if (rcd == null) { 2234 return; 2235 } 2236 IAudioService service = getService(); 2237 try { 2238 // passing a negative value for art work width and height as they are unknown at 2239 // this stage 2240 service.registerRemoteControlDisplay(rcd, w, h); 2241 } catch (RemoteException e) { 2242 Log.e(TAG, "Dead object in registerRemoteControlDisplay " + e); 2243 } 2244 } 2245 2246 /** 2247 * @hide 2248 * Unregisters a remote control display that was sent information by remote control clients. 2249 * @param rcd 2250 */ unregisterRemoteControlDisplay(IRemoteControlDisplay rcd)2251 public void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) { 2252 if (rcd == null) { 2253 return; 2254 } 2255 IAudioService service = getService(); 2256 try { 2257 service.unregisterRemoteControlDisplay(rcd); 2258 } catch (RemoteException e) { 2259 Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e); 2260 } 2261 } 2262 2263 /** 2264 * @hide 2265 * Sets the artwork size a remote control display expects when receiving bitmaps. 2266 * @param rcd 2267 * @param w the maximum width of the expected bitmap. Negative values indicate it is 2268 * useless to send artwork. 2269 * @param h the maximum height of the expected bitmap. Negative values indicate it is 2270 * useless to send artwork. 2271 */ remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h)2272 public void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) { 2273 if (rcd == null) { 2274 return; 2275 } 2276 IAudioService service = getService(); 2277 try { 2278 service.remoteControlDisplayUsesBitmapSize(rcd, w, h); 2279 } catch (RemoteException e) { 2280 Log.e(TAG, "Dead object in remoteControlDisplayUsesBitmapSize " + e); 2281 } 2282 } 2283 2284 /** 2285 * @hide 2286 * Controls whether a remote control display needs periodic checks of the RemoteControlClient 2287 * playback position to verify that the estimated position has not drifted from the actual 2288 * position. By default the check is not performed. 2289 * The IRemoteControlDisplay must have been previously registered for this to have any effect. 2290 * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled 2291 * or disabled. No effect is null. 2292 * @param wantsSync if true, RemoteControlClient instances which expose their playback position 2293 * to the framework will regularly compare the estimated playback position with the actual 2294 * position, and will update the IRemoteControlDisplay implementation whenever a drift is 2295 * detected. 2296 */ remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd, boolean wantsSync)2297 public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd, 2298 boolean wantsSync) { 2299 if (rcd == null) { 2300 return; 2301 } 2302 IAudioService service = getService(); 2303 try { 2304 service.remoteControlDisplayWantsPlaybackPositionSync(rcd, wantsSync); 2305 } catch (RemoteException e) { 2306 Log.e(TAG, "Dead object in remoteControlDisplayWantsPlaybackPositionSync " + e); 2307 } 2308 } 2309 2310 /** 2311 * @hide 2312 * Request the user of a RemoteControlClient to seek to the given playback position. 2313 * @param generationId the RemoteControlClient generation counter for which this request is 2314 * issued. Requests for an older generation than current one will be ignored. 2315 * @param timeMs the time in ms to seek to, must be positive. 2316 */ setRemoteControlClientPlaybackPosition(int generationId, long timeMs)2317 public void setRemoteControlClientPlaybackPosition(int generationId, long timeMs) { 2318 if (timeMs < 0) { 2319 return; 2320 } 2321 IAudioService service = getService(); 2322 try { 2323 service.setRemoteControlClientPlaybackPosition(generationId, timeMs); 2324 } catch (RemoteException e) { 2325 Log.e(TAG, "Dead object in setRccPlaybackPosition("+ generationId + ", " 2326 + timeMs + ")", e); 2327 } 2328 } 2329 2330 /** 2331 * @hide 2332 * Reload audio settings. This method is called by Settings backup 2333 * agent when audio settings are restored and causes the AudioService 2334 * to read and apply restored settings. 2335 */ reloadAudioSettings()2336 public void reloadAudioSettings() { 2337 IAudioService service = getService(); 2338 try { 2339 service.reloadAudioSettings(); 2340 } catch (RemoteException e) { 2341 Log.e(TAG, "Dead object in reloadAudioSettings"+e); 2342 } 2343 } 2344 2345 /** 2346 * {@hide} 2347 */ 2348 private final IBinder mICallBack = new Binder(); 2349 2350 /** 2351 * Checks whether the phone is in silent mode, with or without vibrate. 2352 * 2353 * @return true if phone is in silent mode, with or without vibrate. 2354 * 2355 * @see #getRingerMode() 2356 * 2357 * @hide pending API Council approval 2358 */ isSilentMode()2359 public boolean isSilentMode() { 2360 int ringerMode = getRingerMode(); 2361 boolean silentMode = 2362 (ringerMode == RINGER_MODE_SILENT) || 2363 (ringerMode == RINGER_MODE_VIBRATE); 2364 return silentMode; 2365 } 2366 2367 // This section re-defines new output device constants from AudioSystem, because the AudioSystem 2368 // class is not used by other parts of the framework, which instead use definitions and methods 2369 // from AudioManager. AudioSystem is an internal class used by AudioManager and AudioService. 2370 2371 /** {@hide} The audio output device code for the small speaker at the front of the device used 2372 * when placing calls. Does not refer to an in-ear headphone without attached microphone, 2373 * such as earbuds, earphones, or in-ear monitors (IEM). Those would be handled as a 2374 * {@link #DEVICE_OUT_WIRED_HEADPHONE}. 2375 */ 2376 public static final int DEVICE_OUT_EARPIECE = AudioSystem.DEVICE_OUT_EARPIECE; 2377 /** {@hide} The audio output device code for the built-in speaker */ 2378 public static final int DEVICE_OUT_SPEAKER = AudioSystem.DEVICE_OUT_SPEAKER; 2379 /** {@hide} The audio output device code for a wired headset with attached microphone */ 2380 public static final int DEVICE_OUT_WIRED_HEADSET = AudioSystem.DEVICE_OUT_WIRED_HEADSET; 2381 /** {@hide} The audio output device code for a wired headphone without attached microphone */ 2382 public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE; 2383 /** {@hide} The audio output device code for generic Bluetooth SCO, for voice */ 2384 public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; 2385 /** {@hide} The audio output device code for Bluetooth SCO Headset Profile (HSP) and 2386 * Hands-Free Profile (HFP), for voice 2387 */ 2388 public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 2389 AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2390 /** {@hide} The audio output device code for Bluetooth SCO car audio, for voice */ 2391 public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 2392 AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2393 /** {@hide} The audio output device code for generic Bluetooth A2DP, for music */ 2394 public static final int DEVICE_OUT_BLUETOOTH_A2DP = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; 2395 /** {@hide} The audio output device code for Bluetooth A2DP headphones, for music */ 2396 public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 2397 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2398 /** {@hide} The audio output device code for Bluetooth A2DP external speaker, for music */ 2399 public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 2400 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2401 /** {@hide} The audio output device code for S/PDIF or HDMI */ 2402 public static final int DEVICE_OUT_AUX_DIGITAL = AudioSystem.DEVICE_OUT_AUX_DIGITAL; 2403 /** {@hide} The audio output device code for an analog wired headset attached via a 2404 * docking station 2405 */ 2406 public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET; 2407 /** {@hide} The audio output device code for a digital wired headset attached via a 2408 * docking station 2409 */ 2410 public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; 2411 /** {@hide} The audio output device code for a USB audio accessory. The accessory is in USB host 2412 * mode and the Android device in USB device mode 2413 */ 2414 public static final int DEVICE_OUT_USB_ACCESSORY = AudioSystem.DEVICE_OUT_USB_ACCESSORY; 2415 /** {@hide} The audio output device code for a USB audio device. The device is in USB device 2416 * mode and the Android device in USB host mode 2417 */ 2418 public static final int DEVICE_OUT_USB_DEVICE = AudioSystem.DEVICE_OUT_USB_DEVICE; 2419 /** {@hide} This is not used as a returned value from {@link #getDevicesForStream}, but could be 2420 * used in the future in a set method to select whatever default device is chosen by the 2421 * platform-specific implementation. 2422 */ 2423 public static final int DEVICE_OUT_DEFAULT = AudioSystem.DEVICE_OUT_DEFAULT; 2424 2425 /** 2426 * Return the enabled devices for the specified output stream type. 2427 * 2428 * @param streamType The stream type to query. One of 2429 * {@link #STREAM_VOICE_CALL}, 2430 * {@link #STREAM_SYSTEM}, 2431 * {@link #STREAM_RING}, 2432 * {@link #STREAM_MUSIC}, 2433 * {@link #STREAM_ALARM}, 2434 * {@link #STREAM_NOTIFICATION}, 2435 * {@link #STREAM_DTMF}. 2436 * 2437 * @return The bit-mask "or" of audio output device codes for all enabled devices on this 2438 * stream. Zero or more of 2439 * {@link #DEVICE_OUT_EARPIECE}, 2440 * {@link #DEVICE_OUT_SPEAKER}, 2441 * {@link #DEVICE_OUT_WIRED_HEADSET}, 2442 * {@link #DEVICE_OUT_WIRED_HEADPHONE}, 2443 * {@link #DEVICE_OUT_BLUETOOTH_SCO}, 2444 * {@link #DEVICE_OUT_BLUETOOTH_SCO_HEADSET}, 2445 * {@link #DEVICE_OUT_BLUETOOTH_SCO_CARKIT}, 2446 * {@link #DEVICE_OUT_BLUETOOTH_A2DP}, 2447 * {@link #DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES}, 2448 * {@link #DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER}, 2449 * {@link #DEVICE_OUT_AUX_DIGITAL}, 2450 * {@link #DEVICE_OUT_ANLG_DOCK_HEADSET}, 2451 * {@link #DEVICE_OUT_DGTL_DOCK_HEADSET}. 2452 * {@link #DEVICE_OUT_DEFAULT} is not used here. 2453 * 2454 * The implementation may support additional device codes beyond those listed, so 2455 * the application should ignore any bits which it does not recognize. 2456 * Note that the information may be imprecise when the implementation 2457 * cannot distinguish whether a particular device is enabled. 2458 * 2459 * {@hide} 2460 */ getDevicesForStream(int streamType)2461 public int getDevicesForStream(int streamType) { 2462 switch (streamType) { 2463 case STREAM_VOICE_CALL: 2464 case STREAM_SYSTEM: 2465 case STREAM_RING: 2466 case STREAM_MUSIC: 2467 case STREAM_ALARM: 2468 case STREAM_NOTIFICATION: 2469 case STREAM_DTMF: 2470 return AudioSystem.getDevicesForStream(streamType); 2471 default: 2472 return 0; 2473 } 2474 } 2475 2476 /** 2477 * Indicate wired accessory connection state change. 2478 * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx) 2479 * @param state new connection state: 1 connected, 0 disconnected 2480 * @param name device name 2481 * {@hide} 2482 */ setWiredDeviceConnectionState(int device, int state, String name)2483 public void setWiredDeviceConnectionState(int device, int state, String name) { 2484 IAudioService service = getService(); 2485 try { 2486 service.setWiredDeviceConnectionState(device, state, name); 2487 } catch (RemoteException e) { 2488 Log.e(TAG, "Dead object in setWiredDeviceConnectionState "+e); 2489 } 2490 } 2491 2492 /** 2493 * Indicate A2DP sink connection state change. 2494 * @param device Bluetooth device connected/disconnected 2495 * @param state new connection state (BluetoothProfile.STATE_xxx) 2496 * @return a delay in ms that the caller should wait before broadcasting 2497 * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent. 2498 * {@hide} 2499 */ setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state)2500 public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state) { 2501 IAudioService service = getService(); 2502 int delay = 0; 2503 try { 2504 delay = service.setBluetoothA2dpDeviceConnectionState(device, state); 2505 } catch (RemoteException e) { 2506 Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e); 2507 } finally { 2508 return delay; 2509 } 2510 } 2511 2512 /** {@hide} */ getRingtonePlayer()2513 public IRingtonePlayer getRingtonePlayer() { 2514 try { 2515 return getService().getRingtonePlayer(); 2516 } catch (RemoteException e) { 2517 return null; 2518 } 2519 } 2520 2521 /** 2522 * Used as a key for {@link #getProperty} to request the native or optimal output sample rate 2523 * for this device's primary output stream, in decimal Hz. 2524 */ 2525 public static final String PROPERTY_OUTPUT_SAMPLE_RATE = 2526 "android.media.property.OUTPUT_SAMPLE_RATE"; 2527 2528 /** 2529 * Used as a key for {@link #getProperty} to request the native or optimal output buffer size 2530 * for this device's primary output stream, in decimal PCM frames. 2531 */ 2532 public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = 2533 "android.media.property.OUTPUT_FRAMES_PER_BUFFER"; 2534 2535 /** 2536 * Returns the value of the property with the specified key. 2537 * @param key One of the strings corresponding to a property key: either 2538 * {@link #PROPERTY_OUTPUT_SAMPLE_RATE} or 2539 * {@link #PROPERTY_OUTPUT_FRAMES_PER_BUFFER} 2540 * @return A string representing the associated value for that property key, 2541 * or null if there is no value for that key. 2542 */ getProperty(String key)2543 public String getProperty(String key) { 2544 if (PROPERTY_OUTPUT_SAMPLE_RATE.equals(key)) { 2545 int outputSampleRate = AudioSystem.getPrimaryOutputSamplingRate(); 2546 return outputSampleRate > 0 ? Integer.toString(outputSampleRate) : null; 2547 } else if (PROPERTY_OUTPUT_FRAMES_PER_BUFFER.equals(key)) { 2548 int outputFramesPerBuffer = AudioSystem.getPrimaryOutputFrameCount(); 2549 return outputFramesPerBuffer > 0 ? Integer.toString(outputFramesPerBuffer) : null; 2550 } else { 2551 // null or unknown key 2552 return null; 2553 } 2554 } 2555 2556 /** 2557 * Returns the estimated latency for the given stream type in milliseconds. 2558 * 2559 * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need 2560 * a better solution. 2561 * @hide 2562 */ getOutputLatency(int streamType)2563 public int getOutputLatency(int streamType) { 2564 return AudioSystem.getOutputLatency(streamType); 2565 } 2566 2567 } 2568