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