AudioManager.java revision c614df96507229eda13c029176ecc8f424a9854b
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 * Returns the maximum volume index for master volume. 730 * 731 * @hide 732 */ 733 public int getMasterMaxVolume() { 734 IAudioService service = getService(); 735 try { 736 return service.getMasterMaxVolume(); 737 } catch (RemoteException e) { 738 Log.e(TAG, "Dead object in getMasterMaxVolume", e); 739 return 0; 740 } 741 } 742 743 /** 744 * Returns the current volume index for master volume. 745 * 746 * @return The current volume index for master volume. 747 * @hide 748 */ 749 public int getMasterVolume() { 750 IAudioService service = getService(); 751 try { 752 return service.getMasterVolume(); 753 } catch (RemoteException e) { 754 Log.e(TAG, "Dead object in getMasterVolume", e); 755 return 0; 756 } 757 } 758 759 /** 760 * Get last audible volume before master volume was muted. 761 * 762 * @hide 763 */ 764 public int getLastAudibleMasterVolume() { 765 IAudioService service = getService(); 766 try { 767 return service.getLastAudibleMasterVolume(); 768 } catch (RemoteException e) { 769 Log.e(TAG, "Dead object in getLastAudibleMasterVolume", e); 770 return 0; 771 } 772 } 773 774 /** 775 * Sets the volume index for master volume. 776 * 777 * @param index The volume index to set. See 778 * {@link #getMasterMaxVolume(int)} for the largest valid value. 779 * @param flags One or more flags. 780 * @see #getMasterMaxVolume(int) 781 * @see #getMasterVolume(int) 782 * @hide 783 */ 784 public void setMasterVolume(int index, int flags) { 785 IAudioService service = getService(); 786 try { 787 service.setMasterVolume(index, flags); 788 } catch (RemoteException e) { 789 Log.e(TAG, "Dead object in setMasterVolume", e); 790 } 791 } 792 793 /** 794 * Solo or unsolo a particular stream. All other streams are muted. 795 * <p> 796 * The solo command is protected against client process death: if a process 797 * with an active solo request on a stream dies, all streams that were muted 798 * because of this request will be unmuted automatically. 799 * <p> 800 * The solo requests for a given stream are cumulative: the AudioManager 801 * can receive several solo requests from one or more clients and the stream 802 * will be unsoloed only when the same number of unsolo requests are received. 803 * <p> 804 * For a better user experience, applications MUST unsolo a soloed stream 805 * in onPause() and solo is again in onResume() if appropriate. 806 * 807 * @param streamType The stream to be soloed/unsoloed. 808 * @param state The required solo state: true for solo ON, false for solo OFF 809 */ 810 public void setStreamSolo(int streamType, boolean state) { 811 IAudioService service = getService(); 812 try { 813 service.setStreamSolo(streamType, state, mICallBack); 814 } catch (RemoteException e) { 815 Log.e(TAG, "Dead object in setStreamSolo", e); 816 } 817 } 818 819 /** 820 * Mute or unmute an audio stream. 821 * <p> 822 * The mute command is protected against client process death: if a process 823 * with an active mute request on a stream dies, this stream will be unmuted 824 * automatically. 825 * <p> 826 * The mute requests for a given stream are cumulative: the AudioManager 827 * can receive several mute requests from one or more clients and the stream 828 * will be unmuted only when the same number of unmute requests are received. 829 * <p> 830 * For a better user experience, applications MUST unmute a muted stream 831 * in onPause() and mute is again in onResume() if appropriate. 832 * <p> 833 * This method should only be used by applications that replace the platform-wide 834 * management of audio settings or the main telephony application. 835 * 836 * @param streamType The stream to be muted/unmuted. 837 * @param state The required mute state: true for mute ON, false for mute OFF 838 */ 839 public void setStreamMute(int streamType, boolean state) { 840 IAudioService service = getService(); 841 try { 842 service.setStreamMute(streamType, state, mICallBack); 843 } catch (RemoteException e) { 844 Log.e(TAG, "Dead object in setStreamMute", e); 845 } 846 } 847 848 /** 849 * get stream mute state. 850 * 851 * @hide 852 */ 853 public boolean isStreamMute(int streamType) { 854 IAudioService service = getService(); 855 try { 856 return service.isStreamMute(streamType); 857 } catch (RemoteException e) { 858 Log.e(TAG, "Dead object in isStreamMute", e); 859 return false; 860 } 861 } 862 863 /** 864 * set master mute state. 865 * 866 * @hide 867 */ 868 public void setMasterMute(boolean state) { 869 IAudioService service = getService(); 870 try { 871 service.setMasterMute(state, mICallBack); 872 } catch (RemoteException e) { 873 Log.e(TAG, "Dead object in setMasterMute", e); 874 } 875 } 876 877 /** 878 * get master mute state. 879 * 880 * @hide 881 */ 882 public boolean isMasterMute() { 883 IAudioService service = getService(); 884 try { 885 return service.isMasterMute(); 886 } catch (RemoteException e) { 887 Log.e(TAG, "Dead object in isMasterMute", e); 888 return false; 889 } 890 } 891 892 /** 893 * forces the stream controlled by hard volume keys 894 * specifying streamType == -1 releases control to the 895 * logic. 896 * 897 * @hide 898 */ 899 public void forceVolumeControlStream(int streamType) { 900 mVolumeControlStream = streamType; 901 } 902 903 /** 904 * Returns whether a particular type should vibrate according to user 905 * settings and the current ringer mode. 906 * <p> 907 * This shouldn't be needed by most clients that use notifications to 908 * vibrate. The notification manager will not vibrate if the policy doesn't 909 * allow it, so the client should always set a vibrate pattern and let the 910 * notification manager control whether or not to actually vibrate. 911 * 912 * @param vibrateType The type of vibrate. One of 913 * {@link #VIBRATE_TYPE_NOTIFICATION} or 914 * {@link #VIBRATE_TYPE_RINGER}. 915 * @return Whether the type should vibrate at the instant this method is 916 * called. 917 * @see #setVibrateSetting(int, int) 918 * @see #getVibrateSetting(int) 919 */ 920 public boolean shouldVibrate(int vibrateType) { 921 IAudioService service = getService(); 922 try { 923 return service.shouldVibrate(vibrateType); 924 } catch (RemoteException e) { 925 Log.e(TAG, "Dead object in shouldVibrate", e); 926 return false; 927 } 928 } 929 930 /** 931 * Returns whether the user's vibrate setting for a vibrate type. 932 * <p> 933 * This shouldn't be needed by most clients that want to vibrate, instead 934 * see {@link #shouldVibrate(int)}. 935 * 936 * @param vibrateType The type of vibrate. One of 937 * {@link #VIBRATE_TYPE_NOTIFICATION} or 938 * {@link #VIBRATE_TYPE_RINGER}. 939 * @return The vibrate setting, one of {@link #VIBRATE_SETTING_ON}, 940 * {@link #VIBRATE_SETTING_OFF}, or 941 * {@link #VIBRATE_SETTING_ONLY_SILENT}. 942 * @see #setVibrateSetting(int, int) 943 * @see #shouldVibrate(int) 944 */ 945 public int getVibrateSetting(int vibrateType) { 946 IAudioService service = getService(); 947 try { 948 return service.getVibrateSetting(vibrateType); 949 } catch (RemoteException e) { 950 Log.e(TAG, "Dead object in getVibrateSetting", e); 951 return VIBRATE_SETTING_OFF; 952 } 953 } 954 955 /** 956 * Sets the setting for when the vibrate type should vibrate. 957 * <p> 958 * This method should only be used by applications that replace the platform-wide 959 * management of audio settings or the main telephony application. 960 * 961 * @param vibrateType The type of vibrate. One of 962 * {@link #VIBRATE_TYPE_NOTIFICATION} or 963 * {@link #VIBRATE_TYPE_RINGER}. 964 * @param vibrateSetting The vibrate setting, one of 965 * {@link #VIBRATE_SETTING_ON}, 966 * {@link #VIBRATE_SETTING_OFF}, or 967 * {@link #VIBRATE_SETTING_ONLY_SILENT}. 968 * @see #getVibrateSetting(int) 969 * @see #shouldVibrate(int) 970 */ 971 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 972 IAudioService service = getService(); 973 try { 974 service.setVibrateSetting(vibrateType, vibrateSetting); 975 } catch (RemoteException e) { 976 Log.e(TAG, "Dead object in setVibrateSetting", e); 977 } 978 } 979 980 /** 981 * Sets the speakerphone on or off. 982 * <p> 983 * This method should only be used by applications that replace the platform-wide 984 * management of audio settings or the main telephony application. 985 * 986 * @param on set <var>true</var> to turn on speakerphone; 987 * <var>false</var> to turn it off 988 */ 989 public void setSpeakerphoneOn(boolean on){ 990 IAudioService service = getService(); 991 try { 992 service.setSpeakerphoneOn(on); 993 } catch (RemoteException e) { 994 Log.e(TAG, "Dead object in setSpeakerphoneOn", e); 995 } 996 } 997 998 /** 999 * Checks whether the speakerphone is on or off. 1000 * 1001 * @return true if speakerphone is on, false if it's off 1002 */ 1003 public boolean isSpeakerphoneOn() { 1004 IAudioService service = getService(); 1005 try { 1006 return service.isSpeakerphoneOn(); 1007 } catch (RemoteException e) { 1008 Log.e(TAG, "Dead object in isSpeakerphoneOn", e); 1009 return false; 1010 } 1011 } 1012 1013 //==================================================================== 1014 // Bluetooth SCO control 1015 /** 1016 * Sticky broadcast intent action indicating that the bluetoooth SCO audio 1017 * connection state has changed. The intent contains on extra {@link #EXTRA_SCO_AUDIO_STATE} 1018 * indicating the new state which is either {@link #SCO_AUDIO_STATE_DISCONNECTED} 1019 * or {@link #SCO_AUDIO_STATE_CONNECTED} 1020 * 1021 * @see #startBluetoothSco() 1022 * @deprecated Use {@link #ACTION_SCO_AUDIO_STATE_UPDATED} instead 1023 */ 1024 @Deprecated 1025 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1026 public static final String ACTION_SCO_AUDIO_STATE_CHANGED = 1027 "android.media.SCO_AUDIO_STATE_CHANGED"; 1028 1029 /** 1030 * Sticky broadcast intent action indicating that the bluetoooth SCO audio 1031 * connection state has been updated. 1032 * <p>This intent has two extras: 1033 * <ul> 1034 * <li> {@link #EXTRA_SCO_AUDIO_STATE} - The new SCO audio state. </li> 1035 * <li> {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE}- The previous SCO audio state. </li> 1036 * </ul> 1037 * <p> EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE can be any of: 1038 * <ul> 1039 * <li> {@link #SCO_AUDIO_STATE_DISCONNECTED}, </li> 1040 * <li> {@link #SCO_AUDIO_STATE_CONNECTING} or </li> 1041 * <li> {@link #SCO_AUDIO_STATE_CONNECTED}, </li> 1042 * </ul> 1043 * @see #startBluetoothSco() 1044 */ 1045 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1046 public static final String ACTION_SCO_AUDIO_STATE_UPDATED = 1047 "android.media.ACTION_SCO_AUDIO_STATE_UPDATED"; 1048 1049 /** 1050 * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_CHANGED} or 1051 * {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the new bluetooth SCO connection state. 1052 */ 1053 public static final String EXTRA_SCO_AUDIO_STATE = 1054 "android.media.extra.SCO_AUDIO_STATE"; 1055 1056 /** 1057 * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the previous 1058 * bluetooth SCO connection state. 1059 */ 1060 public static final String EXTRA_SCO_AUDIO_PREVIOUS_STATE = 1061 "android.media.extra.SCO_AUDIO_PREVIOUS_STATE"; 1062 1063 /** 1064 * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE 1065 * indicating that the SCO audio channel is not established 1066 */ 1067 public static final int SCO_AUDIO_STATE_DISCONNECTED = 0; 1068 /** 1069 * Value for extra {@link #EXTRA_SCO_AUDIO_STATE} or {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE} 1070 * indicating that the SCO audio channel is established 1071 */ 1072 public static final int SCO_AUDIO_STATE_CONNECTED = 1; 1073 /** 1074 * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE 1075 * indicating that the SCO audio channel is being established 1076 */ 1077 public static final int SCO_AUDIO_STATE_CONNECTING = 2; 1078 /** 1079 * Value for extra EXTRA_SCO_AUDIO_STATE indicating that 1080 * there was an error trying to obtain the state 1081 */ 1082 public static final int SCO_AUDIO_STATE_ERROR = -1; 1083 1084 1085 /** 1086 * Indicates if current platform supports use of SCO for off call use cases. 1087 * Application wanted to use bluetooth SCO audio when the phone is not in call 1088 * must first call thsi method to make sure that the platform supports this 1089 * feature. 1090 * @return true if bluetooth SCO can be used for audio when not in call 1091 * false otherwise 1092 * @see #startBluetoothSco() 1093 */ 1094 public boolean isBluetoothScoAvailableOffCall() { 1095 return mContext.getResources().getBoolean( 1096 com.android.internal.R.bool.config_bluetooth_sco_off_call); 1097 } 1098 1099 /** 1100 * Start bluetooth SCO audio connection. 1101 * <p>Requires Permission: 1102 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1103 * <p>This method can be used by applications wanting to send and received audio 1104 * to/from a bluetooth SCO headset while the phone is not in call. 1105 * <p>As the SCO connection establishment can take several seconds, 1106 * applications should not rely on the connection to be available when the method 1107 * returns but instead register to receive the intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} 1108 * and wait for the state to be {@link #SCO_AUDIO_STATE_CONNECTED}. 1109 * <p>As the ACTION_SCO_AUDIO_STATE_UPDATED intent is sticky, the application can check the SCO 1110 * audio state before calling startBluetoothSco() by reading the intent returned by the receiver 1111 * registration. If the state is already CONNECTED, no state change will be received via the 1112 * intent after calling startBluetoothSco(). It is however useful to call startBluetoothSco() 1113 * so that the connection stays active in case the current initiator stops the connection. 1114 * <p>Unless the connection is already active as described above, the state will always 1115 * transition from DISCONNECTED to CONNECTING and then either to CONNECTED if the connection 1116 * succeeds or back to DISCONNECTED if the connection fails (e.g no headset is connected). 1117 * <p>When finished with the SCO connection or if the establishment fails, the application must 1118 * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection. 1119 * <p>Even if a SCO connection is established, the following restrictions apply on audio 1120 * output streams so that they can be routed to SCO headset: 1121 * <ul> 1122 * <li> the stream type must be {@link #STREAM_VOICE_CALL} </li> 1123 * <li> the format must be mono </li> 1124 * <li> the sampling must be 16kHz or 8kHz </li> 1125 * </ul> 1126 * <p>The following restrictions apply on input streams: 1127 * <ul> 1128 * <li> the format must be mono </li> 1129 * <li> the sampling must be 8kHz </li> 1130 * </ul> 1131 * <p>Note that the phone application always has the priority on the usage of the SCO 1132 * connection for telephony. If this method is called while the phone is in call 1133 * it will be ignored. Similarly, if a call is received or sent while an application 1134 * is using the SCO connection, the connection will be lost for the application and NOT 1135 * returned automatically when the call ends. 1136 * @see #stopBluetoothSco() 1137 * @see #ACTION_SCO_AUDIO_STATE_UPDATED 1138 */ 1139 public void startBluetoothSco(){ 1140 IAudioService service = getService(); 1141 try { 1142 service.startBluetoothSco(mICallBack); 1143 } catch (RemoteException e) { 1144 Log.e(TAG, "Dead object in startBluetoothSco", e); 1145 } 1146 } 1147 1148 /** 1149 * Stop bluetooth SCO audio connection. 1150 * <p>Requires Permission: 1151 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1152 * <p>This method must be called by applications having requested the use of 1153 * bluetooth SCO audio with {@link #startBluetoothSco()} 1154 * when finished with the SCO connection or if connection fails. 1155 * @see #startBluetoothSco() 1156 */ 1157 public void stopBluetoothSco(){ 1158 IAudioService service = getService(); 1159 try { 1160 service.stopBluetoothSco(mICallBack); 1161 } catch (RemoteException e) { 1162 Log.e(TAG, "Dead object in stopBluetoothSco", e); 1163 } 1164 } 1165 1166 /** 1167 * Request use of Bluetooth SCO headset for communications. 1168 * <p> 1169 * This method should only be used by applications that replace the platform-wide 1170 * management of audio settings or the main telephony application. 1171 * 1172 * @param on set <var>true</var> to use bluetooth SCO for communications; 1173 * <var>false</var> to not use bluetooth SCO for communications 1174 */ 1175 public void setBluetoothScoOn(boolean on){ 1176 IAudioService service = getService(); 1177 try { 1178 service.setBluetoothScoOn(on); 1179 } catch (RemoteException e) { 1180 Log.e(TAG, "Dead object in setBluetoothScoOn", e); 1181 } 1182 } 1183 1184 /** 1185 * Checks whether communications use Bluetooth SCO. 1186 * 1187 * @return true if SCO is used for communications; 1188 * false if otherwise 1189 */ 1190 public boolean isBluetoothScoOn() { 1191 IAudioService service = getService(); 1192 try { 1193 return service.isBluetoothScoOn(); 1194 } catch (RemoteException e) { 1195 Log.e(TAG, "Dead object in isBluetoothScoOn", e); 1196 return false; 1197 } 1198 } 1199 1200 /** 1201 * @param on set <var>true</var> to route A2DP audio to/from Bluetooth 1202 * headset; <var>false</var> disable A2DP audio 1203 * @deprecated Do not use. 1204 */ 1205 @Deprecated public void setBluetoothA2dpOn(boolean on){ 1206 } 1207 1208 /** 1209 * Checks whether A2DP audio routing to the Bluetooth headset is on or off. 1210 * 1211 * @return true if A2DP audio is being routed to/from Bluetooth headset; 1212 * false if otherwise 1213 */ 1214 public boolean isBluetoothA2dpOn() { 1215 if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"") 1216 == AudioSystem.DEVICE_STATE_UNAVAILABLE) { 1217 return false; 1218 } else { 1219 return true; 1220 } 1221 } 1222 1223 /** 1224 * Sets audio routing to the wired headset on or off. 1225 * 1226 * @param on set <var>true</var> to route audio to/from wired 1227 * headset; <var>false</var> disable wired headset audio 1228 * @deprecated Do not use. 1229 */ 1230 @Deprecated public void setWiredHeadsetOn(boolean on){ 1231 } 1232 1233 /** 1234 * Checks whether a wired headset is connected or not. 1235 * <p>This is not a valid indication that audio playback is 1236 * actually over the wired headset as audio routing depends on other conditions. 1237 * 1238 * @return true if a wired headset is connected. 1239 * false if otherwise 1240 * @deprecated Use only to check is a headset is connected or not. 1241 */ 1242 public boolean isWiredHeadsetOn() { 1243 if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"") 1244 == AudioSystem.DEVICE_STATE_UNAVAILABLE && 1245 AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"") 1246 == AudioSystem.DEVICE_STATE_UNAVAILABLE) { 1247 return false; 1248 } else { 1249 return true; 1250 } 1251 } 1252 1253 /** 1254 * Sets the microphone mute on or off. 1255 * <p> 1256 * This method should only be used by applications that replace the platform-wide 1257 * management of audio settings or the main telephony application. 1258 * 1259 * @param on set <var>true</var> to mute the microphone; 1260 * <var>false</var> to turn mute off 1261 */ 1262 public void setMicrophoneMute(boolean on){ 1263 AudioSystem.muteMicrophone(on); 1264 } 1265 1266 /** 1267 * Checks whether the microphone mute is on or off. 1268 * 1269 * @return true if microphone is muted, false if it's not 1270 */ 1271 public boolean isMicrophoneMute() { 1272 return AudioSystem.isMicrophoneMuted(); 1273 } 1274 1275 /** 1276 * Sets the audio mode. 1277 * <p> 1278 * The audio mode encompasses audio routing AND the behavior of 1279 * the telephony layer. Therefore this method should only be used by applications that 1280 * replace the platform-wide management of audio settings or the main telephony application. 1281 * In particular, the {@link #MODE_IN_CALL} mode should only be used by the telephony 1282 * application when it places a phone call, as it will cause signals from the radio layer 1283 * to feed the platform mixer. 1284 * 1285 * @param mode the requested audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, 1286 * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). 1287 * Informs the HAL about the current audio state so that 1288 * it can route the audio appropriately. 1289 */ 1290 public void setMode(int mode) { 1291 IAudioService service = getService(); 1292 try { 1293 service.setMode(mode, mICallBack); 1294 } catch (RemoteException e) { 1295 Log.e(TAG, "Dead object in setMode", e); 1296 } 1297 } 1298 1299 /** 1300 * Returns the current audio mode. 1301 * 1302 * @return the current audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, 1303 * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). 1304 * Returns the current current audio state from the HAL. 1305 */ 1306 public int getMode() { 1307 IAudioService service = getService(); 1308 try { 1309 return service.getMode(); 1310 } catch (RemoteException e) { 1311 Log.e(TAG, "Dead object in getMode", e); 1312 return MODE_INVALID; 1313 } 1314 } 1315 1316 /* modes for setMode/getMode/setRoute/getRoute */ 1317 /** 1318 * Audio harware modes. 1319 */ 1320 /** 1321 * Invalid audio mode. 1322 */ 1323 public static final int MODE_INVALID = AudioSystem.MODE_INVALID; 1324 /** 1325 * Current audio mode. Used to apply audio routing to current mode. 1326 */ 1327 public static final int MODE_CURRENT = AudioSystem.MODE_CURRENT; 1328 /** 1329 * Normal audio mode: not ringing and no call established. 1330 */ 1331 public static final int MODE_NORMAL = AudioSystem.MODE_NORMAL; 1332 /** 1333 * Ringing audio mode. An incoming is being signaled. 1334 */ 1335 public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE; 1336 /** 1337 * In call audio mode. A telephony call is established. 1338 */ 1339 public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL; 1340 /** 1341 * In communication audio mode. An audio/video chat or VoIP call is established. 1342 */ 1343 public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION; 1344 1345 /* Routing bits for setRouting/getRouting API */ 1346 /** 1347 * Routing audio output to earpiece 1348 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1349 * setBluetoothScoOn() methods instead. 1350 */ 1351 @Deprecated public static final int ROUTE_EARPIECE = AudioSystem.ROUTE_EARPIECE; 1352 /** 1353 * Routing audio output to speaker 1354 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1355 * setBluetoothScoOn() methods instead. 1356 */ 1357 @Deprecated public static final int ROUTE_SPEAKER = AudioSystem.ROUTE_SPEAKER; 1358 /** 1359 * @deprecated use {@link #ROUTE_BLUETOOTH_SCO} 1360 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1361 * setBluetoothScoOn() methods instead. 1362 */ 1363 @Deprecated public static final int ROUTE_BLUETOOTH = AudioSystem.ROUTE_BLUETOOTH_SCO; 1364 /** 1365 * Routing audio output to bluetooth SCO 1366 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1367 * setBluetoothScoOn() methods instead. 1368 */ 1369 @Deprecated public static final int ROUTE_BLUETOOTH_SCO = AudioSystem.ROUTE_BLUETOOTH_SCO; 1370 /** 1371 * Routing audio output to headset 1372 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1373 * setBluetoothScoOn() methods instead. 1374 */ 1375 @Deprecated public static final int ROUTE_HEADSET = AudioSystem.ROUTE_HEADSET; 1376 /** 1377 * Routing audio output to bluetooth A2DP 1378 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1379 * setBluetoothScoOn() methods instead. 1380 */ 1381 @Deprecated public static final int ROUTE_BLUETOOTH_A2DP = AudioSystem.ROUTE_BLUETOOTH_A2DP; 1382 /** 1383 * Used for mask parameter of {@link #setRouting(int,int,int)}. 1384 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1385 * setBluetoothScoOn() methods instead. 1386 */ 1387 @Deprecated public static final int ROUTE_ALL = AudioSystem.ROUTE_ALL; 1388 1389 /** 1390 * Sets the audio routing for a specified mode 1391 * 1392 * @param mode audio mode to change route. E.g., MODE_RINGTONE. 1393 * @param routes bit vector of routes requested, created from one or 1394 * more of ROUTE_xxx types. Set bits indicate that route should be on 1395 * @param mask bit vector of routes to change, created from one or more of 1396 * ROUTE_xxx types. Unset bits indicate the route should be left unchanged 1397 * 1398 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1399 * setBluetoothScoOn() methods instead. 1400 */ 1401 @Deprecated 1402 public void setRouting(int mode, int routes, int mask) { 1403 } 1404 1405 /** 1406 * Returns the current audio routing bit vector for a specified mode. 1407 * 1408 * @param mode audio mode to get route (e.g., MODE_RINGTONE) 1409 * @return an audio route bit vector that can be compared with ROUTE_xxx 1410 * bits 1411 * @deprecated Do not query audio routing directly, use isSpeakerphoneOn(), 1412 * isBluetoothScoOn(), isBluetoothA2dpOn() and isWiredHeadsetOn() methods instead. 1413 */ 1414 @Deprecated 1415 public int getRouting(int mode) { 1416 return -1; 1417 } 1418 1419 /** 1420 * Checks whether any music is active. 1421 * 1422 * @return true if any music tracks are active. 1423 */ 1424 public boolean isMusicActive() { 1425 return AudioSystem.isStreamActive(STREAM_MUSIC, 0); 1426 } 1427 1428 /* 1429 * Sets a generic audio configuration parameter. The use of these parameters 1430 * are platform dependant, see libaudio 1431 * 1432 * ** Temporary interface - DO NOT USE 1433 * 1434 * TODO: Replace with a more generic key:value get/set mechanism 1435 * 1436 * param key name of parameter to set. Must not be null. 1437 * param value value of parameter. Must not be null. 1438 */ 1439 /** 1440 * @hide 1441 * @deprecated Use {@link #setPrameters(String)} instead 1442 */ 1443 @Deprecated public void setParameter(String key, String value) { 1444 setParameters(key+"="+value); 1445 } 1446 1447 /** 1448 * Sets a variable number of parameter values to audio hardware. 1449 * 1450 * @param keyValuePairs list of parameters key value pairs in the form: 1451 * key1=value1;key2=value2;... 1452 * 1453 */ 1454 public void setParameters(String keyValuePairs) { 1455 AudioSystem.setParameters(keyValuePairs); 1456 } 1457 1458 /** 1459 * Sets a varaible number of parameter values to audio hardware. 1460 * 1461 * @param keys list of parameters 1462 * @return list of parameters key value pairs in the form: 1463 * key1=value1;key2=value2;... 1464 */ 1465 public String getParameters(String keys) { 1466 return AudioSystem.getParameters(keys); 1467 } 1468 1469 /* Sound effect identifiers */ 1470 /** 1471 * Keyboard and direction pad click sound 1472 * @see #playSoundEffect(int) 1473 */ 1474 public static final int FX_KEY_CLICK = 0; 1475 /** 1476 * Focus has moved up 1477 * @see #playSoundEffect(int) 1478 */ 1479 public static final int FX_FOCUS_NAVIGATION_UP = 1; 1480 /** 1481 * Focus has moved down 1482 * @see #playSoundEffect(int) 1483 */ 1484 public static final int FX_FOCUS_NAVIGATION_DOWN = 2; 1485 /** 1486 * Focus has moved left 1487 * @see #playSoundEffect(int) 1488 */ 1489 public static final int FX_FOCUS_NAVIGATION_LEFT = 3; 1490 /** 1491 * Focus has moved right 1492 * @see #playSoundEffect(int) 1493 */ 1494 public static final int FX_FOCUS_NAVIGATION_RIGHT = 4; 1495 /** 1496 * IME standard keypress sound 1497 * @see #playSoundEffect(int) 1498 */ 1499 public static final int FX_KEYPRESS_STANDARD = 5; 1500 /** 1501 * IME spacebar keypress sound 1502 * @see #playSoundEffect(int) 1503 */ 1504 public static final int FX_KEYPRESS_SPACEBAR = 6; 1505 /** 1506 * IME delete keypress sound 1507 * @see #playSoundEffect(int) 1508 */ 1509 public static final int FX_KEYPRESS_DELETE = 7; 1510 /** 1511 * IME return_keypress sound 1512 * @see #playSoundEffect(int) 1513 */ 1514 public static final int FX_KEYPRESS_RETURN = 8; 1515 /** 1516 * @hide Number of sound effects 1517 */ 1518 public static final int NUM_SOUND_EFFECTS = 9; 1519 1520 /** 1521 * Plays a sound effect (Key clicks, lid open/close...) 1522 * @param effectType The type of sound effect. One of 1523 * {@link #FX_KEY_CLICK}, 1524 * {@link #FX_FOCUS_NAVIGATION_UP}, 1525 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 1526 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 1527 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 1528 * {@link #FX_KEYPRESS_STANDARD}, 1529 * {@link #FX_KEYPRESS_SPACEBAR}, 1530 * {@link #FX_KEYPRESS_DELETE}, 1531 * {@link #FX_KEYPRESS_RETURN}, 1532 * NOTE: This version uses the UI settings to determine 1533 * whether sounds are heard or not. 1534 */ 1535 public void playSoundEffect(int effectType) { 1536 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 1537 return; 1538 } 1539 1540 if (!querySoundEffectsEnabled()) { 1541 return; 1542 } 1543 1544 IAudioService service = getService(); 1545 try { 1546 service.playSoundEffect(effectType); 1547 } catch (RemoteException e) { 1548 Log.e(TAG, "Dead object in playSoundEffect"+e); 1549 } 1550 } 1551 1552 /** 1553 * Plays a sound effect (Key clicks, lid open/close...) 1554 * @param effectType The type of sound effect. One of 1555 * {@link #FX_KEY_CLICK}, 1556 * {@link #FX_FOCUS_NAVIGATION_UP}, 1557 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 1558 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 1559 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 1560 * {@link #FX_KEYPRESS_STANDARD}, 1561 * {@link #FX_KEYPRESS_SPACEBAR}, 1562 * {@link #FX_KEYPRESS_DELETE}, 1563 * {@link #FX_KEYPRESS_RETURN}, 1564 * @param volume Sound effect volume. 1565 * The volume value is a raw scalar so UI controls should be scaled logarithmically. 1566 * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used. 1567 * NOTE: This version is for applications that have their own 1568 * settings panel for enabling and controlling volume. 1569 */ 1570 public void playSoundEffect(int effectType, float volume) { 1571 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 1572 return; 1573 } 1574 1575 IAudioService service = getService(); 1576 try { 1577 service.playSoundEffectVolume(effectType, volume); 1578 } catch (RemoteException e) { 1579 Log.e(TAG, "Dead object in playSoundEffect"+e); 1580 } 1581 } 1582 1583 /** 1584 * Settings has an in memory cache, so this is fast. 1585 */ 1586 private boolean querySoundEffectsEnabled() { 1587 return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0; 1588 } 1589 1590 1591 /** 1592 * Load Sound effects. 1593 * This method must be called when sound effects are enabled. 1594 */ 1595 public void loadSoundEffects() { 1596 IAudioService service = getService(); 1597 try { 1598 service.loadSoundEffects(); 1599 } catch (RemoteException e) { 1600 Log.e(TAG, "Dead object in loadSoundEffects"+e); 1601 } 1602 } 1603 1604 /** 1605 * Unload Sound effects. 1606 * This method can be called to free some memory when 1607 * sound effects are disabled. 1608 */ 1609 public void unloadSoundEffects() { 1610 IAudioService service = getService(); 1611 try { 1612 service.unloadSoundEffects(); 1613 } catch (RemoteException e) { 1614 Log.e(TAG, "Dead object in unloadSoundEffects"+e); 1615 } 1616 } 1617 1618 /** 1619 * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration. 1620 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1621 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1622 */ 1623 public static final int AUDIOFOCUS_GAIN = 1; 1624 /** 1625 * Used to indicate a temporary gain or request of audio focus, anticipated to last a short 1626 * amount of time. Examples of temporary changes are the playback of driving directions, or an 1627 * event notification. 1628 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1629 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1630 */ 1631 public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2; 1632 /** 1633 * Used to indicate a temporary request of audio focus, anticipated to last a short 1634 * amount of time, and where it is acceptable for other audio applications to keep playing 1635 * after having lowered their output level (also referred to as "ducking"). 1636 * Examples of temporary changes are the playback of driving directions where playback of music 1637 * in the background is acceptable. 1638 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1639 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1640 */ 1641 public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3; 1642 /** 1643 * Used to indicate a loss of audio focus of unknown duration. 1644 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1645 */ 1646 public static final int AUDIOFOCUS_LOSS = -1 * AUDIOFOCUS_GAIN; 1647 /** 1648 * Used to indicate a transient loss of audio focus. 1649 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1650 */ 1651 public static final int AUDIOFOCUS_LOSS_TRANSIENT = -1 * AUDIOFOCUS_GAIN_TRANSIENT; 1652 /** 1653 * Used to indicate a transient loss of audio focus where the loser of the audio focus can 1654 * lower its output volume if it wants to continue playing (also referred to as "ducking"), as 1655 * the new focus owner doesn't require others to be silent. 1656 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1657 */ 1658 public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = 1659 -1 * AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK; 1660 1661 /** 1662 * Interface definition for a callback to be invoked when the audio focus of the system is 1663 * updated. 1664 */ 1665 public interface OnAudioFocusChangeListener { 1666 /** 1667 * Called on the listener to notify it the audio focus for this listener has been changed. 1668 * The focusChange value indicates whether the focus was gained, 1669 * whether the focus was lost, and whether that loss is transient, or whether the new focus 1670 * holder will hold it for an unknown amount of time. 1671 * When losing focus, listeners can use the focus change information to decide what 1672 * behavior to adopt when losing focus. A music player could for instance elect to lower 1673 * the volume of its music stream (duck) for transient focus losses, and pause otherwise. 1674 * @param focusChange the type of focus change, one of {@link AudioManager#AUDIOFOCUS_GAIN}, 1675 * {@link AudioManager#AUDIOFOCUS_LOSS}, {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT} 1676 * and {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}. 1677 */ 1678 public void onAudioFocusChange(int focusChange); 1679 } 1680 1681 /** 1682 * Map to convert focus event listener IDs, as used in the AudioService audio focus stack, 1683 * to actual listener objects. 1684 */ 1685 private HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap = 1686 new HashMap<String, OnAudioFocusChangeListener>(); 1687 /** 1688 * Lock to prevent concurrent changes to the list of focus listeners for this AudioManager 1689 * instance. 1690 */ 1691 private final Object mFocusListenerLock = new Object(); 1692 1693 private OnAudioFocusChangeListener findFocusListener(String id) { 1694 return mAudioFocusIdListenerMap.get(id); 1695 } 1696 1697 /** 1698 * Handler for audio focus events coming from the audio service. 1699 */ 1700 private FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate = 1701 new FocusEventHandlerDelegate(); 1702 1703 /** 1704 * Helper class to handle the forwarding of audio focus events to the appropriate listener 1705 */ 1706 private class FocusEventHandlerDelegate { 1707 private final Handler mHandler; 1708 1709 FocusEventHandlerDelegate() { 1710 Looper looper; 1711 if ((looper = Looper.myLooper()) == null) { 1712 looper = Looper.getMainLooper(); 1713 } 1714 1715 if (looper != null) { 1716 // implement the event handler delegate to receive audio focus events 1717 mHandler = new Handler(looper) { 1718 @Override 1719 public void handleMessage(Message msg) { 1720 OnAudioFocusChangeListener listener = null; 1721 synchronized(mFocusListenerLock) { 1722 listener = findFocusListener((String)msg.obj); 1723 } 1724 if (listener != null) { 1725 listener.onAudioFocusChange(msg.what); 1726 } 1727 } 1728 }; 1729 } else { 1730 mHandler = null; 1731 } 1732 } 1733 1734 Handler getHandler() { 1735 return mHandler; 1736 } 1737 } 1738 1739 private IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() { 1740 1741 public void dispatchAudioFocusChange(int focusChange, String id) { 1742 Message m = mAudioFocusEventHandlerDelegate.getHandler().obtainMessage(focusChange, id); 1743 mAudioFocusEventHandlerDelegate.getHandler().sendMessage(m); 1744 } 1745 1746 }; 1747 1748 private String getIdForAudioFocusListener(OnAudioFocusChangeListener l) { 1749 if (l == null) { 1750 return new String(this.toString()); 1751 } else { 1752 return new String(this.toString() + l.toString()); 1753 } 1754 } 1755 1756 /** 1757 * @hide 1758 * Registers a listener to be called when audio focus changes. Calling this method is optional 1759 * before calling {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, as it 1760 * will register the listener as well if it wasn't registered already. 1761 * @param l the listener to be notified of audio focus changes. 1762 */ 1763 public void registerAudioFocusListener(OnAudioFocusChangeListener l) { 1764 synchronized(mFocusListenerLock) { 1765 if (mAudioFocusIdListenerMap.containsKey(getIdForAudioFocusListener(l))) { 1766 return; 1767 } 1768 mAudioFocusIdListenerMap.put(getIdForAudioFocusListener(l), l); 1769 } 1770 } 1771 1772 /** 1773 * @hide 1774 * Causes the specified listener to not be called anymore when focus is gained or lost. 1775 * @param l the listener to unregister. 1776 */ 1777 public void unregisterAudioFocusListener(OnAudioFocusChangeListener l) { 1778 1779 // remove locally 1780 synchronized(mFocusListenerLock) { 1781 mAudioFocusIdListenerMap.remove(getIdForAudioFocusListener(l)); 1782 } 1783 } 1784 1785 1786 /** 1787 * A failed focus change request. 1788 */ 1789 public static final int AUDIOFOCUS_REQUEST_FAILED = 0; 1790 /** 1791 * A successful focus change request. 1792 */ 1793 public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; 1794 1795 1796 /** 1797 * Request audio focus. 1798 * Send a request to obtain the audio focus 1799 * @param l the listener to be notified of audio focus changes 1800 * @param streamType the main audio stream type affected by the focus request 1801 * @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request 1802 * is temporary, and focus will be abandonned shortly. Examples of transient requests are 1803 * for the playback of driving directions, or notifications sounds. 1804 * Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for 1805 * the previous focus owner to keep playing if it ducks its audio output. 1806 * Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such 1807 * as the playback of a song or a video. 1808 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 1809 */ 1810 public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) { 1811 int status = AUDIOFOCUS_REQUEST_FAILED; 1812 if ((durationHint < AUDIOFOCUS_GAIN) || (durationHint > AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)) 1813 { 1814 Log.e(TAG, "Invalid duration hint, audio focus request denied"); 1815 return status; 1816 } 1817 registerAudioFocusListener(l); 1818 //TODO protect request by permission check? 1819 IAudioService service = getService(); 1820 try { 1821 status = service.requestAudioFocus(streamType, durationHint, mICallBack, 1822 mAudioFocusDispatcher, getIdForAudioFocusListener(l), 1823 mContext.getPackageName() /* package name */); 1824 } catch (RemoteException e) { 1825 Log.e(TAG, "Can't call requestAudioFocus() from AudioService due to "+e); 1826 } 1827 return status; 1828 } 1829 1830 1831 /** 1832 * Abandon audio focus. Causes the previous focus owner, if any, to receive focus. 1833 * @param l the listener with which focus was requested. 1834 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 1835 */ 1836 public int abandonAudioFocus(OnAudioFocusChangeListener l) { 1837 int status = AUDIOFOCUS_REQUEST_FAILED; 1838 unregisterAudioFocusListener(l); 1839 IAudioService service = getService(); 1840 try { 1841 status = service.abandonAudioFocus(mAudioFocusDispatcher, 1842 getIdForAudioFocusListener(l)); 1843 } catch (RemoteException e) { 1844 Log.e(TAG, "Can't call abandonAudioFocus() from AudioService due to "+e); 1845 } 1846 return status; 1847 } 1848 1849 1850 //==================================================================== 1851 // Remote Control 1852 /** 1853 * Register a component to be the sole receiver of MEDIA_BUTTON intents. 1854 * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} 1855 * that will receive the media button intent. This broadcast receiver must be declared 1856 * in the application manifest. The package of the component must match that of 1857 * the context you're registering from. 1858 */ 1859 public void registerMediaButtonEventReceiver(ComponentName eventReceiver) { 1860 if (eventReceiver == null) { 1861 return; 1862 } 1863 if (!eventReceiver.getPackageName().equals(mContext.getPackageName())) { 1864 Log.e(TAG, "registerMediaButtonEventReceiver() error: " + 1865 "receiver and context package names don't match"); 1866 return; 1867 } 1868 // construct a PendingIntent for the media button and register it 1869 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 1870 // the associated intent will be handled by the component being registered 1871 mediaButtonIntent.setComponent(eventReceiver); 1872 PendingIntent pi = PendingIntent.getBroadcast(mContext, 1873 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); 1874 registerMediaButtonIntent(pi, eventReceiver); 1875 } 1876 1877 /** 1878 * @hide 1879 * no-op if (pi == null) or (eventReceiver == null) 1880 */ 1881 public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) { 1882 if ((pi == null) || (eventReceiver == null)) { 1883 Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null parameter"); 1884 return; 1885 } 1886 IAudioService service = getService(); 1887 try { 1888 // pi != null 1889 service.registerMediaButtonIntent(pi, eventReceiver); 1890 } catch (RemoteException e) { 1891 Log.e(TAG, "Dead object in registerMediaButtonIntent"+e); 1892 } 1893 } 1894 1895 /** 1896 * Unregister the receiver of MEDIA_BUTTON intents. 1897 * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} 1898 * that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}. 1899 */ 1900 public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) { 1901 if (eventReceiver == null) { 1902 return; 1903 } 1904 // construct a PendingIntent for the media button and unregister it 1905 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 1906 // the associated intent will be handled by the component being registered 1907 mediaButtonIntent.setComponent(eventReceiver); 1908 PendingIntent pi = PendingIntent.getBroadcast(mContext, 1909 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); 1910 unregisterMediaButtonIntent(pi, eventReceiver); 1911 } 1912 1913 /** 1914 * @hide 1915 */ 1916 public void unregisterMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) { 1917 IAudioService service = getService(); 1918 try { 1919 service.unregisterMediaButtonIntent(pi, eventReceiver); 1920 } catch (RemoteException e) { 1921 Log.e(TAG, "Dead object in unregisterMediaButtonIntent"+e); 1922 } 1923 } 1924 1925 /** 1926 * Registers the remote control client for providing information to display on the remote 1927 * controls. 1928 * @param rcClient The remote control client from which remote controls will receive 1929 * information to display. 1930 * @see RemoteControlClient 1931 */ 1932 public void registerRemoteControlClient(RemoteControlClient rcClient) { 1933 if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { 1934 return; 1935 } 1936 IAudioService service = getService(); 1937 try { 1938 service.registerRemoteControlClient(rcClient.getRcMediaIntent(), /* mediaIntent */ 1939 rcClient.getIRemoteControlClient(), /* rcClient */ 1940 // used to match media button event receiver and audio focus 1941 mContext.getPackageName()); /* packageName */ 1942 } catch (RemoteException e) { 1943 Log.e(TAG, "Dead object in registerRemoteControlClient"+e); 1944 } 1945 } 1946 1947 /** 1948 * Unregisters the remote control client that was providing information to display on the 1949 * remote controls. 1950 * @param rcClient The remote control client to unregister. 1951 * @see #registerRemoteControlClient(RemoteControlClient) 1952 */ 1953 public void unregisterRemoteControlClient(RemoteControlClient rcClient) { 1954 if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { 1955 return; 1956 } 1957 IAudioService service = getService(); 1958 try { 1959 service.unregisterRemoteControlClient(rcClient.getRcMediaIntent(), /* mediaIntent */ 1960 rcClient.getIRemoteControlClient()); /* rcClient */ 1961 } catch (RemoteException e) { 1962 Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e); 1963 } 1964 } 1965 1966 /** 1967 * @hide 1968 * Registers a remote control display that will be sent information by remote control clients. 1969 * @param rcd 1970 */ 1971 public void registerRemoteControlDisplay(IRemoteControlDisplay rcd) { 1972 if (rcd == null) { 1973 return; 1974 } 1975 IAudioService service = getService(); 1976 try { 1977 service.registerRemoteControlDisplay(rcd); 1978 } catch (RemoteException e) { 1979 Log.e(TAG, "Dead object in registerRemoteControlDisplay " + e); 1980 } 1981 } 1982 1983 /** 1984 * @hide 1985 * Unregisters a remote control display that was sent information by remote control clients. 1986 * @param rcd 1987 */ 1988 public void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) { 1989 if (rcd == null) { 1990 return; 1991 } 1992 IAudioService service = getService(); 1993 try { 1994 service.unregisterRemoteControlDisplay(rcd); 1995 } catch (RemoteException e) { 1996 Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e); 1997 } 1998 } 1999 2000 /** 2001 * @hide 2002 * Sets the artwork size a remote control display expects when receiving bitmaps. 2003 * @param rcd 2004 * @param w the maximum width of the expected bitmap. Negative values indicate it is 2005 * useless to send artwork. 2006 * @param h the maximum height of the expected bitmap. Negative values indicate it is 2007 * useless to send artwork. 2008 */ 2009 public void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) { 2010 if (rcd == null) { 2011 return; 2012 } 2013 IAudioService service = getService(); 2014 try { 2015 service.remoteControlDisplayUsesBitmapSize(rcd, w, h); 2016 } catch (RemoteException e) { 2017 Log.e(TAG, "Dead object in remoteControlDisplayUsesBitmapSize " + e); 2018 } 2019 } 2020 2021 // FIXME remove because we are not using intents anymore between AudioService and RcDisplay 2022 /** 2023 * @hide 2024 * Broadcast intent action indicating that the displays on the remote controls 2025 * should be updated because a new remote control client is now active. If there is no 2026 * {@link #EXTRA_REMOTE_CONTROL_CLIENT}, the remote control display should be cleared 2027 * because there is no valid client to supply it with information. 2028 * 2029 * @see #EXTRA_REMOTE_CONTROL_CLIENT 2030 */ 2031 public static final String REMOTE_CONTROL_CLIENT_CHANGED = 2032 "android.media.REMOTE_CONTROL_CLIENT_CHANGED"; 2033 2034 // FIXME remove because we are not using intents anymore between AudioService and RcDisplay 2035 /** 2036 * @hide 2037 * The IRemoteControlClientDispatcher monotonically increasing generation counter. 2038 * 2039 * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION 2040 */ 2041 public static final String EXTRA_REMOTE_CONTROL_CLIENT_GENERATION = 2042 "android.media.EXTRA_REMOTE_CONTROL_CLIENT_GENERATION"; 2043 2044 // FIXME remove because we are not using intents anymore between AudioService and RcDisplay 2045 /** 2046 * @hide 2047 * The name of the RemoteControlClient. 2048 * This String is passed as the client name when calling methods from the 2049 * IRemoteControlClientDispatcher interface. 2050 * 2051 * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION 2052 */ 2053 public static final String EXTRA_REMOTE_CONTROL_CLIENT_NAME = 2054 "android.media.EXTRA_REMOTE_CONTROL_CLIENT_NAME"; 2055 2056 // FIXME remove because we are not using intents anymore between AudioService and RcDisplay 2057 /** 2058 * @hide 2059 * The media button event receiver associated with the RemoteControlClient. 2060 * The {@link android.content.ComponentName} value of the event receiver can be retrieved with 2061 * {@link android.content.ComponentName#unflattenFromString(String)} 2062 * 2063 * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION 2064 */ 2065 public static final String EXTRA_REMOTE_CONTROL_EVENT_RECEIVER = 2066 "android.media.EXTRA_REMOTE_CONTROL_EVENT_RECEIVER"; 2067 2068 // FIXME remove because we are not using intents anymore between AudioService and RcDisplay 2069 /** 2070 * @hide 2071 * The flags describing what information has changed in the current remote control client. 2072 * 2073 * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION 2074 */ 2075 public static final String EXTRA_REMOTE_CONTROL_CLIENT_INFO_CHANGED = 2076 "android.media.EXTRA_REMOTE_CONTROL_CLIENT_INFO_CHANGED"; 2077 2078 /** 2079 * @hide 2080 * Reload audio settings. This method is called by Settings backup 2081 * agent when audio settings are restored and causes the AudioService 2082 * to read and apply restored settings. 2083 */ 2084 public void reloadAudioSettings() { 2085 IAudioService service = getService(); 2086 try { 2087 service.reloadAudioSettings(); 2088 } catch (RemoteException e) { 2089 Log.e(TAG, "Dead object in reloadAudioSettings"+e); 2090 } 2091 } 2092 2093 /** 2094 * {@hide} 2095 */ 2096 private IBinder mICallBack = new Binder(); 2097 2098 /** 2099 * Checks whether the phone is in silent mode, with or without vibrate. 2100 * 2101 * @return true if phone is in silent mode, with or without vibrate. 2102 * 2103 * @see #getRingerMode() 2104 * 2105 * @hide pending API Council approval 2106 */ 2107 public boolean isSilentMode() { 2108 int ringerMode = getRingerMode(); 2109 boolean silentMode = 2110 (ringerMode == RINGER_MODE_SILENT) || 2111 (ringerMode == RINGER_MODE_VIBRATE); 2112 return silentMode; 2113 } 2114 2115 // This section re-defines new output device constants from AudioSystem, because the AudioSystem 2116 // class is not used by other parts of the framework, which instead use definitions and methods 2117 // from AudioManager. AudioSystem is an internal class used by AudioManager and AudioService. 2118 2119 /** {@hide} The audio output device code for the small speaker at the front of the device used 2120 * when placing calls. Does not refer to an in-ear headphone without attached microphone, 2121 * such as earbuds, earphones, or in-ear monitors (IEM). Those would be handled as a 2122 * {@link #DEVICE_OUT_WIRED_HEADPHONE}. 2123 */ 2124 public static final int DEVICE_OUT_EARPIECE = AudioSystem.DEVICE_OUT_EARPIECE; 2125 /** {@hide} The audio output device code for the built-in speaker */ 2126 public static final int DEVICE_OUT_SPEAKER = AudioSystem.DEVICE_OUT_SPEAKER; 2127 /** {@hide} The audio output device code for a wired headset with attached microphone */ 2128 public static final int DEVICE_OUT_WIRED_HEADSET = AudioSystem.DEVICE_OUT_WIRED_HEADSET; 2129 /** {@hide} The audio output device code for a wired headphone without attached microphone */ 2130 public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE; 2131 /** {@hide} The audio output device code for generic Bluetooth SCO, for voice */ 2132 public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; 2133 /** {@hide} The audio output device code for Bluetooth SCO Headset Profile (HSP) and 2134 * Hands-Free Profile (HFP), for voice 2135 */ 2136 public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 2137 AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2138 /** {@hide} The audio output device code for Bluetooth SCO car audio, for voice */ 2139 public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 2140 AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2141 /** {@hide} The audio output device code for generic Bluetooth A2DP, for music */ 2142 public static final int DEVICE_OUT_BLUETOOTH_A2DP = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; 2143 /** {@hide} The audio output device code for Bluetooth A2DP headphones, for music */ 2144 public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 2145 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2146 /** {@hide} The audio output device code for Bluetooth A2DP external speaker, for music */ 2147 public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 2148 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2149 /** {@hide} The audio output device code for S/PDIF or HDMI */ 2150 public static final int DEVICE_OUT_AUX_DIGITAL = AudioSystem.DEVICE_OUT_AUX_DIGITAL; 2151 /** {@hide} The audio output device code for an analog wired headset attached via a 2152 * docking station 2153 */ 2154 public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET; 2155 /** {@hide} The audio output device code for a digital wired headset attached via a 2156 * docking station 2157 */ 2158 public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; 2159 /** {@hide} This is not used as a returned value from {@link #getDevicesForStream}, but could be 2160 * used in the future in a set method to select whatever default device is chosen by the 2161 * platform-specific implementation. 2162 */ 2163 public static final int DEVICE_OUT_DEFAULT = AudioSystem.DEVICE_OUT_DEFAULT; 2164 2165 /** 2166 * Return the enabled devices for the specified output stream type. 2167 * 2168 * @param streamType The stream type to query. One of 2169 * {@link #STREAM_VOICE_CALL}, 2170 * {@link #STREAM_SYSTEM}, 2171 * {@link #STREAM_RING}, 2172 * {@link #STREAM_MUSIC}, 2173 * {@link #STREAM_ALARM}, 2174 * {@link #STREAM_NOTIFICATION}, 2175 * {@link #STREAM_DTMF}. 2176 * 2177 * @return The bit-mask "or" of audio output device codes for all enabled devices on this 2178 * stream. Zero or more of 2179 * {@link #DEVICE_OUT_EARPIECE}, 2180 * {@link #DEVICE_OUT_SPEAKER}, 2181 * {@link #DEVICE_OUT_WIRED_HEADSET}, 2182 * {@link #DEVICE_OUT_WIRED_HEADPHONE}, 2183 * {@link #DEVICE_OUT_BLUETOOTH_SCO}, 2184 * {@link #DEVICE_OUT_BLUETOOTH_SCO_HEADSET}, 2185 * {@link #DEVICE_OUT_BLUETOOTH_SCO_CARKIT}, 2186 * {@link #DEVICE_OUT_BLUETOOTH_A2DP}, 2187 * {@link #DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES}, 2188 * {@link #DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER}, 2189 * {@link #DEVICE_OUT_AUX_DIGITAL}, 2190 * {@link #DEVICE_OUT_ANLG_DOCK_HEADSET}, 2191 * {@link #DEVICE_OUT_DGTL_DOCK_HEADSET}. 2192 * {@link #DEVICE_OUT_DEFAULT} is not used here. 2193 * 2194 * The implementation may support additional device codes beyond those listed, so 2195 * the application should ignore any bits which it does not recognize. 2196 * Note that the information may be imprecise when the implementation 2197 * cannot distinguish whether a particular device is enabled. 2198 * 2199 * {@hide} 2200 */ 2201 public int getDevicesForStream(int streamType) { 2202 switch (streamType) { 2203 case STREAM_VOICE_CALL: 2204 case STREAM_SYSTEM: 2205 case STREAM_RING: 2206 case STREAM_MUSIC: 2207 case STREAM_ALARM: 2208 case STREAM_NOTIFICATION: 2209 case STREAM_DTMF: 2210 return AudioSystem.getDevicesForStream(streamType); 2211 default: 2212 return 0; 2213 } 2214 } 2215 2216} 2217