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