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