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