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