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