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