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