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