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