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