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