AudioManager.java revision a8b6bd88cfb010c9e9aa1339e504fd593919e1e0
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.Manifest; 20import android.annotation.SdkConstant; 21import android.annotation.SdkConstant.SdkConstantType; 22import android.app.PendingIntent; 23import android.bluetooth.BluetoothDevice; 24import android.content.ComponentName; 25import android.content.Context; 26import android.content.Intent; 27import android.media.RemoteController.OnClientUpdateListener; 28import android.media.audiopolicy.AudioPolicy; 29import android.media.audiopolicy.AudioPolicyConfig; 30import android.media.session.MediaSessionLegacyHelper; 31import android.os.Binder; 32import android.os.Handler; 33import android.os.IBinder; 34import android.os.Looper; 35import android.os.Message; 36import android.os.RemoteException; 37import android.os.SystemClock; 38import android.os.ServiceManager; 39import android.provider.Settings; 40import android.util.Log; 41import android.view.KeyEvent; 42 43import java.util.HashMap; 44import java.util.ArrayList; 45 46 47/** 48 * AudioManager provides access to volume and ringer mode control. 49 * <p> 50 * Use <code>Context.getSystemService(Context.AUDIO_SERVICE)</code> to get 51 * an instance of this class. 52 */ 53public class AudioManager { 54 55 private final Context mContext; 56 private long mVolumeKeyUpTime; 57 private final boolean mUseMasterVolume; 58 private final boolean mUseVolumeKeySounds; 59 private final boolean mUseFixedVolume; 60 private final Binder mToken = new Binder(); 61 private static String TAG = "AudioManager"; 62 AudioPortEventHandler mAudioPortEventHandler; 63 64 /** 65 * Broadcast intent, a hint for applications that audio is about to become 66 * 'noisy' due to a change in audio outputs. For example, this intent may 67 * be sent when a wired headset is unplugged, or when an A2DP audio 68 * sink is disconnected, and the audio system is about to automatically 69 * switch audio route to the speaker. Applications that are controlling 70 * audio streams may consider pausing, reducing volume or some other action 71 * on receipt of this intent so as not to surprise the user with audio 72 * from the speaker. 73 */ 74 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 75 public static final String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY"; 76 77 /** 78 * Sticky broadcast intent action indicating that the ringer mode has 79 * changed. Includes the new ringer mode. 80 * 81 * @see #EXTRA_RINGER_MODE 82 */ 83 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 84 public static final String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED"; 85 86 /** 87 * The new ringer mode. 88 * 89 * @see #RINGER_MODE_CHANGED_ACTION 90 * @see #RINGER_MODE_NORMAL 91 * @see #RINGER_MODE_SILENT 92 * @see #RINGER_MODE_VIBRATE 93 */ 94 public static final String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE"; 95 96 /** 97 * Broadcast intent action indicating that the vibrate setting has 98 * changed. Includes the vibrate type and its new setting. 99 * 100 * @see #EXTRA_VIBRATE_TYPE 101 * @see #EXTRA_VIBRATE_SETTING 102 * @deprecated Applications should maintain their own vibrate policy based on 103 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 104 */ 105 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 106 public static final String VIBRATE_SETTING_CHANGED_ACTION = 107 "android.media.VIBRATE_SETTING_CHANGED"; 108 109 /** 110 * @hide Broadcast intent when the volume for a particular stream type changes. 111 * Includes the stream, the new volume and previous volumes. 112 * Notes: 113 * - for internal platform use only, do not make public, 114 * - never used for "remote" volume changes 115 * 116 * @see #EXTRA_VOLUME_STREAM_TYPE 117 * @see #EXTRA_VOLUME_STREAM_VALUE 118 * @see #EXTRA_PREV_VOLUME_STREAM_VALUE 119 */ 120 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 121 public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION"; 122 123 /** 124 * @hide Broadcast intent when the master volume changes. 125 * Includes the new volume 126 * 127 * @see #EXTRA_MASTER_VOLUME_VALUE 128 * @see #EXTRA_PREV_MASTER_VOLUME_VALUE 129 */ 130 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 131 public static final String MASTER_VOLUME_CHANGED_ACTION = 132 "android.media.MASTER_VOLUME_CHANGED_ACTION"; 133 134 /** 135 * @hide Broadcast intent when the master mute state changes. 136 * Includes the the new volume 137 * 138 * @see #EXTRA_MASTER_VOLUME_MUTED 139 */ 140 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 141 public static final String MASTER_MUTE_CHANGED_ACTION = 142 "android.media.MASTER_MUTE_CHANGED_ACTION"; 143 144 /** 145 * The new vibrate setting for a particular type. 146 * 147 * @see #VIBRATE_SETTING_CHANGED_ACTION 148 * @see #EXTRA_VIBRATE_TYPE 149 * @see #VIBRATE_SETTING_ON 150 * @see #VIBRATE_SETTING_OFF 151 * @see #VIBRATE_SETTING_ONLY_SILENT 152 * @deprecated Applications should maintain their own vibrate policy based on 153 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 154 */ 155 public static final String EXTRA_VIBRATE_SETTING = "android.media.EXTRA_VIBRATE_SETTING"; 156 157 /** 158 * The vibrate type whose setting has changed. 159 * 160 * @see #VIBRATE_SETTING_CHANGED_ACTION 161 * @see #VIBRATE_TYPE_NOTIFICATION 162 * @see #VIBRATE_TYPE_RINGER 163 * @deprecated Applications should maintain their own vibrate policy based on 164 * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead. 165 */ 166 public static final String EXTRA_VIBRATE_TYPE = "android.media.EXTRA_VIBRATE_TYPE"; 167 168 /** 169 * @hide The stream type for the volume changed intent. 170 */ 171 public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE"; 172 173 /** 174 * @hide The volume associated with the stream for the volume changed intent. 175 */ 176 public static final String EXTRA_VOLUME_STREAM_VALUE = 177 "android.media.EXTRA_VOLUME_STREAM_VALUE"; 178 179 /** 180 * @hide The previous volume associated with the stream for the volume changed intent. 181 */ 182 public static final String EXTRA_PREV_VOLUME_STREAM_VALUE = 183 "android.media.EXTRA_PREV_VOLUME_STREAM_VALUE"; 184 185 /** 186 * @hide The new master volume value for the master volume changed intent. 187 * Value is integer between 0 and 100 inclusive. 188 */ 189 public static final String EXTRA_MASTER_VOLUME_VALUE = 190 "android.media.EXTRA_MASTER_VOLUME_VALUE"; 191 192 /** 193 * @hide The previous master volume value for the master volume changed intent. 194 * Value is integer between 0 and 100 inclusive. 195 */ 196 public static final String EXTRA_PREV_MASTER_VOLUME_VALUE = 197 "android.media.EXTRA_PREV_MASTER_VOLUME_VALUE"; 198 199 /** 200 * @hide The new master volume mute state for the master mute changed intent. 201 * Value is boolean 202 */ 203 public static final String EXTRA_MASTER_VOLUME_MUTED = 204 "android.media.EXTRA_MASTER_VOLUME_MUTED"; 205 206 /** The audio stream for phone calls */ 207 public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL; 208 /** The audio stream for system sounds */ 209 public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM; 210 /** The audio stream for the phone ring */ 211 public static final int STREAM_RING = AudioSystem.STREAM_RING; 212 /** The audio stream for music playback */ 213 public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC; 214 /** The audio stream for alarms */ 215 public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM; 216 /** The audio stream for notifications */ 217 public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION; 218 /** @hide The audio stream for phone calls when connected to bluetooth */ 219 public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO; 220 /** @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */ 221 public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED; 222 /** The audio stream for DTMF Tones */ 223 public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF; 224 /** @hide The audio stream for text to speech (TTS) */ 225 public static final int STREAM_TTS = AudioSystem.STREAM_TTS; 226 /** Number of audio streams */ 227 /** 228 * @deprecated Use AudioSystem.getNumStreamTypes() instead 229 */ 230 @Deprecated public static final int NUM_STREAMS = AudioSystem.NUM_STREAMS; 231 232 233 /** @hide Default volume index values for audio streams */ 234 public static final int[] DEFAULT_STREAM_VOLUME = new int[] { 235 4, // STREAM_VOICE_CALL 236 7, // STREAM_SYSTEM 237 5, // STREAM_RING 238 11, // STREAM_MUSIC 239 6, // STREAM_ALARM 240 5, // STREAM_NOTIFICATION 241 7, // STREAM_BLUETOOTH_SCO 242 7, // STREAM_SYSTEM_ENFORCED 243 11, // STREAM_DTMF 244 11 // STREAM_TTS 245 }; 246 247 /** 248 * Increase the ringer volume. 249 * 250 * @see #adjustVolume(int, int) 251 * @see #adjustStreamVolume(int, int, int) 252 */ 253 public static final int ADJUST_RAISE = 1; 254 255 /** 256 * Decrease the ringer volume. 257 * 258 * @see #adjustVolume(int, int) 259 * @see #adjustStreamVolume(int, int, int) 260 */ 261 public static final int ADJUST_LOWER = -1; 262 263 /** 264 * Maintain the previous ringer volume. This may be useful when needing to 265 * show the volume toast without actually modifying the volume. 266 * 267 * @see #adjustVolume(int, int) 268 * @see #adjustStreamVolume(int, int, int) 269 */ 270 public static final int ADJUST_SAME = 0; 271 272 // Flags should be powers of 2! 273 274 /** 275 * Show a toast containing the current volume. 276 * 277 * @see #adjustStreamVolume(int, int, int) 278 * @see #adjustVolume(int, int) 279 * @see #setStreamVolume(int, int, int) 280 * @see #setRingerMode(int) 281 */ 282 public static final int FLAG_SHOW_UI = 1 << 0; 283 284 /** 285 * Whether to include ringer modes as possible options when changing volume. 286 * For example, if true and volume level is 0 and the volume is adjusted 287 * with {@link #ADJUST_LOWER}, then the ringer mode may switch the silent or 288 * vibrate mode. 289 * <p> 290 * By default this is on for the ring stream. If this flag is included, 291 * this behavior will be present regardless of the stream type being 292 * affected by the ringer mode. 293 * 294 * @see #adjustVolume(int, int) 295 * @see #adjustStreamVolume(int, int, int) 296 */ 297 public static final int FLAG_ALLOW_RINGER_MODES = 1 << 1; 298 299 /** 300 * Whether to play a sound when changing the volume. 301 * <p> 302 * If this is given to {@link #adjustVolume(int, int)} or 303 * {@link #adjustSuggestedStreamVolume(int, int, int)}, it may be ignored 304 * in some cases (for example, the decided stream type is not 305 * {@link AudioManager#STREAM_RING}, or the volume is being adjusted 306 * downward). 307 * 308 * @see #adjustStreamVolume(int, int, int) 309 * @see #adjustVolume(int, int) 310 * @see #setStreamVolume(int, int, int) 311 */ 312 public static final int FLAG_PLAY_SOUND = 1 << 2; 313 314 /** 315 * Removes any sounds/vibrate that may be in the queue, or are playing (related to 316 * changing volume). 317 */ 318 public static final int FLAG_REMOVE_SOUND_AND_VIBRATE = 1 << 3; 319 320 /** 321 * Whether to vibrate if going into the vibrate ringer mode. 322 */ 323 public static final int FLAG_VIBRATE = 1 << 4; 324 325 /** 326 * Indicates to VolumePanel that the volume slider should be disabled as user 327 * cannot change the stream volume 328 * @hide 329 */ 330 public static final int FLAG_FIXED_VOLUME = 1 << 5; 331 332 /** 333 * Indicates the volume set/adjust call is for Bluetooth absolute volume 334 * @hide 335 */ 336 public static final int FLAG_BLUETOOTH_ABS_VOLUME = 1 << 6; 337 338 /** 339 * Adjusting the volume was prevented due to silent mode, display a hint in the UI. 340 * @hide 341 */ 342 public static final int FLAG_SHOW_SILENT_HINT = 1 << 7; 343 344 /** 345 * Indicates the volume call is for Hdmi Cec system audio volume 346 * @hide 347 */ 348 public static final int FLAG_HDMI_SYSTEM_AUDIO_VOLUME = 1 << 8; 349 350 /** 351 * Indicates that this should only be handled if media is actively playing. 352 * @hide 353 */ 354 public static final int FLAG_ACTIVE_MEDIA_ONLY = 1 << 9; 355 356 /** 357 * Ringer mode that will be silent and will not vibrate. (This overrides the 358 * vibrate setting.) 359 * 360 * @see #setRingerMode(int) 361 * @see #getRingerMode() 362 */ 363 public static final int RINGER_MODE_SILENT = 0; 364 365 /** 366 * Ringer mode that will be silent and will vibrate. (This will cause the 367 * phone ringer to always vibrate, but the notification vibrate to only 368 * vibrate if set.) 369 * 370 * @see #setRingerMode(int) 371 * @see #getRingerMode() 372 */ 373 public static final int RINGER_MODE_VIBRATE = 1; 374 375 /** 376 * Ringer mode that may be audible and may vibrate. It will be audible if 377 * the volume before changing out of this mode was audible. It will vibrate 378 * if the vibrate setting is on. 379 * 380 * @see #setRingerMode(int) 381 * @see #getRingerMode() 382 */ 383 public static final int RINGER_MODE_NORMAL = 2; 384 385 // maximum valid ringer mode value. Values must start from 0 and be contiguous. 386 private static final int RINGER_MODE_MAX = RINGER_MODE_NORMAL; 387 388 /** 389 * Vibrate type that corresponds to the ringer. 390 * 391 * @see #setVibrateSetting(int, int) 392 * @see #getVibrateSetting(int) 393 * @see #shouldVibrate(int) 394 * @deprecated Applications should maintain their own vibrate policy based on 395 * current ringer mode that can be queried via {@link #getRingerMode()}. 396 */ 397 public static final int VIBRATE_TYPE_RINGER = 0; 398 399 /** 400 * Vibrate type that corresponds to notifications. 401 * 402 * @see #setVibrateSetting(int, int) 403 * @see #getVibrateSetting(int) 404 * @see #shouldVibrate(int) 405 * @deprecated Applications should maintain their own vibrate policy based on 406 * current ringer mode that can be queried via {@link #getRingerMode()}. 407 */ 408 public static final int VIBRATE_TYPE_NOTIFICATION = 1; 409 410 /** 411 * Vibrate setting that suggests to never vibrate. 412 * 413 * @see #setVibrateSetting(int, int) 414 * @see #getVibrateSetting(int) 415 * @deprecated Applications should maintain their own vibrate policy based on 416 * current ringer mode that can be queried via {@link #getRingerMode()}. 417 */ 418 public static final int VIBRATE_SETTING_OFF = 0; 419 420 /** 421 * Vibrate setting that suggests to vibrate when possible. 422 * 423 * @see #setVibrateSetting(int, int) 424 * @see #getVibrateSetting(int) 425 * @deprecated Applications should maintain their own vibrate policy based on 426 * current ringer mode that can be queried via {@link #getRingerMode()}. 427 */ 428 public static final int VIBRATE_SETTING_ON = 1; 429 430 /** 431 * Vibrate setting that suggests to only vibrate when in the vibrate ringer 432 * mode. 433 * 434 * @see #setVibrateSetting(int, int) 435 * @see #getVibrateSetting(int) 436 * @deprecated Applications should maintain their own vibrate policy based on 437 * current ringer mode that can be queried via {@link #getRingerMode()}. 438 */ 439 public static final int VIBRATE_SETTING_ONLY_SILENT = 2; 440 441 /** 442 * Suggests using the default stream type. This may not be used in all 443 * places a stream type is needed. 444 */ 445 public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE; 446 447 private static IAudioService sService; 448 449 /** 450 * @hide 451 */ 452 public AudioManager(Context context) { 453 mContext = context; 454 mUseMasterVolume = mContext.getResources().getBoolean( 455 com.android.internal.R.bool.config_useMasterVolume); 456 mUseVolumeKeySounds = mContext.getResources().getBoolean( 457 com.android.internal.R.bool.config_useVolumeKeySounds); 458 mAudioPortEventHandler = new AudioPortEventHandler(this); 459 mUseFixedVolume = mContext.getResources().getBoolean( 460 com.android.internal.R.bool.config_useFixedVolume); 461 } 462 463 private static IAudioService getService() 464 { 465 if (sService != null) { 466 return sService; 467 } 468 IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); 469 sService = IAudioService.Stub.asInterface(b); 470 return sService; 471 } 472 473 /** 474 * Sends a simulated key event for a media button. 475 * To simulate a key press, you must first send a KeyEvent built with a 476 * {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP} 477 * action. 478 * <p>The key event will be sent to the current media key event consumer which registered with 479 * {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}. 480 * @param keyEvent a {@link KeyEvent} instance whose key code is one of 481 * {@link KeyEvent#KEYCODE_MUTE}, 482 * {@link KeyEvent#KEYCODE_HEADSETHOOK}, 483 * {@link KeyEvent#KEYCODE_MEDIA_PLAY}, 484 * {@link KeyEvent#KEYCODE_MEDIA_PAUSE}, 485 * {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE}, 486 * {@link KeyEvent#KEYCODE_MEDIA_STOP}, 487 * {@link KeyEvent#KEYCODE_MEDIA_NEXT}, 488 * {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}, 489 * {@link KeyEvent#KEYCODE_MEDIA_REWIND}, 490 * {@link KeyEvent#KEYCODE_MEDIA_RECORD}, 491 * {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD}, 492 * {@link KeyEvent#KEYCODE_MEDIA_CLOSE}, 493 * {@link KeyEvent#KEYCODE_MEDIA_EJECT}, 494 * or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}. 495 */ 496 public void dispatchMediaKeyEvent(KeyEvent keyEvent) { 497 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 498 helper.sendMediaButtonEvent(keyEvent, false); 499 } 500 501 /** 502 * @hide 503 */ 504 public void preDispatchKeyEvent(KeyEvent event, int stream) { 505 /* 506 * If the user hits another key within the play sound delay, then 507 * cancel the sound 508 */ 509 int keyCode = event.getKeyCode(); 510 if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP 511 && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE 512 && mVolumeKeyUpTime + AudioService.PLAY_SOUND_DELAY 513 > SystemClock.uptimeMillis()) { 514 /* 515 * The user has hit another key during the delay (e.g., 300ms) 516 * since the last volume key up, so cancel any sounds. 517 */ 518 if (mUseMasterVolume) { 519 adjustMasterVolume(ADJUST_SAME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 520 } else { 521 adjustSuggestedStreamVolume(ADJUST_SAME, 522 stream, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 523 } 524 } 525 } 526 527 /** 528 * @hide 529 */ 530 public void handleKeyDown(KeyEvent event, int stream) { 531 int keyCode = event.getKeyCode(); 532 switch (keyCode) { 533 case KeyEvent.KEYCODE_VOLUME_UP: 534 case KeyEvent.KEYCODE_VOLUME_DOWN: 535 /* 536 * Adjust the volume in on key down since it is more 537 * responsive to the user. 538 */ 539 int flags = FLAG_SHOW_UI | FLAG_VIBRATE; 540 541 if (mUseMasterVolume) { 542 adjustMasterVolume( 543 keyCode == KeyEvent.KEYCODE_VOLUME_UP 544 ? ADJUST_RAISE 545 : ADJUST_LOWER, 546 flags); 547 } else { 548 adjustSuggestedStreamVolume( 549 keyCode == KeyEvent.KEYCODE_VOLUME_UP 550 ? ADJUST_RAISE 551 : ADJUST_LOWER, 552 stream, 553 flags); 554 } 555 break; 556 case KeyEvent.KEYCODE_VOLUME_MUTE: 557 if (event.getRepeatCount() == 0) { 558 if (mUseMasterVolume) { 559 setMasterMute(!isMasterMute()); 560 } else { 561 // TODO: Actually handle MUTE. 562 } 563 } 564 break; 565 } 566 } 567 568 /** 569 * @hide 570 */ 571 public void handleKeyUp(KeyEvent event, int stream) { 572 int keyCode = event.getKeyCode(); 573 switch (keyCode) { 574 case KeyEvent.KEYCODE_VOLUME_UP: 575 case KeyEvent.KEYCODE_VOLUME_DOWN: 576 /* 577 * Play a sound. This is done on key up since we don't want the 578 * sound to play when a user holds down volume down to mute. 579 */ 580 if (mUseVolumeKeySounds) { 581 if (mUseMasterVolume) { 582 adjustMasterVolume(ADJUST_SAME, FLAG_PLAY_SOUND); 583 } else { 584 int flags = FLAG_PLAY_SOUND; 585 adjustSuggestedStreamVolume( 586 ADJUST_SAME, 587 stream, 588 flags); 589 } 590 } 591 mVolumeKeyUpTime = SystemClock.uptimeMillis(); 592 break; 593 } 594 } 595 596 /** 597 * Indicates if the device implements a fixed volume policy. 598 * <p>Some devices may not have volume control and may operate at a fixed volume, 599 * and may not enable muting or changing the volume of audio streams. 600 * This method will return true on such devices. 601 * <p>The following APIs have no effect when volume is fixed: 602 * <ul> 603 * <li> {@link #adjustVolume(int, int)} 604 * <li> {@link #adjustSuggestedStreamVolume(int, int, int)} 605 * <li> {@link #adjustStreamVolume(int, int, int)} 606 * <li> {@link #setStreamVolume(int, int, int)} 607 * <li> {@link #setRingerMode(int)} 608 * <li> {@link #setStreamSolo(int, boolean)} 609 * <li> {@link #setStreamMute(int, boolean)} 610 * </ul> 611 */ 612 public boolean isVolumeFixed() { 613 return mUseFixedVolume; 614 } 615 616 /** 617 * Adjusts the volume of a particular stream by one step in a direction. 618 * <p> 619 * This method should only be used by applications that replace the platform-wide 620 * management of audio settings or the main telephony application. 621 * 622 * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL}, 623 * {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC} or 624 * {@link #STREAM_ALARM} 625 * @param direction The direction to adjust the volume. One of 626 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 627 * {@link #ADJUST_SAME}. 628 * @param flags One or more flags. 629 * @see #adjustVolume(int, int) 630 * @see #setStreamVolume(int, int, int) 631 */ 632 public void adjustStreamVolume(int streamType, int direction, int flags) { 633 IAudioService service = getService(); 634 try { 635 if (mUseMasterVolume) { 636 service.adjustMasterVolume(direction, flags, mContext.getOpPackageName()); 637 } else { 638 service.adjustStreamVolume(streamType, direction, flags, 639 mContext.getOpPackageName()); 640 } 641 } catch (RemoteException e) { 642 Log.e(TAG, "Dead object in adjustStreamVolume", e); 643 } 644 } 645 646 /** 647 * Adjusts the volume of the most relevant stream. For example, if a call is 648 * active, it will have the highest priority regardless of if the in-call 649 * screen is showing. Another example, if music is playing in the background 650 * and a call is not active, the music stream will be adjusted. 651 * <p> 652 * This method should only be used by applications that replace the platform-wide 653 * management of audio settings or the main telephony application. 654 * <p>This method has no effect if the device implements a fixed volume policy 655 * as indicated by {@link #isVolumeFixed()}. 656 * @param direction The direction to adjust the volume. One of 657 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 658 * {@link #ADJUST_SAME}. 659 * @param flags One or more flags. 660 * @see #adjustSuggestedStreamVolume(int, int, int) 661 * @see #adjustStreamVolume(int, int, int) 662 * @see #setStreamVolume(int, int, int) 663 * @see #isVolumeFixed() 664 */ 665 public void adjustVolume(int direction, int flags) { 666 IAudioService service = getService(); 667 try { 668 if (mUseMasterVolume) { 669 service.adjustMasterVolume(direction, flags, mContext.getOpPackageName()); 670 } else { 671 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 672 helper.sendAdjustVolumeBy(USE_DEFAULT_STREAM_TYPE, direction, flags); 673 } 674 } catch (RemoteException e) { 675 Log.e(TAG, "Dead object in adjustVolume", e); 676 } 677 } 678 679 /** 680 * Adjusts the volume of the most relevant stream, or the given fallback 681 * stream. 682 * <p> 683 * This method should only be used by applications that replace the platform-wide 684 * management of audio settings or the main telephony application. 685 * 686 * <p>This method has no effect if the device implements a fixed volume policy 687 * as indicated by {@link #isVolumeFixed()}. 688 * @param direction The direction to adjust the volume. One of 689 * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or 690 * {@link #ADJUST_SAME}. 691 * @param suggestedStreamType The stream type that will be used if there 692 * isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is valid here. 693 * @param flags One or more flags. 694 * @see #adjustVolume(int, int) 695 * @see #adjustStreamVolume(int, int, int) 696 * @see #setStreamVolume(int, int, int) 697 * @see #isVolumeFixed() 698 */ 699 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) { 700 IAudioService service = getService(); 701 try { 702 if (mUseMasterVolume) { 703 service.adjustMasterVolume(direction, flags, mContext.getOpPackageName()); 704 } else { 705 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 706 helper.sendAdjustVolumeBy(suggestedStreamType, direction, flags); 707 } 708 } catch (RemoteException e) { 709 Log.e(TAG, "Dead object in adjustSuggestedStreamVolume", e); 710 } 711 } 712 713 /** 714 * Adjusts the master volume for the device's audio amplifier. 715 * <p> 716 * 717 * @param steps The number of volume steps to adjust. A positive 718 * value will raise the volume. 719 * @param flags One or more flags. 720 * @hide 721 */ 722 public void adjustMasterVolume(int steps, int flags) { 723 IAudioService service = getService(); 724 try { 725 service.adjustMasterVolume(steps, flags, mContext.getOpPackageName()); 726 } catch (RemoteException e) { 727 Log.e(TAG, "Dead object in adjustMasterVolume", e); 728 } 729 } 730 731 /** 732 * Returns the current ringtone mode. 733 * 734 * @return The current ringtone mode, one of {@link #RINGER_MODE_NORMAL}, 735 * {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}. 736 * @see #setRingerMode(int) 737 */ 738 public int getRingerMode() { 739 IAudioService service = getService(); 740 try { 741 return service.getRingerMode(); 742 } catch (RemoteException e) { 743 Log.e(TAG, "Dead object in getRingerMode", e); 744 return RINGER_MODE_NORMAL; 745 } 746 } 747 748 /** 749 * Checks valid ringer mode values. 750 * 751 * @return true if the ringer mode indicated is valid, false otherwise. 752 * 753 * @see #setRingerMode(int) 754 * @hide 755 */ 756 public static boolean isValidRingerMode(int ringerMode) { 757 if (ringerMode < 0 || ringerMode > RINGER_MODE_MAX) { 758 return false; 759 } 760 return true; 761 } 762 763 /** 764 * Returns the maximum volume index for a particular stream. 765 * 766 * @param streamType The stream type whose maximum volume index is returned. 767 * @return The maximum valid volume index for the stream. 768 * @see #getStreamVolume(int) 769 */ 770 public int getStreamMaxVolume(int streamType) { 771 IAudioService service = getService(); 772 try { 773 if (mUseMasterVolume) { 774 return service.getMasterMaxVolume(); 775 } else { 776 return service.getStreamMaxVolume(streamType); 777 } 778 } catch (RemoteException e) { 779 Log.e(TAG, "Dead object in getStreamMaxVolume", e); 780 return 0; 781 } 782 } 783 784 /** 785 * Returns the current volume index for a particular stream. 786 * 787 * @param streamType The stream type whose volume index is returned. 788 * @return The current volume index for the stream. 789 * @see #getStreamMaxVolume(int) 790 * @see #setStreamVolume(int, int, int) 791 */ 792 public int getStreamVolume(int streamType) { 793 IAudioService service = getService(); 794 try { 795 if (mUseMasterVolume) { 796 return service.getMasterVolume(); 797 } else { 798 return service.getStreamVolume(streamType); 799 } 800 } catch (RemoteException e) { 801 Log.e(TAG, "Dead object in getStreamVolume", e); 802 return 0; 803 } 804 } 805 806 /** 807 * Get last audible volume before stream was muted. 808 * 809 * @hide 810 */ 811 public int getLastAudibleStreamVolume(int streamType) { 812 IAudioService service = getService(); 813 try { 814 if (mUseMasterVolume) { 815 return service.getLastAudibleMasterVolume(); 816 } else { 817 return service.getLastAudibleStreamVolume(streamType); 818 } 819 } catch (RemoteException e) { 820 Log.e(TAG, "Dead object in getLastAudibleStreamVolume", e); 821 return 0; 822 } 823 } 824 825 /** 826 * Get the stream type whose volume is driving the UI sounds volume. 827 * UI sounds are screen lock/unlock, camera shutter, key clicks... 828 * @hide 829 */ 830 public int getMasterStreamType() { 831 IAudioService service = getService(); 832 try { 833 return service.getMasterStreamType(); 834 } catch (RemoteException e) { 835 Log.e(TAG, "Dead object in getMasterStreamType", e); 836 return STREAM_RING; 837 } 838 } 839 840 /** 841 * Sets the ringer mode. 842 * <p> 843 * Silent mode will mute the volume and will not vibrate. Vibrate mode will 844 * mute the volume and vibrate. Normal mode will be audible and may vibrate 845 * according to user settings. 846 * <p>This method has no effect if the device implements a fixed volume policy 847 * as indicated by {@link #isVolumeFixed()}. 848 * @param ringerMode The ringer mode, one of {@link #RINGER_MODE_NORMAL}, 849 * {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}. 850 * @see #getRingerMode() 851 * @see #isVolumeFixed() 852 */ 853 public void setRingerMode(int ringerMode) { 854 if (!isValidRingerMode(ringerMode)) { 855 return; 856 } 857 IAudioService service = getService(); 858 try { 859 service.setRingerMode(ringerMode); 860 } catch (RemoteException e) { 861 Log.e(TAG, "Dead object in setRingerMode", e); 862 } 863 } 864 865 /** 866 * Sets the volume index for a particular stream. 867 * <p>This method has no effect if the device implements a fixed volume policy 868 * as indicated by {@link #isVolumeFixed()}. 869 * @param streamType The stream whose volume index should be set. 870 * @param index The volume index to set. See 871 * {@link #getStreamMaxVolume(int)} for the largest valid value. 872 * @param flags One or more flags. 873 * @see #getStreamMaxVolume(int) 874 * @see #getStreamVolume(int) 875 * @see #isVolumeFixed() 876 */ 877 public void setStreamVolume(int streamType, int index, int flags) { 878 IAudioService service = getService(); 879 try { 880 if (mUseMasterVolume) { 881 service.setMasterVolume(index, flags, mContext.getOpPackageName()); 882 } else { 883 service.setStreamVolume(streamType, index, flags, mContext.getOpPackageName()); 884 } 885 } catch (RemoteException e) { 886 Log.e(TAG, "Dead object in setStreamVolume", e); 887 } 888 } 889 890 /** 891 * Returns the maximum volume index for master volume. 892 * 893 * @hide 894 */ 895 public int getMasterMaxVolume() { 896 IAudioService service = getService(); 897 try { 898 return service.getMasterMaxVolume(); 899 } catch (RemoteException e) { 900 Log.e(TAG, "Dead object in getMasterMaxVolume", e); 901 return 0; 902 } 903 } 904 905 /** 906 * Returns the current volume index for master volume. 907 * 908 * @return The current volume index for master volume. 909 * @hide 910 */ 911 public int getMasterVolume() { 912 IAudioService service = getService(); 913 try { 914 return service.getMasterVolume(); 915 } catch (RemoteException e) { 916 Log.e(TAG, "Dead object in getMasterVolume", e); 917 return 0; 918 } 919 } 920 921 /** 922 * Get last audible volume before master volume was muted. 923 * 924 * @hide 925 */ 926 public int getLastAudibleMasterVolume() { 927 IAudioService service = getService(); 928 try { 929 return service.getLastAudibleMasterVolume(); 930 } catch (RemoteException e) { 931 Log.e(TAG, "Dead object in getLastAudibleMasterVolume", e); 932 return 0; 933 } 934 } 935 936 /** 937 * Sets the volume index for master volume. 938 * 939 * @param index The volume index to set. See 940 * {@link #getMasterMaxVolume()} for the largest valid value. 941 * @param flags One or more flags. 942 * @see #getMasterMaxVolume() 943 * @see #getMasterVolume() 944 * @hide 945 */ 946 public void setMasterVolume(int index, int flags) { 947 IAudioService service = getService(); 948 try { 949 service.setMasterVolume(index, flags, mContext.getOpPackageName()); 950 } catch (RemoteException e) { 951 Log.e(TAG, "Dead object in setMasterVolume", e); 952 } 953 } 954 955 /** 956 * Solo or unsolo a particular stream. All other streams are muted. 957 * <p> 958 * The solo command is protected against client process death: if a process 959 * with an active solo request on a stream dies, all streams that were muted 960 * because of this request will be unmuted automatically. 961 * <p> 962 * The solo requests for a given stream are cumulative: the AudioManager 963 * can receive several solo requests from one or more clients and the stream 964 * will be unsoloed only when the same number of unsolo requests are received. 965 * <p> 966 * For a better user experience, applications MUST unsolo a soloed stream 967 * in onPause() and solo is again in onResume() if appropriate. 968 * <p>This method has no effect if the device implements a fixed volume policy 969 * as indicated by {@link #isVolumeFixed()}. 970 * 971 * @param streamType The stream to be soloed/unsoloed. 972 * @param state The required solo state: true for solo ON, false for solo OFF 973 * 974 * @see #isVolumeFixed() 975 */ 976 public void setStreamSolo(int streamType, boolean state) { 977 IAudioService service = getService(); 978 try { 979 service.setStreamSolo(streamType, state, mICallBack); 980 } catch (RemoteException e) { 981 Log.e(TAG, "Dead object in setStreamSolo", e); 982 } 983 } 984 985 /** 986 * Mute or unmute an audio stream. 987 * <p> 988 * The mute command is protected against client process death: if a process 989 * with an active mute request on a stream dies, this stream will be unmuted 990 * automatically. 991 * <p> 992 * The mute requests for a given stream are cumulative: the AudioManager 993 * can receive several mute requests from one or more clients and the stream 994 * will be unmuted only when the same number of unmute requests are received. 995 * <p> 996 * For a better user experience, applications MUST unmute a muted stream 997 * in onPause() and mute is again in onResume() if appropriate. 998 * <p> 999 * This method should only be used by applications that replace the platform-wide 1000 * management of audio settings or the main telephony application. 1001 * <p>This method has no effect if the device implements a fixed volume policy 1002 * as indicated by {@link #isVolumeFixed()}. 1003 * 1004 * @param streamType The stream to be muted/unmuted. 1005 * @param state The required mute state: true for mute ON, false for mute OFF 1006 * 1007 * @see #isVolumeFixed() 1008 */ 1009 public void setStreamMute(int streamType, boolean state) { 1010 IAudioService service = getService(); 1011 try { 1012 service.setStreamMute(streamType, state, mICallBack); 1013 } catch (RemoteException e) { 1014 Log.e(TAG, "Dead object in setStreamMute", e); 1015 } 1016 } 1017 1018 /** 1019 * get stream mute state. 1020 * 1021 * @hide 1022 */ 1023 public boolean isStreamMute(int streamType) { 1024 IAudioService service = getService(); 1025 try { 1026 return service.isStreamMute(streamType); 1027 } catch (RemoteException e) { 1028 Log.e(TAG, "Dead object in isStreamMute", e); 1029 return false; 1030 } 1031 } 1032 1033 /** 1034 * set master mute state. 1035 * 1036 * @hide 1037 */ 1038 public void setMasterMute(boolean state) { 1039 setMasterMute(state, FLAG_SHOW_UI); 1040 } 1041 1042 /** 1043 * set master mute state with optional flags. 1044 * 1045 * @hide 1046 */ 1047 public void setMasterMute(boolean state, int flags) { 1048 IAudioService service = getService(); 1049 try { 1050 service.setMasterMute(state, flags, mContext.getOpPackageName(), mICallBack); 1051 } catch (RemoteException e) { 1052 Log.e(TAG, "Dead object in setMasterMute", e); 1053 } 1054 } 1055 1056 /** 1057 * get master mute state. 1058 * 1059 * @hide 1060 */ 1061 public boolean isMasterMute() { 1062 IAudioService service = getService(); 1063 try { 1064 return service.isMasterMute(); 1065 } catch (RemoteException e) { 1066 Log.e(TAG, "Dead object in isMasterMute", e); 1067 return false; 1068 } 1069 } 1070 1071 /** 1072 * forces the stream controlled by hard volume keys 1073 * specifying streamType == -1 releases control to the 1074 * logic. 1075 * 1076 * @hide 1077 */ 1078 public void forceVolumeControlStream(int streamType) { 1079 IAudioService service = getService(); 1080 try { 1081 service.forceVolumeControlStream(streamType, mICallBack); 1082 } catch (RemoteException e) { 1083 Log.e(TAG, "Dead object in forceVolumeControlStream", e); 1084 } 1085 } 1086 1087 /** 1088 * Returns whether a particular type should vibrate according to user 1089 * settings and the current ringer mode. 1090 * <p> 1091 * This shouldn't be needed by most clients that use notifications to 1092 * vibrate. The notification manager will not vibrate if the policy doesn't 1093 * allow it, so the client should always set a vibrate pattern and let the 1094 * notification manager control whether or not to actually vibrate. 1095 * 1096 * @param vibrateType The type of vibrate. One of 1097 * {@link #VIBRATE_TYPE_NOTIFICATION} or 1098 * {@link #VIBRATE_TYPE_RINGER}. 1099 * @return Whether the type should vibrate at the instant this method is 1100 * called. 1101 * @see #setVibrateSetting(int, int) 1102 * @see #getVibrateSetting(int) 1103 * @deprecated Applications should maintain their own vibrate policy based on 1104 * current ringer mode that can be queried via {@link #getRingerMode()}. 1105 */ 1106 public boolean shouldVibrate(int vibrateType) { 1107 IAudioService service = getService(); 1108 try { 1109 return service.shouldVibrate(vibrateType); 1110 } catch (RemoteException e) { 1111 Log.e(TAG, "Dead object in shouldVibrate", e); 1112 return false; 1113 } 1114 } 1115 1116 /** 1117 * Returns whether the user's vibrate setting for a vibrate type. 1118 * <p> 1119 * This shouldn't be needed by most clients that want to vibrate, instead 1120 * see {@link #shouldVibrate(int)}. 1121 * 1122 * @param vibrateType The type of vibrate. One of 1123 * {@link #VIBRATE_TYPE_NOTIFICATION} or 1124 * {@link #VIBRATE_TYPE_RINGER}. 1125 * @return The vibrate setting, one of {@link #VIBRATE_SETTING_ON}, 1126 * {@link #VIBRATE_SETTING_OFF}, or 1127 * {@link #VIBRATE_SETTING_ONLY_SILENT}. 1128 * @see #setVibrateSetting(int, int) 1129 * @see #shouldVibrate(int) 1130 * @deprecated Applications should maintain their own vibrate policy based on 1131 * current ringer mode that can be queried via {@link #getRingerMode()}. 1132 */ 1133 public int getVibrateSetting(int vibrateType) { 1134 IAudioService service = getService(); 1135 try { 1136 return service.getVibrateSetting(vibrateType); 1137 } catch (RemoteException e) { 1138 Log.e(TAG, "Dead object in getVibrateSetting", e); 1139 return VIBRATE_SETTING_OFF; 1140 } 1141 } 1142 1143 /** 1144 * Sets the setting for when the vibrate type should vibrate. 1145 * <p> 1146 * This method should only be used by applications that replace the platform-wide 1147 * management of audio settings or the main telephony application. 1148 * 1149 * @param vibrateType The type of vibrate. One of 1150 * {@link #VIBRATE_TYPE_NOTIFICATION} or 1151 * {@link #VIBRATE_TYPE_RINGER}. 1152 * @param vibrateSetting The vibrate setting, one of 1153 * {@link #VIBRATE_SETTING_ON}, 1154 * {@link #VIBRATE_SETTING_OFF}, or 1155 * {@link #VIBRATE_SETTING_ONLY_SILENT}. 1156 * @see #getVibrateSetting(int) 1157 * @see #shouldVibrate(int) 1158 * @deprecated Applications should maintain their own vibrate policy based on 1159 * current ringer mode that can be queried via {@link #getRingerMode()}. 1160 */ 1161 public void setVibrateSetting(int vibrateType, int vibrateSetting) { 1162 IAudioService service = getService(); 1163 try { 1164 service.setVibrateSetting(vibrateType, vibrateSetting); 1165 } catch (RemoteException e) { 1166 Log.e(TAG, "Dead object in setVibrateSetting", e); 1167 } 1168 } 1169 1170 /** 1171 * Sets the speakerphone on or off. 1172 * <p> 1173 * This method should only be used by applications that replace the platform-wide 1174 * management of audio settings or the main telephony application. 1175 * 1176 * @param on set <var>true</var> to turn on speakerphone; 1177 * <var>false</var> to turn it off 1178 */ 1179 public void setSpeakerphoneOn(boolean on){ 1180 IAudioService service = getService(); 1181 try { 1182 service.setSpeakerphoneOn(on); 1183 } catch (RemoteException e) { 1184 Log.e(TAG, "Dead object in setSpeakerphoneOn", e); 1185 } 1186 } 1187 1188 /** 1189 * Checks whether the speakerphone is on or off. 1190 * 1191 * @return true if speakerphone is on, false if it's off 1192 */ 1193 public boolean isSpeakerphoneOn() { 1194 IAudioService service = getService(); 1195 try { 1196 return service.isSpeakerphoneOn(); 1197 } catch (RemoteException e) { 1198 Log.e(TAG, "Dead object in isSpeakerphoneOn", e); 1199 return false; 1200 } 1201 } 1202 1203 //==================================================================== 1204 // Bluetooth SCO control 1205 /** 1206 * Sticky broadcast intent action indicating that the bluetoooth SCO audio 1207 * connection state has changed. The intent contains on extra {@link #EXTRA_SCO_AUDIO_STATE} 1208 * indicating the new state which is either {@link #SCO_AUDIO_STATE_DISCONNECTED} 1209 * or {@link #SCO_AUDIO_STATE_CONNECTED} 1210 * 1211 * @see #startBluetoothSco() 1212 * @deprecated Use {@link #ACTION_SCO_AUDIO_STATE_UPDATED} instead 1213 */ 1214 @Deprecated 1215 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1216 public static final String ACTION_SCO_AUDIO_STATE_CHANGED = 1217 "android.media.SCO_AUDIO_STATE_CHANGED"; 1218 1219 /** 1220 * Sticky broadcast intent action indicating that the bluetoooth SCO audio 1221 * connection state has been updated. 1222 * <p>This intent has two extras: 1223 * <ul> 1224 * <li> {@link #EXTRA_SCO_AUDIO_STATE} - The new SCO audio state. </li> 1225 * <li> {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE}- The previous SCO audio state. </li> 1226 * </ul> 1227 * <p> EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE can be any of: 1228 * <ul> 1229 * <li> {@link #SCO_AUDIO_STATE_DISCONNECTED}, </li> 1230 * <li> {@link #SCO_AUDIO_STATE_CONNECTING} or </li> 1231 * <li> {@link #SCO_AUDIO_STATE_CONNECTED}, </li> 1232 * </ul> 1233 * @see #startBluetoothSco() 1234 */ 1235 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1236 public static final String ACTION_SCO_AUDIO_STATE_UPDATED = 1237 "android.media.ACTION_SCO_AUDIO_STATE_UPDATED"; 1238 1239 /** 1240 * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_CHANGED} or 1241 * {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the new bluetooth SCO connection state. 1242 */ 1243 public static final String EXTRA_SCO_AUDIO_STATE = 1244 "android.media.extra.SCO_AUDIO_STATE"; 1245 1246 /** 1247 * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the previous 1248 * bluetooth SCO connection state. 1249 */ 1250 public static final String EXTRA_SCO_AUDIO_PREVIOUS_STATE = 1251 "android.media.extra.SCO_AUDIO_PREVIOUS_STATE"; 1252 1253 /** 1254 * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE 1255 * indicating that the SCO audio channel is not established 1256 */ 1257 public static final int SCO_AUDIO_STATE_DISCONNECTED = 0; 1258 /** 1259 * Value for extra {@link #EXTRA_SCO_AUDIO_STATE} or {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE} 1260 * indicating that the SCO audio channel is established 1261 */ 1262 public static final int SCO_AUDIO_STATE_CONNECTED = 1; 1263 /** 1264 * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE 1265 * indicating that the SCO audio channel is being established 1266 */ 1267 public static final int SCO_AUDIO_STATE_CONNECTING = 2; 1268 /** 1269 * Value for extra EXTRA_SCO_AUDIO_STATE indicating that 1270 * there was an error trying to obtain the state 1271 */ 1272 public static final int SCO_AUDIO_STATE_ERROR = -1; 1273 1274 1275 /** 1276 * Indicates if current platform supports use of SCO for off call use cases. 1277 * Application wanted to use bluetooth SCO audio when the phone is not in call 1278 * must first call this method to make sure that the platform supports this 1279 * feature. 1280 * @return true if bluetooth SCO can be used for audio when not in call 1281 * false otherwise 1282 * @see #startBluetoothSco() 1283 */ 1284 public boolean isBluetoothScoAvailableOffCall() { 1285 return mContext.getResources().getBoolean( 1286 com.android.internal.R.bool.config_bluetooth_sco_off_call); 1287 } 1288 1289 /** 1290 * Start bluetooth SCO audio connection. 1291 * <p>Requires Permission: 1292 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1293 * <p>This method can be used by applications wanting to send and received audio 1294 * to/from a bluetooth SCO headset while the phone is not in call. 1295 * <p>As the SCO connection establishment can take several seconds, 1296 * applications should not rely on the connection to be available when the method 1297 * returns but instead register to receive the intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} 1298 * and wait for the state to be {@link #SCO_AUDIO_STATE_CONNECTED}. 1299 * <p>As the ACTION_SCO_AUDIO_STATE_UPDATED intent is sticky, the application can check the SCO 1300 * audio state before calling startBluetoothSco() by reading the intent returned by the receiver 1301 * registration. If the state is already CONNECTED, no state change will be received via the 1302 * intent after calling startBluetoothSco(). It is however useful to call startBluetoothSco() 1303 * so that the connection stays active in case the current initiator stops the connection. 1304 * <p>Unless the connection is already active as described above, the state will always 1305 * transition from DISCONNECTED to CONNECTING and then either to CONNECTED if the connection 1306 * succeeds or back to DISCONNECTED if the connection fails (e.g no headset is connected). 1307 * <p>When finished with the SCO connection or if the establishment fails, the application must 1308 * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection. 1309 * <p>Even if a SCO connection is established, the following restrictions apply on audio 1310 * output streams so that they can be routed to SCO headset: 1311 * <ul> 1312 * <li> the stream type must be {@link #STREAM_VOICE_CALL} </li> 1313 * <li> the format must be mono </li> 1314 * <li> the sampling must be 16kHz or 8kHz </li> 1315 * </ul> 1316 * <p>The following restrictions apply on input streams: 1317 * <ul> 1318 * <li> the format must be mono </li> 1319 * <li> the sampling must be 8kHz </li> 1320 * </ul> 1321 * <p>Note that the phone application always has the priority on the usage of the SCO 1322 * connection for telephony. If this method is called while the phone is in call 1323 * it will be ignored. Similarly, if a call is received or sent while an application 1324 * is using the SCO connection, the connection will be lost for the application and NOT 1325 * returned automatically when the call ends. 1326 * <p>NOTE: up to and including API version 1327 * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual 1328 * voice call to the bluetooth headset. 1329 * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio 1330 * connection is established. 1331 * @see #stopBluetoothSco() 1332 * @see #ACTION_SCO_AUDIO_STATE_UPDATED 1333 */ 1334 public void startBluetoothSco(){ 1335 IAudioService service = getService(); 1336 try { 1337 service.startBluetoothSco(mICallBack, mContext.getApplicationInfo().targetSdkVersion); 1338 } catch (RemoteException e) { 1339 Log.e(TAG, "Dead object in startBluetoothSco", e); 1340 } 1341 } 1342 1343 /** 1344 * Start bluetooth SCO audio connection in virtual call mode. 1345 * <p>Requires Permission: 1346 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1347 * <p>Similar to {@link #startBluetoothSco()} with explicit selection of virtual call mode. 1348 * Telephony and communication applications (VoIP, Video Chat) should preferably select 1349 * virtual call mode. 1350 * Applications using voice input for search or commands should first try raw audio connection 1351 * with {@link #startBluetoothSco()} and fall back to startBluetoothScoVirtualCall() in case of 1352 * failure. 1353 * @see #startBluetoothSco() 1354 * @see #stopBluetoothSco() 1355 * @see #ACTION_SCO_AUDIO_STATE_UPDATED 1356 */ 1357 public void startBluetoothScoVirtualCall() { 1358 IAudioService service = getService(); 1359 try { 1360 service.startBluetoothScoVirtualCall(mICallBack); 1361 } catch (RemoteException e) { 1362 Log.e(TAG, "Dead object in startBluetoothScoVirtualCall", e); 1363 } 1364 } 1365 1366 /** 1367 * Stop bluetooth SCO audio connection. 1368 * <p>Requires Permission: 1369 * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. 1370 * <p>This method must be called by applications having requested the use of 1371 * bluetooth SCO audio with {@link #startBluetoothSco()} or 1372 * {@link #startBluetoothScoVirtualCall()} when finished with the SCO connection or 1373 * if connection fails. 1374 * @see #startBluetoothSco() 1375 * @see #startBluetoothScoVirtualCall() 1376 */ 1377 public void stopBluetoothSco(){ 1378 IAudioService service = getService(); 1379 try { 1380 service.stopBluetoothSco(mICallBack); 1381 } catch (RemoteException e) { 1382 Log.e(TAG, "Dead object in stopBluetoothSco", e); 1383 } 1384 } 1385 1386 /** 1387 * Request use of Bluetooth SCO headset for communications. 1388 * <p> 1389 * This method should only be used by applications that replace the platform-wide 1390 * management of audio settings or the main telephony application. 1391 * 1392 * @param on set <var>true</var> to use bluetooth SCO for communications; 1393 * <var>false</var> to not use bluetooth SCO for communications 1394 */ 1395 public void setBluetoothScoOn(boolean on){ 1396 IAudioService service = getService(); 1397 try { 1398 service.setBluetoothScoOn(on); 1399 } catch (RemoteException e) { 1400 Log.e(TAG, "Dead object in setBluetoothScoOn", e); 1401 } 1402 } 1403 1404 /** 1405 * Checks whether communications use Bluetooth SCO. 1406 * 1407 * @return true if SCO is used for communications; 1408 * false if otherwise 1409 */ 1410 public boolean isBluetoothScoOn() { 1411 IAudioService service = getService(); 1412 try { 1413 return service.isBluetoothScoOn(); 1414 } catch (RemoteException e) { 1415 Log.e(TAG, "Dead object in isBluetoothScoOn", e); 1416 return false; 1417 } 1418 } 1419 1420 /** 1421 * @param on set <var>true</var> to route A2DP audio to/from Bluetooth 1422 * headset; <var>false</var> disable A2DP audio 1423 * @deprecated Do not use. 1424 */ 1425 @Deprecated public void setBluetoothA2dpOn(boolean on){ 1426 } 1427 1428 /** 1429 * Checks whether A2DP audio routing to the Bluetooth headset is on or off. 1430 * 1431 * @return true if A2DP audio is being routed to/from Bluetooth headset; 1432 * false if otherwise 1433 */ 1434 public boolean isBluetoothA2dpOn() { 1435 if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"") 1436 == AudioSystem.DEVICE_STATE_UNAVAILABLE) { 1437 return false; 1438 } else { 1439 return true; 1440 } 1441 } 1442 1443 /** 1444 * Sets audio routing to the wired headset on or off. 1445 * 1446 * @param on set <var>true</var> to route audio to/from wired 1447 * headset; <var>false</var> disable wired headset audio 1448 * @deprecated Do not use. 1449 */ 1450 @Deprecated public void setWiredHeadsetOn(boolean on){ 1451 } 1452 1453 /** 1454 * Checks whether a wired headset is connected or not. 1455 * <p>This is not a valid indication that audio playback is 1456 * actually over the wired headset as audio routing depends on other conditions. 1457 * 1458 * @return true if a wired headset is connected. 1459 * false if otherwise 1460 * @deprecated Use only to check is a headset is connected or not. 1461 */ 1462 public boolean isWiredHeadsetOn() { 1463 if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"") 1464 == AudioSystem.DEVICE_STATE_UNAVAILABLE && 1465 AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"") 1466 == AudioSystem.DEVICE_STATE_UNAVAILABLE) { 1467 return false; 1468 } else { 1469 return true; 1470 } 1471 } 1472 1473 /** 1474 * Sets the microphone mute on or off. 1475 * <p> 1476 * This method should only be used by applications that replace the platform-wide 1477 * management of audio settings or the main telephony application. 1478 * 1479 * @param on set <var>true</var> to mute the microphone; 1480 * <var>false</var> to turn mute off 1481 */ 1482 public void setMicrophoneMute(boolean on){ 1483 IAudioService service = getService(); 1484 try { 1485 service.setMicrophoneMute(on, mContext.getOpPackageName()); 1486 } catch (RemoteException e) { 1487 Log.e(TAG, "Dead object in setMicrophoneMute", e); 1488 } 1489 } 1490 1491 /** 1492 * Checks whether the microphone mute is on or off. 1493 * 1494 * @return true if microphone is muted, false if it's not 1495 */ 1496 public boolean isMicrophoneMute() { 1497 return AudioSystem.isMicrophoneMuted(); 1498 } 1499 1500 /** 1501 * Sets the audio mode. 1502 * <p> 1503 * The audio mode encompasses audio routing AND the behavior of 1504 * the telephony layer. Therefore this method should only be used by applications that 1505 * replace the platform-wide management of audio settings or the main telephony application. 1506 * In particular, the {@link #MODE_IN_CALL} mode should only be used by the telephony 1507 * application when it places a phone call, as it will cause signals from the radio layer 1508 * to feed the platform mixer. 1509 * 1510 * @param mode the requested audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, 1511 * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). 1512 * Informs the HAL about the current audio state so that 1513 * it can route the audio appropriately. 1514 */ 1515 public void setMode(int mode) { 1516 IAudioService service = getService(); 1517 try { 1518 service.setMode(mode, mICallBack); 1519 } catch (RemoteException e) { 1520 Log.e(TAG, "Dead object in setMode", e); 1521 } 1522 } 1523 1524 /** 1525 * Returns the current audio mode. 1526 * 1527 * @return the current audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, 1528 * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). 1529 * Returns the current current audio state from the HAL. 1530 */ 1531 public int getMode() { 1532 IAudioService service = getService(); 1533 try { 1534 return service.getMode(); 1535 } catch (RemoteException e) { 1536 Log.e(TAG, "Dead object in getMode", e); 1537 return MODE_INVALID; 1538 } 1539 } 1540 1541 /* modes for setMode/getMode/setRoute/getRoute */ 1542 /** 1543 * Audio harware modes. 1544 */ 1545 /** 1546 * Invalid audio mode. 1547 */ 1548 public static final int MODE_INVALID = AudioSystem.MODE_INVALID; 1549 /** 1550 * Current audio mode. Used to apply audio routing to current mode. 1551 */ 1552 public static final int MODE_CURRENT = AudioSystem.MODE_CURRENT; 1553 /** 1554 * Normal audio mode: not ringing and no call established. 1555 */ 1556 public static final int MODE_NORMAL = AudioSystem.MODE_NORMAL; 1557 /** 1558 * Ringing audio mode. An incoming is being signaled. 1559 */ 1560 public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE; 1561 /** 1562 * In call audio mode. A telephony call is established. 1563 */ 1564 public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL; 1565 /** 1566 * In communication audio mode. An audio/video chat or VoIP call is established. 1567 */ 1568 public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION; 1569 1570 /* Routing bits for setRouting/getRouting API */ 1571 /** 1572 * Routing audio output to earpiece 1573 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1574 * setBluetoothScoOn() methods instead. 1575 */ 1576 @Deprecated public static final int ROUTE_EARPIECE = AudioSystem.ROUTE_EARPIECE; 1577 /** 1578 * Routing audio output to speaker 1579 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1580 * setBluetoothScoOn() methods instead. 1581 */ 1582 @Deprecated public static final int ROUTE_SPEAKER = AudioSystem.ROUTE_SPEAKER; 1583 /** 1584 * @deprecated use {@link #ROUTE_BLUETOOTH_SCO} 1585 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1586 * setBluetoothScoOn() methods instead. 1587 */ 1588 @Deprecated public static final int ROUTE_BLUETOOTH = AudioSystem.ROUTE_BLUETOOTH_SCO; 1589 /** 1590 * Routing audio output to bluetooth SCO 1591 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1592 * setBluetoothScoOn() methods instead. 1593 */ 1594 @Deprecated public static final int ROUTE_BLUETOOTH_SCO = AudioSystem.ROUTE_BLUETOOTH_SCO; 1595 /** 1596 * Routing audio output to headset 1597 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1598 * setBluetoothScoOn() methods instead. 1599 */ 1600 @Deprecated public static final int ROUTE_HEADSET = AudioSystem.ROUTE_HEADSET; 1601 /** 1602 * Routing audio output to bluetooth A2DP 1603 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1604 * setBluetoothScoOn() methods instead. 1605 */ 1606 @Deprecated public static final int ROUTE_BLUETOOTH_A2DP = AudioSystem.ROUTE_BLUETOOTH_A2DP; 1607 /** 1608 * Used for mask parameter of {@link #setRouting(int,int,int)}. 1609 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1610 * setBluetoothScoOn() methods instead. 1611 */ 1612 @Deprecated public static final int ROUTE_ALL = AudioSystem.ROUTE_ALL; 1613 1614 /** 1615 * Sets the audio routing for a specified mode 1616 * 1617 * @param mode audio mode to change route. E.g., MODE_RINGTONE. 1618 * @param routes bit vector of routes requested, created from one or 1619 * more of ROUTE_xxx types. Set bits indicate that route should be on 1620 * @param mask bit vector of routes to change, created from one or more of 1621 * ROUTE_xxx types. Unset bits indicate the route should be left unchanged 1622 * 1623 * @deprecated Do not set audio routing directly, use setSpeakerphoneOn(), 1624 * setBluetoothScoOn() methods instead. 1625 */ 1626 @Deprecated 1627 public void setRouting(int mode, int routes, int mask) { 1628 } 1629 1630 /** 1631 * Returns the current audio routing bit vector for a specified mode. 1632 * 1633 * @param mode audio mode to get route (e.g., MODE_RINGTONE) 1634 * @return an audio route bit vector that can be compared with ROUTE_xxx 1635 * bits 1636 * @deprecated Do not query audio routing directly, use isSpeakerphoneOn(), 1637 * isBluetoothScoOn(), isBluetoothA2dpOn() and isWiredHeadsetOn() methods instead. 1638 */ 1639 @Deprecated 1640 public int getRouting(int mode) { 1641 return -1; 1642 } 1643 1644 /** 1645 * Checks whether any music is active. 1646 * 1647 * @return true if any music tracks are active. 1648 */ 1649 public boolean isMusicActive() { 1650 return AudioSystem.isStreamActive(STREAM_MUSIC, 0); 1651 } 1652 1653 /** 1654 * @hide 1655 * Checks whether any music or media is actively playing on a remote device (e.g. wireless 1656 * display). Note that BT audio sinks are not considered remote devices. 1657 * @return true if {@link AudioManager#STREAM_MUSIC} is active on a remote device 1658 */ 1659 public boolean isMusicActiveRemotely() { 1660 return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0); 1661 } 1662 1663 /** 1664 * @hide 1665 * Checks whether any local or remote media playback is active. 1666 * Local playback refers to playback for instance on the device's speakers or wired headphones. 1667 * Remote playback refers to playback for instance on a wireless display mirroring the 1668 * devices's, or on a device using a Cast-like protocol. 1669 * @return true if media playback, from which the device is aware, is active. 1670 */ 1671 public boolean isLocalOrRemoteMusicActive() { 1672 IAudioService service = getService(); 1673 try { 1674 return service.isLocalOrRemoteMusicActive(); 1675 } catch (RemoteException e) { 1676 Log.e(TAG, "Dead object in isLocalOrRemoteMusicActive()", e); 1677 return false; 1678 } 1679 } 1680 1681 /** 1682 * @hide 1683 * Checks whether the current audio focus is exclusive. 1684 * @return true if the top of the audio focus stack requested focus 1685 * with {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} 1686 */ 1687 public boolean isAudioFocusExclusive() { 1688 IAudioService service = getService(); 1689 try { 1690 return service.getCurrentAudioFocus() == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE; 1691 } catch (RemoteException e) { 1692 Log.e(TAG, "Dead object in isAudioFocusExclusive()", e); 1693 return false; 1694 } 1695 } 1696 1697 /** 1698 * Return a new audio session identifier not associated with any player or effect. 1699 * It can for instance be used to create one of the {@link android.media.audiofx.AudioEffect} 1700 * objects. 1701 * @return a new unclaimed and unused audio session identifier, or {@link #ERROR} when the 1702 * system failed to allocate a new session. 1703 */ 1704 public int allocateAudioSessionId() { 1705 int session = AudioSystem.newAudioSessionId(); 1706 if (session > 0) { 1707 return session; 1708 } else { 1709 Log.e(TAG, "Failure to allocate a new audio session ID"); 1710 return ERROR; 1711 } 1712 } 1713 1714 1715 /* 1716 * Sets a generic audio configuration parameter. The use of these parameters 1717 * are platform dependant, see libaudio 1718 * 1719 * ** Temporary interface - DO NOT USE 1720 * 1721 * TODO: Replace with a more generic key:value get/set mechanism 1722 * 1723 * param key name of parameter to set. Must not be null. 1724 * param value value of parameter. Must not be null. 1725 */ 1726 /** 1727 * @hide 1728 * @deprecated Use {@link #setParameters(String)} instead 1729 */ 1730 @Deprecated public void setParameter(String key, String value) { 1731 setParameters(key+"="+value); 1732 } 1733 1734 /** 1735 * Sets a variable number of parameter values to audio hardware. 1736 * 1737 * @param keyValuePairs list of parameters key value pairs in the form: 1738 * key1=value1;key2=value2;... 1739 * 1740 */ 1741 public void setParameters(String keyValuePairs) { 1742 AudioSystem.setParameters(keyValuePairs); 1743 } 1744 1745 /** 1746 * Gets a variable number of parameter values from audio hardware. 1747 * 1748 * @param keys list of parameters 1749 * @return list of parameters key value pairs in the form: 1750 * key1=value1;key2=value2;... 1751 */ 1752 public String getParameters(String keys) { 1753 return AudioSystem.getParameters(keys); 1754 } 1755 1756 /* Sound effect identifiers */ 1757 /** 1758 * Keyboard and direction pad click sound 1759 * @see #playSoundEffect(int) 1760 */ 1761 public static final int FX_KEY_CLICK = 0; 1762 /** 1763 * Focus has moved up 1764 * @see #playSoundEffect(int) 1765 */ 1766 public static final int FX_FOCUS_NAVIGATION_UP = 1; 1767 /** 1768 * Focus has moved down 1769 * @see #playSoundEffect(int) 1770 */ 1771 public static final int FX_FOCUS_NAVIGATION_DOWN = 2; 1772 /** 1773 * Focus has moved left 1774 * @see #playSoundEffect(int) 1775 */ 1776 public static final int FX_FOCUS_NAVIGATION_LEFT = 3; 1777 /** 1778 * Focus has moved right 1779 * @see #playSoundEffect(int) 1780 */ 1781 public static final int FX_FOCUS_NAVIGATION_RIGHT = 4; 1782 /** 1783 * IME standard keypress sound 1784 * @see #playSoundEffect(int) 1785 */ 1786 public static final int FX_KEYPRESS_STANDARD = 5; 1787 /** 1788 * IME spacebar keypress sound 1789 * @see #playSoundEffect(int) 1790 */ 1791 public static final int FX_KEYPRESS_SPACEBAR = 6; 1792 /** 1793 * IME delete keypress sound 1794 * @see #playSoundEffect(int) 1795 */ 1796 public static final int FX_KEYPRESS_DELETE = 7; 1797 /** 1798 * IME return_keypress sound 1799 * @see #playSoundEffect(int) 1800 */ 1801 public static final int FX_KEYPRESS_RETURN = 8; 1802 1803 /** 1804 * Invalid keypress sound 1805 * @see #playSoundEffect(int) 1806 */ 1807 public static final int FX_KEYPRESS_INVALID = 9; 1808 /** 1809 * @hide Number of sound effects 1810 */ 1811 public static final int NUM_SOUND_EFFECTS = 10; 1812 1813 /** 1814 * Plays a sound effect (Key clicks, lid open/close...) 1815 * @param effectType The type of sound effect. One of 1816 * {@link #FX_KEY_CLICK}, 1817 * {@link #FX_FOCUS_NAVIGATION_UP}, 1818 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 1819 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 1820 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 1821 * {@link #FX_KEYPRESS_STANDARD}, 1822 * {@link #FX_KEYPRESS_SPACEBAR}, 1823 * {@link #FX_KEYPRESS_DELETE}, 1824 * {@link #FX_KEYPRESS_RETURN}, 1825 * {@link #FX_KEYPRESS_INVALID}, 1826 * NOTE: This version uses the UI settings to determine 1827 * whether sounds are heard or not. 1828 */ 1829 public void playSoundEffect(int effectType) { 1830 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 1831 return; 1832 } 1833 1834 if (!querySoundEffectsEnabled()) { 1835 return; 1836 } 1837 1838 IAudioService service = getService(); 1839 try { 1840 service.playSoundEffect(effectType); 1841 } catch (RemoteException e) { 1842 Log.e(TAG, "Dead object in playSoundEffect"+e); 1843 } 1844 } 1845 1846 /** 1847 * Plays a sound effect (Key clicks, lid open/close...) 1848 * @param effectType The type of sound effect. One of 1849 * {@link #FX_KEY_CLICK}, 1850 * {@link #FX_FOCUS_NAVIGATION_UP}, 1851 * {@link #FX_FOCUS_NAVIGATION_DOWN}, 1852 * {@link #FX_FOCUS_NAVIGATION_LEFT}, 1853 * {@link #FX_FOCUS_NAVIGATION_RIGHT}, 1854 * {@link #FX_KEYPRESS_STANDARD}, 1855 * {@link #FX_KEYPRESS_SPACEBAR}, 1856 * {@link #FX_KEYPRESS_DELETE}, 1857 * {@link #FX_KEYPRESS_RETURN}, 1858 * {@link #FX_KEYPRESS_INVALID}, 1859 * @param volume Sound effect volume. 1860 * The volume value is a raw scalar so UI controls should be scaled logarithmically. 1861 * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used. 1862 * NOTE: This version is for applications that have their own 1863 * settings panel for enabling and controlling volume. 1864 */ 1865 public void playSoundEffect(int effectType, float volume) { 1866 if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { 1867 return; 1868 } 1869 1870 IAudioService service = getService(); 1871 try { 1872 service.playSoundEffectVolume(effectType, volume); 1873 } catch (RemoteException e) { 1874 Log.e(TAG, "Dead object in playSoundEffect"+e); 1875 } 1876 } 1877 1878 /** 1879 * Settings has an in memory cache, so this is fast. 1880 */ 1881 private boolean querySoundEffectsEnabled() { 1882 return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0; 1883 } 1884 1885 1886 /** 1887 * Load Sound effects. 1888 * This method must be called when sound effects are enabled. 1889 */ 1890 public void loadSoundEffects() { 1891 IAudioService service = getService(); 1892 try { 1893 service.loadSoundEffects(); 1894 } catch (RemoteException e) { 1895 Log.e(TAG, "Dead object in loadSoundEffects"+e); 1896 } 1897 } 1898 1899 /** 1900 * Unload Sound effects. 1901 * This method can be called to free some memory when 1902 * sound effects are disabled. 1903 */ 1904 public void unloadSoundEffects() { 1905 IAudioService service = getService(); 1906 try { 1907 service.unloadSoundEffects(); 1908 } catch (RemoteException e) { 1909 Log.e(TAG, "Dead object in unloadSoundEffects"+e); 1910 } 1911 } 1912 1913 /** 1914 * @hide 1915 * Used to indicate no audio focus has been gained or lost. 1916 */ 1917 public static final int AUDIOFOCUS_NONE = 0; 1918 1919 /** 1920 * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration. 1921 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1922 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1923 */ 1924 public static final int AUDIOFOCUS_GAIN = 1; 1925 /** 1926 * Used to indicate a temporary gain or request of audio focus, anticipated to last a short 1927 * amount of time. Examples of temporary changes are the playback of driving directions, or an 1928 * event notification. 1929 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1930 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1931 */ 1932 public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2; 1933 /** 1934 * Used to indicate a temporary request of audio focus, anticipated to last a short 1935 * amount of time, and where it is acceptable for other audio applications to keep playing 1936 * after having lowered their output level (also referred to as "ducking"). 1937 * Examples of temporary changes are the playback of driving directions where playback of music 1938 * in the background is acceptable. 1939 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1940 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1941 */ 1942 public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3; 1943 /** 1944 * Used to indicate a temporary request of audio focus, anticipated to last a short 1945 * amount of time, during which no other applications, or system components, should play 1946 * anything. Examples of exclusive and transient audio focus requests are voice 1947 * memo recording and speech recognition, during which the system shouldn't play any 1948 * notifications, and media playback should have paused. 1949 * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int) 1950 */ 1951 public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE = 4; 1952 /** 1953 * Used to indicate a loss of audio focus of unknown duration. 1954 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1955 */ 1956 public static final int AUDIOFOCUS_LOSS = -1 * AUDIOFOCUS_GAIN; 1957 /** 1958 * Used to indicate a transient loss of audio focus. 1959 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1960 */ 1961 public static final int AUDIOFOCUS_LOSS_TRANSIENT = -1 * AUDIOFOCUS_GAIN_TRANSIENT; 1962 /** 1963 * Used to indicate a transient loss of audio focus where the loser of the audio focus can 1964 * lower its output volume if it wants to continue playing (also referred to as "ducking"), as 1965 * the new focus owner doesn't require others to be silent. 1966 * @see OnAudioFocusChangeListener#onAudioFocusChange(int) 1967 */ 1968 public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = 1969 -1 * AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK; 1970 1971 /** 1972 * Interface definition for a callback to be invoked when the audio focus of the system is 1973 * updated. 1974 */ 1975 public interface OnAudioFocusChangeListener { 1976 /** 1977 * Called on the listener to notify it the audio focus for this listener has been changed. 1978 * The focusChange value indicates whether the focus was gained, 1979 * whether the focus was lost, and whether that loss is transient, or whether the new focus 1980 * holder will hold it for an unknown amount of time. 1981 * When losing focus, listeners can use the focus change information to decide what 1982 * behavior to adopt when losing focus. A music player could for instance elect to lower 1983 * the volume of its music stream (duck) for transient focus losses, and pause otherwise. 1984 * @param focusChange the type of focus change, one of {@link AudioManager#AUDIOFOCUS_GAIN}, 1985 * {@link AudioManager#AUDIOFOCUS_LOSS}, {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT} 1986 * and {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}. 1987 */ 1988 public void onAudioFocusChange(int focusChange); 1989 } 1990 1991 /** 1992 * Map to convert focus event listener IDs, as used in the AudioService audio focus stack, 1993 * to actual listener objects. 1994 */ 1995 private final HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap = 1996 new HashMap<String, OnAudioFocusChangeListener>(); 1997 /** 1998 * Lock to prevent concurrent changes to the list of focus listeners for this AudioManager 1999 * instance. 2000 */ 2001 private final Object mFocusListenerLock = new Object(); 2002 2003 private OnAudioFocusChangeListener findFocusListener(String id) { 2004 return mAudioFocusIdListenerMap.get(id); 2005 } 2006 2007 /** 2008 * Handler for audio focus events coming from the audio service. 2009 */ 2010 private final FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate = 2011 new FocusEventHandlerDelegate(); 2012 2013 /** 2014 * Helper class to handle the forwarding of audio focus events to the appropriate listener 2015 */ 2016 private class FocusEventHandlerDelegate { 2017 private final Handler mHandler; 2018 2019 FocusEventHandlerDelegate() { 2020 Looper looper; 2021 if ((looper = Looper.myLooper()) == null) { 2022 looper = Looper.getMainLooper(); 2023 } 2024 2025 if (looper != null) { 2026 // implement the event handler delegate to receive audio focus events 2027 mHandler = new Handler(looper) { 2028 @Override 2029 public void handleMessage(Message msg) { 2030 OnAudioFocusChangeListener listener = null; 2031 synchronized(mFocusListenerLock) { 2032 listener = findFocusListener((String)msg.obj); 2033 } 2034 if (listener != null) { 2035 listener.onAudioFocusChange(msg.what); 2036 } 2037 } 2038 }; 2039 } else { 2040 mHandler = null; 2041 } 2042 } 2043 2044 Handler getHandler() { 2045 return mHandler; 2046 } 2047 } 2048 2049 private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() { 2050 2051 public void dispatchAudioFocusChange(int focusChange, String id) { 2052 Message m = mAudioFocusEventHandlerDelegate.getHandler().obtainMessage(focusChange, id); 2053 mAudioFocusEventHandlerDelegate.getHandler().sendMessage(m); 2054 } 2055 2056 }; 2057 2058 private String getIdForAudioFocusListener(OnAudioFocusChangeListener l) { 2059 if (l == null) { 2060 return new String(this.toString()); 2061 } else { 2062 return new String(this.toString() + l.toString()); 2063 } 2064 } 2065 2066 /** 2067 * @hide 2068 * Registers a listener to be called when audio focus changes. Calling this method is optional 2069 * before calling {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, as it 2070 * will register the listener as well if it wasn't registered already. 2071 * @param l the listener to be notified of audio focus changes. 2072 */ 2073 public void registerAudioFocusListener(OnAudioFocusChangeListener l) { 2074 synchronized(mFocusListenerLock) { 2075 if (mAudioFocusIdListenerMap.containsKey(getIdForAudioFocusListener(l))) { 2076 return; 2077 } 2078 mAudioFocusIdListenerMap.put(getIdForAudioFocusListener(l), l); 2079 } 2080 } 2081 2082 /** 2083 * @hide 2084 * Causes the specified listener to not be called anymore when focus is gained or lost. 2085 * @param l the listener to unregister. 2086 */ 2087 public void unregisterAudioFocusListener(OnAudioFocusChangeListener l) { 2088 2089 // remove locally 2090 synchronized(mFocusListenerLock) { 2091 mAudioFocusIdListenerMap.remove(getIdForAudioFocusListener(l)); 2092 } 2093 } 2094 2095 2096 /** 2097 * A failed focus change request. 2098 */ 2099 public static final int AUDIOFOCUS_REQUEST_FAILED = 0; 2100 /** 2101 * A successful focus change request. 2102 */ 2103 public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; 2104 2105 2106 /** 2107 * Request audio focus. 2108 * Send a request to obtain the audio focus 2109 * @param l the listener to be notified of audio focus changes 2110 * @param streamType the main audio stream type affected by the focus request 2111 * @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request 2112 * is temporary, and focus will be abandonned shortly. Examples of transient requests are 2113 * for the playback of driving directions, or notifications sounds. 2114 * Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for 2115 * the previous focus owner to keep playing if it ducks its audio output. 2116 * Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request 2117 * that benefits from the system not playing disruptive sounds like notifications, for 2118 * usecases such as voice memo recording, or speech recognition. 2119 * Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such 2120 * as the playback of a song or a video. 2121 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 2122 */ 2123 public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) { 2124 int status = AUDIOFOCUS_REQUEST_FAILED; 2125 if ((durationHint < AUDIOFOCUS_GAIN) || 2126 (durationHint > AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) { 2127 Log.e(TAG, "Invalid duration hint, audio focus request denied"); 2128 return status; 2129 } 2130 registerAudioFocusListener(l); 2131 //TODO protect request by permission check? 2132 IAudioService service = getService(); 2133 try { 2134 status = service.requestAudioFocus(streamType, durationHint, mICallBack, 2135 mAudioFocusDispatcher, getIdForAudioFocusListener(l), 2136 mContext.getOpPackageName() /* package name */); 2137 } catch (RemoteException e) { 2138 Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e); 2139 } 2140 return status; 2141 } 2142 2143 /** 2144 * @hide 2145 * Used internally by telephony package to request audio focus. Will cause the focus request 2146 * to be associated with the "voice communication" identifier only used in AudioService 2147 * to identify this use case. 2148 * @param streamType use STREAM_RING for focus requests when ringing, VOICE_CALL for 2149 * the establishment of the call 2150 * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so 2151 * media applications resume after a call 2152 */ 2153 public void requestAudioFocusForCall(int streamType, int durationHint) { 2154 IAudioService service = getService(); 2155 try { 2156 service.requestAudioFocus(streamType, durationHint, mICallBack, null, 2157 MediaFocusControl.IN_VOICE_COMM_FOCUS_ID, 2158 mContext.getOpPackageName()); 2159 } catch (RemoteException e) { 2160 Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e); 2161 } 2162 } 2163 2164 /** 2165 * @hide 2166 * Used internally by telephony package to abandon audio focus, typically after a call or 2167 * when ringing ends and the call is rejected or not answered. 2168 * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}. 2169 */ 2170 public void abandonAudioFocusForCall() { 2171 IAudioService service = getService(); 2172 try { 2173 service.abandonAudioFocus(null, MediaFocusControl.IN_VOICE_COMM_FOCUS_ID); 2174 } catch (RemoteException e) { 2175 Log.e(TAG, "Can't call abandonAudioFocusForCall() on AudioService due to "+e); 2176 } 2177 } 2178 2179 /** 2180 * Abandon audio focus. Causes the previous focus owner, if any, to receive focus. 2181 * @param l the listener with which focus was requested. 2182 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 2183 */ 2184 public int abandonAudioFocus(OnAudioFocusChangeListener l) { 2185 int status = AUDIOFOCUS_REQUEST_FAILED; 2186 unregisterAudioFocusListener(l); 2187 IAudioService service = getService(); 2188 try { 2189 status = service.abandonAudioFocus(mAudioFocusDispatcher, 2190 getIdForAudioFocusListener(l)); 2191 } catch (RemoteException e) { 2192 Log.e(TAG, "Can't call abandonAudioFocus() on AudioService due to "+e); 2193 } 2194 return status; 2195 } 2196 2197 2198 //==================================================================== 2199 // Remote Control 2200 /** 2201 * Register a component to be the sole receiver of MEDIA_BUTTON intents. 2202 * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} 2203 * that will receive the media button intent. This broadcast receiver must be declared 2204 * in the application manifest. The package of the component must match that of 2205 * the context you're registering from. 2206 */ 2207 public void registerMediaButtonEventReceiver(ComponentName eventReceiver) { 2208 if (eventReceiver == null) { 2209 return; 2210 } 2211 if (!eventReceiver.getPackageName().equals(mContext.getPackageName())) { 2212 Log.e(TAG, "registerMediaButtonEventReceiver() error: " + 2213 "receiver and context package names don't match"); 2214 return; 2215 } 2216 // construct a PendingIntent for the media button and register it 2217 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 2218 // the associated intent will be handled by the component being registered 2219 mediaButtonIntent.setComponent(eventReceiver); 2220 PendingIntent pi = PendingIntent.getBroadcast(mContext, 2221 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); 2222 registerMediaButtonIntent(pi, eventReceiver); 2223 } 2224 2225 /** 2226 * Register a component to be the sole receiver of MEDIA_BUTTON intents. This is like 2227 * {@link #registerMediaButtonEventReceiver(android.content.ComponentName)}, but allows 2228 * the buttons to go to any PendingIntent. Note that you should only use this form if 2229 * you know you will continue running for the full time until unregistering the 2230 * PendingIntent. 2231 * @param eventReceiver target that will receive media button intents. The PendingIntent 2232 * will be sent as-is when a media button action occurs, with {@link Intent#EXTRA_KEY_EVENT} 2233 * added and holding the key code of the media button that was pressed. 2234 */ 2235 public void registerMediaButtonEventReceiver(PendingIntent eventReceiver) { 2236 if (eventReceiver == null) { 2237 return; 2238 } 2239 registerMediaButtonIntent(eventReceiver, null); 2240 } 2241 2242 /** 2243 * @hide 2244 * no-op if (pi == null) or (eventReceiver == null) 2245 */ 2246 public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) { 2247 if (pi == null) { 2248 Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null parameter"); 2249 return; 2250 } 2251 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 2252 helper.addMediaButtonListener(pi, eventReceiver, mContext); 2253 } 2254 2255 /** 2256 * Unregister the receiver of MEDIA_BUTTON intents. 2257 * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} 2258 * that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}. 2259 */ 2260 public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) { 2261 if (eventReceiver == null) { 2262 return; 2263 } 2264 // construct a PendingIntent for the media button and unregister it 2265 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 2266 // the associated intent will be handled by the component being registered 2267 mediaButtonIntent.setComponent(eventReceiver); 2268 PendingIntent pi = PendingIntent.getBroadcast(mContext, 2269 0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/); 2270 unregisterMediaButtonIntent(pi); 2271 } 2272 2273 /** 2274 * Unregister the receiver of MEDIA_BUTTON intents. 2275 * @param eventReceiver same PendingIntent that was registed with 2276 * {@link #registerMediaButtonEventReceiver(PendingIntent)}. 2277 */ 2278 public void unregisterMediaButtonEventReceiver(PendingIntent eventReceiver) { 2279 if (eventReceiver == null) { 2280 return; 2281 } 2282 unregisterMediaButtonIntent(eventReceiver); 2283 } 2284 2285 /** 2286 * @hide 2287 */ 2288 public void unregisterMediaButtonIntent(PendingIntent pi) { 2289 MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext); 2290 helper.removeMediaButtonListener(pi); 2291 } 2292 2293 /** 2294 * Registers the remote control client for providing information to display on the remote 2295 * controls. 2296 * @param rcClient The remote control client from which remote controls will receive 2297 * information to display. 2298 * @see RemoteControlClient 2299 */ 2300 public void registerRemoteControlClient(RemoteControlClient rcClient) { 2301 if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { 2302 return; 2303 } 2304 rcClient.registerWithSession(MediaSessionLegacyHelper.getHelper(mContext)); 2305 } 2306 2307 /** 2308 * Unregisters the remote control client that was providing information to display on the 2309 * remote controls. 2310 * @param rcClient The remote control client to unregister. 2311 * @see #registerRemoteControlClient(RemoteControlClient) 2312 */ 2313 public void unregisterRemoteControlClient(RemoteControlClient rcClient) { 2314 if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) { 2315 return; 2316 } 2317 rcClient.unregisterWithSession(MediaSessionLegacyHelper.getHelper(mContext)); 2318 } 2319 2320 /** 2321 * Registers a {@link RemoteController} instance for it to receive media metadata updates 2322 * and playback state information from applications using {@link RemoteControlClient}, and 2323 * control their playback. 2324 * <p>Registration requires the {@link OnClientUpdateListener} listener to be one of the 2325 * enabled notification listeners (see 2326 * {@link android.service.notification.NotificationListenerService}). 2327 * @param rctlr the object to register. 2328 * @return true if the {@link RemoteController} was successfully registered, false if an 2329 * error occurred, due to an internal system error, or insufficient permissions. 2330 */ 2331 public boolean registerRemoteController(RemoteController rctlr) { 2332 if (rctlr == null) { 2333 return false; 2334 } 2335 rctlr.startListeningToSessions(); 2336 return true; 2337 } 2338 2339 /** 2340 * Unregisters a {@link RemoteController}, causing it to no longer receive media metadata and 2341 * playback state information, and no longer be capable of controlling playback. 2342 * @param rctlr the object to unregister. 2343 */ 2344 public void unregisterRemoteController(RemoteController rctlr) { 2345 if (rctlr == null) { 2346 return; 2347 } 2348 rctlr.stopListeningToSessions(); 2349 } 2350 2351 /** 2352 * @hide 2353 * Registers a remote control display that will be sent information by remote control clients. 2354 * Use this method if your IRemoteControlDisplay is not going to display artwork, otherwise 2355 * use {@link #registerRemoteControlDisplay(IRemoteControlDisplay, int, int)} to pass the 2356 * artwork size directly, or 2357 * {@link #remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay, int, int)} later if artwork 2358 * is not yet needed. 2359 * <p>Registration requires the {@link Manifest.permission#MEDIA_CONTENT_CONTROL} permission. 2360 * @param rcd the IRemoteControlDisplay 2361 */ 2362 public void registerRemoteControlDisplay(IRemoteControlDisplay rcd) { 2363 // passing a negative value for art work width and height as they are unknown at this stage 2364 registerRemoteControlDisplay(rcd, /*w*/-1, /*h*/ -1); 2365 } 2366 2367 /** 2368 * @hide 2369 * Registers a remote control display that will be sent information by remote control clients. 2370 * <p>Registration requires the {@link Manifest.permission#MEDIA_CONTENT_CONTROL} permission. 2371 * @param rcd 2372 * @param w the maximum width of the expected bitmap. Negative values indicate it is 2373 * useless to send artwork. 2374 * @param h the maximum height of the expected bitmap. Negative values indicate it is 2375 * useless to send artwork. 2376 */ 2377 public void registerRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h) { 2378 if (rcd == null) { 2379 return; 2380 } 2381 IAudioService service = getService(); 2382 try { 2383 service.registerRemoteControlDisplay(rcd, w, h); 2384 } catch (RemoteException e) { 2385 Log.e(TAG, "Dead object in registerRemoteControlDisplay " + e); 2386 } 2387 } 2388 2389 /** 2390 * @hide 2391 * Unregisters a remote control display that was sent information by remote control clients. 2392 * @param rcd 2393 */ 2394 public void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) { 2395 if (rcd == null) { 2396 return; 2397 } 2398 IAudioService service = getService(); 2399 try { 2400 service.unregisterRemoteControlDisplay(rcd); 2401 } catch (RemoteException e) { 2402 Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e); 2403 } 2404 } 2405 2406 /** 2407 * @hide 2408 * Sets the artwork size a remote control display expects when receiving bitmaps. 2409 * @param rcd 2410 * @param w the maximum width of the expected bitmap. Negative values indicate it is 2411 * useless to send artwork. 2412 * @param h the maximum height of the expected bitmap. Negative values indicate it is 2413 * useless to send artwork. 2414 */ 2415 public void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) { 2416 if (rcd == null) { 2417 return; 2418 } 2419 IAudioService service = getService(); 2420 try { 2421 service.remoteControlDisplayUsesBitmapSize(rcd, w, h); 2422 } catch (RemoteException e) { 2423 Log.e(TAG, "Dead object in remoteControlDisplayUsesBitmapSize " + e); 2424 } 2425 } 2426 2427 /** 2428 * @hide 2429 * Controls whether a remote control display needs periodic checks of the RemoteControlClient 2430 * playback position to verify that the estimated position has not drifted from the actual 2431 * position. By default the check is not performed. 2432 * The IRemoteControlDisplay must have been previously registered for this to have any effect. 2433 * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled 2434 * or disabled. No effect is null. 2435 * @param wantsSync if true, RemoteControlClient instances which expose their playback position 2436 * to the framework will regularly compare the estimated playback position with the actual 2437 * position, and will update the IRemoteControlDisplay implementation whenever a drift is 2438 * detected. 2439 */ 2440 public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd, 2441 boolean wantsSync) { 2442 if (rcd == null) { 2443 return; 2444 } 2445 IAudioService service = getService(); 2446 try { 2447 service.remoteControlDisplayWantsPlaybackPositionSync(rcd, wantsSync); 2448 } catch (RemoteException e) { 2449 Log.e(TAG, "Dead object in remoteControlDisplayWantsPlaybackPositionSync " + e); 2450 } 2451 } 2452 2453 /** 2454 * @hide 2455 * CANDIDATE FOR PUBLIC API 2456 * Register the given {@link AudioPolicy}. 2457 * This call is synchronous and blocks until the registration process successfully completed 2458 * or failed to complete. 2459 * @param policy the {@link AudioPolicy} to register. 2460 * @return {@link #ERROR} if there was an error communicating with the registration service 2461 * or if the user doesn't have the required 2462 * {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission, 2463 * {@link #SUCCESS} otherwise. 2464 */ 2465 public int registerAudioPolicy(AudioPolicy policy) { 2466 if (policy == null) { 2467 throw new IllegalArgumentException("Illegal null AudioPolicy argument"); 2468 } 2469 IAudioService service = getService(); 2470 try { 2471 if (!service.registerAudioPolicy(policy.getConfig(), policy.token())) { 2472 return ERROR; 2473 } 2474 } catch (RemoteException e) { 2475 Log.e(TAG, "Dead object in registerAudioPolicyAsync()", e); 2476 return ERROR; 2477 } 2478 return SUCCESS; 2479 } 2480 2481 /** 2482 * @hide 2483 * CANDIDATE FOR PUBLIC API 2484 * @param policy the {@link AudioPolicy} to unregister. 2485 */ 2486 public void unregisterAudioPolicyAsync(AudioPolicy policy) { 2487 if (policy == null) { 2488 throw new IllegalArgumentException("Illegal null AudioPolicy argument"); 2489 } 2490 IAudioService service = getService(); 2491 try { 2492 service.unregisterAudioPolicyAsync(policy.token()); 2493 } catch (RemoteException e) { 2494 Log.e(TAG, "Dead object in unregisterAudioPolicyAsync()", e); 2495 } 2496 } 2497 2498 2499 /** 2500 * @hide 2501 * Reload audio settings. This method is called by Settings backup 2502 * agent when audio settings are restored and causes the AudioService 2503 * to read and apply restored settings. 2504 */ 2505 public void reloadAudioSettings() { 2506 IAudioService service = getService(); 2507 try { 2508 service.reloadAudioSettings(); 2509 } catch (RemoteException e) { 2510 Log.e(TAG, "Dead object in reloadAudioSettings"+e); 2511 } 2512 } 2513 2514 /** 2515 * @hide 2516 * Notifies AudioService that it is connected to an A2DP device that supports absolute volume, 2517 * so that AudioService can send volume change events to the A2DP device, rather than handling 2518 * them. 2519 */ 2520 public void avrcpSupportsAbsoluteVolume(String address, boolean support) { 2521 IAudioService service = getService(); 2522 try { 2523 service.avrcpSupportsAbsoluteVolume(address, support); 2524 } catch (RemoteException e) { 2525 Log.e(TAG, "Dead object in avrcpSupportsAbsoluteVolume", e); 2526 } 2527 } 2528 2529 /** 2530 * {@hide} 2531 */ 2532 private final IBinder mICallBack = new Binder(); 2533 2534 /** 2535 * Checks whether the phone is in silent mode, with or without vibrate. 2536 * 2537 * @return true if phone is in silent mode, with or without vibrate. 2538 * 2539 * @see #getRingerMode() 2540 * 2541 * @hide pending API Council approval 2542 */ 2543 public boolean isSilentMode() { 2544 int ringerMode = getRingerMode(); 2545 boolean silentMode = 2546 (ringerMode == RINGER_MODE_SILENT) || 2547 (ringerMode == RINGER_MODE_VIBRATE); 2548 return silentMode; 2549 } 2550 2551 // This section re-defines new output device constants from AudioSystem, because the AudioSystem 2552 // class is not used by other parts of the framework, which instead use definitions and methods 2553 // from AudioManager. AudioSystem is an internal class used by AudioManager and AudioService. 2554 2555 /** @hide 2556 * The audio device code for representing "no device." */ 2557 public static final int DEVICE_NONE = AudioSystem.DEVICE_NONE; 2558 /** @hide 2559 * The audio output device code for the small speaker at the front of the device used 2560 * when placing calls. Does not refer to an in-ear headphone without attached microphone, 2561 * such as earbuds, earphones, or in-ear monitors (IEM). Those would be handled as a 2562 * {@link #DEVICE_OUT_WIRED_HEADPHONE}. 2563 */ 2564 public static final int DEVICE_OUT_EARPIECE = AudioSystem.DEVICE_OUT_EARPIECE; 2565 /** @hide 2566 * The audio output device code for the built-in speaker */ 2567 public static final int DEVICE_OUT_SPEAKER = AudioSystem.DEVICE_OUT_SPEAKER; 2568 /** @hide 2569 * The audio output device code for a wired headset with attached microphone */ 2570 public static final int DEVICE_OUT_WIRED_HEADSET = AudioSystem.DEVICE_OUT_WIRED_HEADSET; 2571 /** @hide 2572 * The audio output device code for a wired headphone without attached microphone */ 2573 public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE; 2574 /** @hide 2575 * The audio output device code for generic Bluetooth SCO, for voice */ 2576 public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; 2577 /** @hide 2578 * The audio output device code for Bluetooth SCO Headset Profile (HSP) and 2579 * Hands-Free Profile (HFP), for voice 2580 */ 2581 public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 2582 AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 2583 /** @hide 2584 * The audio output device code for Bluetooth SCO car audio, for voice */ 2585 public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 2586 AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; 2587 /** @hide 2588 * The audio output device code for generic Bluetooth A2DP, for music */ 2589 public static final int DEVICE_OUT_BLUETOOTH_A2DP = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; 2590 /** @hide 2591 * The audio output device code for Bluetooth A2DP headphones, for music */ 2592 public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 2593 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; 2594 /** @hide 2595 * The audio output device code for Bluetooth A2DP external speaker, for music */ 2596 public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 2597 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; 2598 /** @hide 2599 * The audio output device code for S/PDIF (legacy) or HDMI 2600 * Deprecated: replaced by {@link #DEVICE_OUT_HDMI} */ 2601 public static final int DEVICE_OUT_AUX_DIGITAL = AudioSystem.DEVICE_OUT_AUX_DIGITAL; 2602 /** @hide 2603 * The audio output device code for HDMI */ 2604 public static final int DEVICE_OUT_HDMI = AudioSystem.DEVICE_OUT_HDMI; 2605 /** @hide 2606 * The audio output device code for an analog wired headset attached via a 2607 * docking station 2608 */ 2609 public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET; 2610 /** @hide 2611 * The audio output device code for a digital wired headset attached via a 2612 * docking station 2613 */ 2614 public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET; 2615 /** @hide 2616 * The audio output device code for a USB audio accessory. The accessory is in USB host 2617 * mode and the Android device in USB device mode 2618 */ 2619 public static final int DEVICE_OUT_USB_ACCESSORY = AudioSystem.DEVICE_OUT_USB_ACCESSORY; 2620 /** @hide 2621 * The audio output device code for a USB audio device. The device is in USB device 2622 * mode and the Android device in USB host mode 2623 */ 2624 public static final int DEVICE_OUT_USB_DEVICE = AudioSystem.DEVICE_OUT_USB_DEVICE; 2625 /** @hide 2626 * The audio output device code for projection output. 2627 */ 2628 public static final int DEVICE_OUT_REMOTE_SUBMIX = AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; 2629 /** @hide 2630 * The audio output device code the telephony voice TX path. 2631 */ 2632 public static final int DEVICE_OUT_TELEPHONY_TX = AudioSystem.DEVICE_OUT_TELEPHONY_TX; 2633 /** @hide 2634 * The audio output device code for an analog jack with line impedance detected. 2635 */ 2636 public static final int DEVICE_OUT_LINE = AudioSystem.DEVICE_OUT_LINE; 2637 /** @hide 2638 * The audio output device code for HDMI Audio Return Channel. 2639 */ 2640 public static final int DEVICE_OUT_HDMI_ARC = AudioSystem.DEVICE_OUT_HDMI_ARC; 2641 /** @hide 2642 * The audio output device code for S/PDIF digital connection. 2643 */ 2644 public static final int DEVICE_OUT_SPDIF = AudioSystem.DEVICE_OUT_SPDIF; 2645 /** @hide 2646 * The audio output device code for built-in FM transmitter. 2647 */ 2648 public static final int DEVICE_OUT_FM = AudioSystem.DEVICE_OUT_FM; 2649 /** @hide 2650 * This is not used as a returned value from {@link #getDevicesForStream}, but could be 2651 * used in the future in a set method to select whatever default device is chosen by the 2652 * platform-specific implementation. 2653 */ 2654 public static final int DEVICE_OUT_DEFAULT = AudioSystem.DEVICE_OUT_DEFAULT; 2655 2656 /** @hide 2657 * The audio input device code for default built-in microphone 2658 */ 2659 public static final int DEVICE_IN_BUILTIN_MIC = AudioSystem.DEVICE_IN_BUILTIN_MIC; 2660 /** @hide 2661 * The audio input device code for a Bluetooth SCO headset 2662 */ 2663 public static final int DEVICE_IN_BLUETOOTH_SCO_HEADSET = 2664 AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET; 2665 /** @hide 2666 * The audio input device code for wired headset microphone 2667 */ 2668 public static final int DEVICE_IN_WIRED_HEADSET = 2669 AudioSystem.DEVICE_IN_WIRED_HEADSET; 2670 /** @hide 2671 * The audio input device code for HDMI 2672 */ 2673 public static final int DEVICE_IN_HDMI = 2674 AudioSystem.DEVICE_IN_HDMI; 2675 /** @hide 2676 * The audio input device code for telephony voice RX path 2677 */ 2678 public static final int DEVICE_IN_TELEPHONY_RX = 2679 AudioSystem.DEVICE_IN_TELEPHONY_RX; 2680 /** @hide 2681 * The audio input device code for built-in microphone pointing to the back 2682 */ 2683 public static final int DEVICE_IN_BACK_MIC = 2684 AudioSystem.DEVICE_IN_BACK_MIC; 2685 /** @hide 2686 * The audio input device code for analog from a docking station 2687 */ 2688 public static final int DEVICE_IN_ANLG_DOCK_HEADSET = 2689 AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET; 2690 /** @hide 2691 * The audio input device code for digital from a docking station 2692 */ 2693 public static final int DEVICE_IN_DGTL_DOCK_HEADSET = 2694 AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET; 2695 /** @hide 2696 * The audio input device code for a USB audio accessory. The accessory is in USB host 2697 * mode and the Android device in USB device mode 2698 */ 2699 public static final int DEVICE_IN_USB_ACCESSORY = 2700 AudioSystem.DEVICE_IN_USB_ACCESSORY; 2701 /** @hide 2702 * The audio input device code for a USB audio device. The device is in USB device 2703 * mode and the Android device in USB host mode 2704 */ 2705 public static final int DEVICE_IN_USB_DEVICE = 2706 AudioSystem.DEVICE_IN_USB_DEVICE; 2707 /** @hide 2708 * The audio input device code for a FM radio tuner 2709 */ 2710 public static final int DEVICE_IN_FM_TUNER = AudioSystem.DEVICE_IN_FM_TUNER; 2711 /** @hide 2712 * The audio input device code for a TV tuner 2713 */ 2714 public static final int DEVICE_IN_TV_TUNER = AudioSystem.DEVICE_IN_TV_TUNER; 2715 /** @hide 2716 * The audio input device code for an analog jack with line impedance detected 2717 */ 2718 public static final int DEVICE_IN_LINE = AudioSystem.DEVICE_IN_LINE; 2719 /** @hide 2720 * The audio input device code for a S/PDIF digital connection 2721 */ 2722 public static final int DEVICE_IN_SPDIF = AudioSystem.DEVICE_IN_SPDIF; 2723 /** @hide 2724 * The audio input device code for audio loopback 2725 */ 2726 public static final int DEVICE_IN_LOOPBACK = AudioSystem.DEVICE_IN_LOOPBACK; 2727 2728 /** 2729 * Return true if the device code corresponds to an output device. 2730 * @hide 2731 */ 2732 public static boolean isOutputDevice(int device) 2733 { 2734 return (device & AudioSystem.DEVICE_BIT_IN) == 0; 2735 } 2736 2737 /** 2738 * Return true if the device code corresponds to an input device. 2739 * @hide 2740 */ 2741 public static boolean isInputDevice(int device) 2742 { 2743 return (device & AudioSystem.DEVICE_BIT_IN) == AudioSystem.DEVICE_BIT_IN; 2744 } 2745 2746 2747 /** 2748 * Return the enabled devices for the specified output stream type. 2749 * 2750 * @param streamType The stream type to query. One of 2751 * {@link #STREAM_VOICE_CALL}, 2752 * {@link #STREAM_SYSTEM}, 2753 * {@link #STREAM_RING}, 2754 * {@link #STREAM_MUSIC}, 2755 * {@link #STREAM_ALARM}, 2756 * {@link #STREAM_NOTIFICATION}, 2757 * {@link #STREAM_DTMF}. 2758 * 2759 * @return The bit-mask "or" of audio output device codes for all enabled devices on this 2760 * stream. Zero or more of 2761 * {@link #DEVICE_OUT_EARPIECE}, 2762 * {@link #DEVICE_OUT_SPEAKER}, 2763 * {@link #DEVICE_OUT_WIRED_HEADSET}, 2764 * {@link #DEVICE_OUT_WIRED_HEADPHONE}, 2765 * {@link #DEVICE_OUT_BLUETOOTH_SCO}, 2766 * {@link #DEVICE_OUT_BLUETOOTH_SCO_HEADSET}, 2767 * {@link #DEVICE_OUT_BLUETOOTH_SCO_CARKIT}, 2768 * {@link #DEVICE_OUT_BLUETOOTH_A2DP}, 2769 * {@link #DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES}, 2770 * {@link #DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER}, 2771 * {@link #DEVICE_OUT_HDMI}, 2772 * {@link #DEVICE_OUT_ANLG_DOCK_HEADSET}, 2773 * {@link #DEVICE_OUT_DGTL_DOCK_HEADSET}. 2774 * {@link #DEVICE_OUT_USB_ACCESSORY}. 2775 * {@link #DEVICE_OUT_USB_DEVICE}. 2776 * {@link #DEVICE_OUT_REMOTE_SUBMIX}. 2777 * {@link #DEVICE_OUT_TELEPHONY_TX}. 2778 * {@link #DEVICE_OUT_LINE}. 2779 * {@link #DEVICE_OUT_HDMI_ARC}. 2780 * {@link #DEVICE_OUT_SPDIF}. 2781 * {@link #DEVICE_OUT_FM}. 2782 * {@link #DEVICE_OUT_DEFAULT} is not used here. 2783 * 2784 * The implementation may support additional device codes beyond those listed, so 2785 * the application should ignore any bits which it does not recognize. 2786 * Note that the information may be imprecise when the implementation 2787 * cannot distinguish whether a particular device is enabled. 2788 * 2789 * {@hide} 2790 */ 2791 public int getDevicesForStream(int streamType) { 2792 switch (streamType) { 2793 case STREAM_VOICE_CALL: 2794 case STREAM_SYSTEM: 2795 case STREAM_RING: 2796 case STREAM_MUSIC: 2797 case STREAM_ALARM: 2798 case STREAM_NOTIFICATION: 2799 case STREAM_DTMF: 2800 return AudioSystem.getDevicesForStream(streamType); 2801 default: 2802 return 0; 2803 } 2804 } 2805 2806 /** 2807 * Indicate wired accessory connection state change. 2808 * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx) 2809 * @param state new connection state: 1 connected, 0 disconnected 2810 * @param name device name 2811 * {@hide} 2812 */ 2813 public void setWiredDeviceConnectionState(int device, int state, String name) { 2814 IAudioService service = getService(); 2815 try { 2816 service.setWiredDeviceConnectionState(device, state, name); 2817 } catch (RemoteException e) { 2818 Log.e(TAG, "Dead object in setWiredDeviceConnectionState "+e); 2819 } 2820 } 2821 2822 /** 2823 * Indicate A2DP source or sink connection state change. 2824 * @param device Bluetooth device connected/disconnected 2825 * @param state new connection state (BluetoothProfile.STATE_xxx) 2826 * @param profile profile for the A2DP device 2827 * (either {@link android.bluetooth.BluetoothProfile.A2DP} or 2828 * {@link android.bluetooth.BluetoothProfile.A2DP_SINK}) 2829 * @return a delay in ms that the caller should wait before broadcasting 2830 * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent. 2831 * {@hide} 2832 */ 2833 public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, 2834 int profile) { 2835 IAudioService service = getService(); 2836 int delay = 0; 2837 try { 2838 delay = service.setBluetoothA2dpDeviceConnectionState(device, state, profile); 2839 } catch (RemoteException e) { 2840 Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e); 2841 } finally { 2842 return delay; 2843 } 2844 } 2845 2846 /** {@hide} */ 2847 public IRingtonePlayer getRingtonePlayer() { 2848 try { 2849 return getService().getRingtonePlayer(); 2850 } catch (RemoteException e) { 2851 return null; 2852 } 2853 } 2854 2855 /** 2856 * Used as a key for {@link #getProperty} to request the native or optimal output sample rate 2857 * for this device's primary output stream, in decimal Hz. 2858 */ 2859 public static final String PROPERTY_OUTPUT_SAMPLE_RATE = 2860 "android.media.property.OUTPUT_SAMPLE_RATE"; 2861 2862 /** 2863 * Used as a key for {@link #getProperty} to request the native or optimal output buffer size 2864 * for this device's primary output stream, in decimal PCM frames. 2865 */ 2866 public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER = 2867 "android.media.property.OUTPUT_FRAMES_PER_BUFFER"; 2868 2869 /** 2870 * Returns the value of the property with the specified key. 2871 * @param key One of the strings corresponding to a property key: either 2872 * {@link #PROPERTY_OUTPUT_SAMPLE_RATE} or 2873 * {@link #PROPERTY_OUTPUT_FRAMES_PER_BUFFER} 2874 * @return A string representing the associated value for that property key, 2875 * or null if there is no value for that key. 2876 */ 2877 public String getProperty(String key) { 2878 if (PROPERTY_OUTPUT_SAMPLE_RATE.equals(key)) { 2879 int outputSampleRate = AudioSystem.getPrimaryOutputSamplingRate(); 2880 return outputSampleRate > 0 ? Integer.toString(outputSampleRate) : null; 2881 } else if (PROPERTY_OUTPUT_FRAMES_PER_BUFFER.equals(key)) { 2882 int outputFramesPerBuffer = AudioSystem.getPrimaryOutputFrameCount(); 2883 return outputFramesPerBuffer > 0 ? Integer.toString(outputFramesPerBuffer) : null; 2884 } else { 2885 // null or unknown key 2886 return null; 2887 } 2888 } 2889 2890 /** 2891 * Returns the estimated latency for the given stream type in milliseconds. 2892 * 2893 * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need 2894 * a better solution. 2895 * @hide 2896 */ 2897 public int getOutputLatency(int streamType) { 2898 return AudioSystem.getOutputLatency(streamType); 2899 } 2900 2901 /** 2902 * Registers a global volume controller interface. Currently limited to SystemUI. 2903 * 2904 * @hide 2905 */ 2906 public void setVolumeController(IVolumeController controller) { 2907 try { 2908 getService().setVolumeController(controller); 2909 } catch (RemoteException e) { 2910 Log.w(TAG, "Error setting volume controller", e); 2911 } 2912 } 2913 2914 /** 2915 * Only useful for volume controllers. 2916 * @hide 2917 */ 2918 public boolean isStreamAffectedByRingerMode(int streamType) { 2919 try { 2920 return getService().isStreamAffectedByRingerMode(streamType); 2921 } catch (RemoteException e) { 2922 Log.w(TAG, "Error calling isStreamAffectedByRingerMode", e); 2923 return false; 2924 } 2925 } 2926 2927 /** 2928 * Only useful for volume controllers. 2929 * @hide 2930 */ 2931 public void disableSafeMediaVolume() { 2932 try { 2933 getService().disableSafeMediaVolume(); 2934 } catch (RemoteException e) { 2935 Log.w(TAG, "Error disabling safe media volume", e); 2936 } 2937 } 2938 2939 /** 2940 * Set Hdmi Cec system audio mode. 2941 * 2942 * @param on whether to be on system audio mode 2943 * @param device out device type to be used for system audio mode. 2944 * Ignored if {@code on} is {@code false} 2945 * @param name name of system audio device 2946 * @return output device type. 0 (DEVICE_NONE) if failed to set device. 2947 * @hide 2948 */ 2949 public int setHdmiSystemAudioSupported(boolean on, int device, String name) { 2950 try { 2951 return getService().setHdmiSystemAudioSupported(on, device, name); 2952 } catch (RemoteException e) { 2953 Log.w(TAG, "Error setting system audio mode", e); 2954 return AudioSystem.DEVICE_NONE; 2955 } 2956 } 2957 2958 /** 2959 * Return codes for listAudioPorts(), createAudioPatch() ... 2960 */ 2961 2962 /** @hide 2963 * CANDIDATE FOR PUBLIC API 2964 */ 2965 public static final int SUCCESS = AudioSystem.SUCCESS; 2966 /** 2967 * A default error code. 2968 */ 2969 public static final int ERROR = AudioSystem.ERROR; 2970 /** @hide 2971 * CANDIDATE FOR PUBLIC API 2972 */ 2973 public static final int ERROR_BAD_VALUE = AudioSystem.BAD_VALUE; 2974 /** @hide 2975 */ 2976 public static final int ERROR_INVALID_OPERATION = AudioSystem.INVALID_OPERATION; 2977 /** @hide 2978 */ 2979 public static final int ERROR_PERMISSION_DENIED = AudioSystem.PERMISSION_DENIED; 2980 /** @hide 2981 */ 2982 public static final int ERROR_NO_INIT = AudioSystem.NO_INIT; 2983 /** 2984 * An error code indicating that the object reporting it is no longer valid and needs to 2985 * be recreated. 2986 */ 2987 public static final int ERROR_DEAD_OBJECT = AudioSystem.DEAD_OBJECT; 2988 2989 /** 2990 * Returns a list of descriptors for all audio ports managed by the audio framework. 2991 * Audio ports are nodes in the audio framework or audio hardware that can be configured 2992 * or connected and disconnected with createAudioPatch() or releaseAudioPatch(). 2993 * See AudioPort for a list of attributes of each audio port. 2994 * @param ports An AudioPort ArrayList where the list will be returned. 2995 * @hide 2996 */ 2997 public int listAudioPorts(ArrayList<AudioPort> ports) { 2998 return updateAudioPortCache(ports, null); 2999 } 3000 3001 /** 3002 * Specialized version of listAudioPorts() listing only audio devices (AudioDevicePort) 3003 * @see listAudioPorts(ArrayList<AudioPort>) 3004 * @hide 3005 */ 3006 public int listAudioDevicePorts(ArrayList<AudioPort> devices) { 3007 ArrayList<AudioPort> ports = new ArrayList<AudioPort>(); 3008 int status = updateAudioPortCache(ports, null); 3009 if (status == SUCCESS) { 3010 devices.clear(); 3011 for (int i = 0; i < ports.size(); i++) { 3012 if (ports.get(i) instanceof AudioDevicePort) { 3013 devices.add(ports.get(i)); 3014 } 3015 } 3016 } 3017 return status; 3018 } 3019 3020 /** 3021 * Create a connection between two or more devices. The framework will reject the request if 3022 * device types are not compatible or the implementation does not support the requested 3023 * configuration. 3024 * NOTE: current implementation is limited to one source and one sink per patch. 3025 * @param patch AudioPatch array where the newly created patch will be returned. 3026 * As input, if patch[0] is not null, the specified patch will be replaced by the 3027 * new patch created. This avoids calling releaseAudioPatch() when modifying a 3028 * patch and allows the implementation to optimize transitions. 3029 * @param sources List of source audio ports. All must be AudioPort.ROLE_SOURCE. 3030 * @param sinks List of sink audio ports. All must be AudioPort.ROLE_SINK. 3031 * 3032 * @return - {@link #SUCCESS} if connection is successful. 3033 * - {@link #ERROR_BAD_VALUE} if incompatible device types are passed. 3034 * - {@link #ERROR_INVALID_OPERATION} if the requested connection is not supported. 3035 * - {@link #ERROR_PERMISSION_DENIED} if the client does not have permission to create 3036 * a patch. 3037 * - {@link #ERROR_DEAD_OBJECT} if the server process is dead 3038 * - {@link #ERROR} if patch cannot be connected for any other reason. 3039 * 3040 * patch[0] contains the newly created patch 3041 * @hide 3042 */ 3043 public int createAudioPatch(AudioPatch[] patch, 3044 AudioPortConfig[] sources, 3045 AudioPortConfig[] sinks) { 3046 return AudioSystem.createAudioPatch(patch, sources, sinks); 3047 } 3048 3049 /** 3050 * Releases an existing audio patch connection. 3051 * @param patch The audio patch to disconnect. 3052 * @return - {@link #SUCCESS} if disconnection is successful. 3053 * - {@link #ERROR_BAD_VALUE} if the specified patch does not exist. 3054 * - {@link #ERROR_PERMISSION_DENIED} if the client does not have permission to release 3055 * a patch. 3056 * - {@link #ERROR_DEAD_OBJECT} if the server process is dead 3057 * - {@link #ERROR} if patch cannot be released for any other reason. 3058 * @hide 3059 */ 3060 public int releaseAudioPatch(AudioPatch patch) { 3061 return AudioSystem.releaseAudioPatch(patch); 3062 } 3063 3064 /** 3065 * List all existing connections between audio ports. 3066 * @param patches An AudioPatch array where the list will be returned. 3067 * @hide 3068 */ 3069 public int listAudioPatches(ArrayList<AudioPatch> patches) { 3070 return updateAudioPortCache(null, patches); 3071 } 3072 3073 /** 3074 * Set the gain on the specified AudioPort. The AudioGainConfig config is build by 3075 * AudioGain.buildConfig() 3076 * @hide 3077 */ 3078 public int setAudioPortGain(AudioPort port, AudioGainConfig gain) { 3079 if (port == null || gain == null) { 3080 return ERROR_BAD_VALUE; 3081 } 3082 AudioPortConfig activeConfig = port.activeConfig(); 3083 AudioPortConfig config = new AudioPortConfig(port, activeConfig.samplingRate(), 3084 activeConfig.channelMask(), activeConfig.format(), gain); 3085 config.mConfigMask = AudioPortConfig.GAIN; 3086 return AudioSystem.setAudioPortConfig(config); 3087 } 3088 3089 /** 3090 * Listener registered by client to be notified upon new audio port connections, 3091 * disconnections or attributes update. 3092 * @hide 3093 */ 3094 public interface OnAudioPortUpdateListener { 3095 /** 3096 * Callback method called upon audio port list update. 3097 * @param portList the updated list of audio ports 3098 */ 3099 public void OnAudioPortListUpdate(AudioPort[] portList); 3100 3101 /** 3102 * Callback method called upon audio patch list update. 3103 * @param patchList the updated list of audio patches 3104 */ 3105 public void OnAudioPatchListUpdate(AudioPatch[] patchList); 3106 3107 /** 3108 * Callback method called when the mediaserver dies 3109 */ 3110 public void OnServiceDied(); 3111 } 3112 3113 /** 3114 * Register an audio port list update listener. 3115 * @hide 3116 */ 3117 public void registerAudioPortUpdateListener(OnAudioPortUpdateListener l) { 3118 mAudioPortEventHandler.registerListener(l); 3119 } 3120 3121 /** 3122 * Unregister an audio port list update listener. 3123 * @hide 3124 */ 3125 public void unregisterAudioPortUpdateListener(OnAudioPortUpdateListener l) { 3126 mAudioPortEventHandler.unregisterListener(l); 3127 } 3128 3129 // 3130 // AudioPort implementation 3131 // 3132 3133 static final int AUDIOPORT_GENERATION_INIT = 0; 3134 Integer mAudioPortGeneration = new Integer(AUDIOPORT_GENERATION_INIT); 3135 ArrayList<AudioPort> mAudioPortsCached = new ArrayList<AudioPort>(); 3136 ArrayList<AudioPatch> mAudioPatchesCached = new ArrayList<AudioPatch>(); 3137 3138 int resetAudioPortGeneration() { 3139 int generation; 3140 synchronized (mAudioPortGeneration) { 3141 generation = mAudioPortGeneration; 3142 mAudioPortGeneration = AUDIOPORT_GENERATION_INIT; 3143 } 3144 return generation; 3145 } 3146 3147 int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches) { 3148 synchronized (mAudioPortGeneration) { 3149 3150 if (mAudioPortGeneration == AUDIOPORT_GENERATION_INIT) { 3151 int[] patchGeneration = new int[1]; 3152 int[] portGeneration = new int[1]; 3153 int status; 3154 ArrayList<AudioPort> newPorts = new ArrayList<AudioPort>(); 3155 ArrayList<AudioPatch> newPatches = new ArrayList<AudioPatch>(); 3156 3157 do { 3158 newPorts.clear(); 3159 status = AudioSystem.listAudioPorts(newPorts, portGeneration); 3160 if (status != SUCCESS) { 3161 return status; 3162 } 3163 newPatches.clear(); 3164 status = AudioSystem.listAudioPatches(newPatches, patchGeneration); 3165 if (status != SUCCESS) { 3166 return status; 3167 } 3168 } while (patchGeneration[0] != portGeneration[0]); 3169 3170 for (int i = 0; i < newPatches.size(); i++) { 3171 for (int j = 0; j < newPatches.get(i).sources().length; j++) { 3172 AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sources()[j], 3173 newPorts); 3174 if (portCfg == null) { 3175 return ERROR; 3176 } 3177 newPatches.get(i).sources()[j] = portCfg; 3178 } 3179 for (int j = 0; j < newPatches.get(i).sinks().length; j++) { 3180 AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sinks()[j], 3181 newPorts); 3182 if (portCfg == null) { 3183 return ERROR; 3184 } 3185 newPatches.get(i).sinks()[j] = portCfg; 3186 } 3187 } 3188 3189 mAudioPortsCached = newPorts; 3190 mAudioPatchesCached = newPatches; 3191 mAudioPortGeneration = portGeneration[0]; 3192 } 3193 if (ports != null) { 3194 ports.clear(); 3195 ports.addAll(mAudioPortsCached); 3196 } 3197 if (patches != null) { 3198 patches.clear(); 3199 patches.addAll(mAudioPatchesCached); 3200 } 3201 } 3202 return SUCCESS; 3203 } 3204 3205 AudioPortConfig updatePortConfig(AudioPortConfig portCfg, ArrayList<AudioPort> ports) { 3206 AudioPort port = portCfg.port(); 3207 int k; 3208 for (k = 0; k < ports.size(); k++) { 3209 // compare handles because the port returned by JNI is not of the correct 3210 // subclass 3211 if (ports.get(k).handle().equals(port.handle())) { 3212 port = ports.get(k); 3213 break; 3214 } 3215 } 3216 if (k == ports.size()) { 3217 // this hould never happen 3218 Log.e(TAG, "updatePortConfig port not found for handle: "+port.handle().id()); 3219 return null; 3220 } 3221 AudioGainConfig gainCfg = portCfg.gain(); 3222 if (gainCfg != null) { 3223 AudioGain gain = port.gain(gainCfg.index()); 3224 gainCfg = gain.buildConfig(gainCfg.mode(), 3225 gainCfg.channelMask(), 3226 gainCfg.values(), 3227 gainCfg.rampDurationMs()); 3228 } 3229 return port.buildConfig(portCfg.samplingRate(), 3230 portCfg.channelMask(), 3231 portCfg.format(), 3232 gainCfg); 3233 } 3234} 3235