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