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