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