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