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