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