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