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