19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.media;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Triviimport android.Manifest;
20958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Triviimport android.annotation.NonNull;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.SdkConstant;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.annotation.SdkConstant.SdkConstantType;
23e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heoimport android.annotation.SystemApi;
24f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Triviimport android.app.PendingIntent;
25b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurentimport android.bluetooth.BluetoothDevice;
26d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Triviimport android.content.ComponentName;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
28f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Triviimport android.content.Intent;
29f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Triviimport android.media.RemoteController.OnClientUpdateListener;
30a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.media.audiopolicy.AudioPolicy;
31a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Triviimport android.media.audiopolicy.AudioPolicyConfig;
32b214efbb9170a9f6a4991684a63ca59680074cc7RoboErikimport android.media.session.MediaController;
33b214efbb9170a9f6a4991684a63ca59680074cc7RoboErikimport android.media.session.MediaSession;
34f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.media.session.MediaSessionLegacyHelper;
35b214efbb9170a9f6a4991684a63ca59680074cc7RoboErikimport android.media.session.MediaSessionManager;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
39d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Triviimport android.os.Looper;
40d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Triviimport android.os.Message;
410c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monkimport android.os.Process;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
4386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onoratoimport android.os.SystemClock;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
47d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Triviimport android.view.KeyEvent;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49a198a29250acb7c3e918f1566727190966bb336fEric Laurentimport java.util.ArrayList;
50b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kimimport java.util.HashMap;
51b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kimimport java.util.Iterator;
52700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AudioManager provides access to volume and ringer mode control.
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use <code>Context.getSystemService(Context.AUDIO_SERVICE)</code> to get
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * an instance of this class.
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AudioManager {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Context mContext;
6286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato    private long mVolumeKeyUpTime;
63cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    private final boolean mUseMasterVolume;
64b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate    private final boolean mUseVolumeKeySounds;
65ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent    private final boolean mUseFixedVolume;
6679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn    private final Binder mToken = new Binder();
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static String TAG = "AudioManager";
68f076db407029e734703d8676f806bea94393e824Eric Laurent    private static final AudioPortEventHandler sAudioPortEventHandler = new AudioPortEventHandler();
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Broadcast intent, a hint for applications that audio is about to become
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 'noisy' due to a change in audio outputs. For example, this intent may
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be sent when a wired headset is unplugged, or when an A2DP audio
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sink is disconnected, and the audio system is about to automatically
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * switch audio route to the speaker. Applications that are controlling
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * audio streams may consider pausing, reducing volume or some other action
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * on receipt of this intent so as not to surprise the user with audio
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from the speaker.
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY";
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sticky broadcast intent action indicating that the ringer mode has
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * changed. Includes the new ringer mode.
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #EXTRA_RINGER_MODE
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
93bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock     * @hide
94bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock     * Sticky broadcast intent action indicating that the internal ringer mode has
95bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock     * changed. Includes the new ringer mode.
96bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock     *
97bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock     * @see #EXTRA_RINGER_MODE
98bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock     */
99bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
100bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    public static final String INTERNAL_RINGER_MODE_CHANGED_ACTION =
101bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock            "android.media.INTERNAL_RINGER_MODE_CHANGED_ACTION";
102bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock
103bcc1087af40a0e1bb35dbe8a39c830ecdea8280bJohn Spurlock    /**
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The new ringer mode.
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #RINGER_MODE_CHANGED_ACTION
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #RINGER_MODE_NORMAL
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #RINGER_MODE_SILENT
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #RINGER_MODE_VIBRATE
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE";
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Broadcast intent action indicating that the vibrate setting has
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * changed. Includes the vibrate type and its new setting.
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #EXTRA_VIBRATE_TYPE
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #EXTRA_VIBRATE_SETTING
119cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
120cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead.
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1230dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    public static final String VIBRATE_SETTING_CHANGED_ACTION =
1240dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood        "android.media.VIBRATE_SETTING_CHANGED";
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide Broadcast intent when the volume for a particular stream type changes.
1283114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Includes the stream, the new volume and previous volumes.
1293114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * Notes:
1303114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     *  - for internal platform use only, do not make public,
1313114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     *  - never used for "remote" volume changes
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #EXTRA_VOLUME_STREAM_TYPE
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #EXTRA_VOLUME_STREAM_VALUE
1359ce379aef155e0c21b5d82d8dc713c62792e4f30Eric Laurent     * @see #EXTRA_PREV_VOLUME_STREAM_VALUE
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1417c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     * @hide Broadcast intent when a stream mute state changes.
1427c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     * Includes the stream that changed and the new mute state
1437c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     *
1447c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     * @see #EXTRA_VOLUME_STREAM_TYPE
1457c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     * @see #EXTRA_STREAM_VOLUME_MUTED
1467c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     */
1477c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1487c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik    public static final String STREAM_MUTE_CHANGED_ACTION =
1497c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik        "android.media.STREAM_MUTE_CHANGED_ACTION";
1507c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik
1517c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik    /**
1520dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * @hide Broadcast intent when the master volume changes.
1530dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * Includes the new volume
1540dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     *
1550dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * @see #EXTRA_MASTER_VOLUME_VALUE
1560dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * @see #EXTRA_PREV_MASTER_VOLUME_VALUE
1570dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     */
1580dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1590dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    public static final String MASTER_VOLUME_CHANGED_ACTION =
1600dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood        "android.media.MASTER_VOLUME_CHANGED_ACTION";
1610dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood
1620dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    /**
1630dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * @hide Broadcast intent when the master mute state changes.
1640dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * Includes the the new volume
1650dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     *
1660dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * @see #EXTRA_MASTER_VOLUME_MUTED
1670dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     */
1680dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1690dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    public static final String MASTER_MUTE_CHANGED_ACTION =
1700dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood        "android.media.MASTER_MUTE_CHANGED_ACTION";
1710dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood
1720dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    /**
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The new vibrate setting for a particular type.
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #VIBRATE_SETTING_CHANGED_ACTION
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #EXTRA_VIBRATE_TYPE
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #VIBRATE_SETTING_ON
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #VIBRATE_SETTING_OFF
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #VIBRATE_SETTING_ONLY_SILENT
180cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
181cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead.
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final String EXTRA_VIBRATE_SETTING = "android.media.EXTRA_VIBRATE_SETTING";
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The vibrate type whose setting has changed.
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #VIBRATE_SETTING_CHANGED_ACTION
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #VIBRATE_TYPE_NOTIFICATION
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #VIBRATE_TYPE_RINGER
191cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
192cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead.
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final String EXTRA_VIBRATE_TYPE = "android.media.EXTRA_VIBRATE_TYPE";
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide The stream type for the volume changed intent.
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide The volume associated with the stream for the volume changed intent.
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final String EXTRA_VOLUME_STREAM_VALUE =
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "android.media.EXTRA_VOLUME_STREAM_VALUE";
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079ce379aef155e0c21b5d82d8dc713c62792e4f30Eric Laurent    /**
2089ce379aef155e0c21b5d82d8dc713c62792e4f30Eric Laurent     * @hide The previous volume associated with the stream for the volume changed intent.
2099ce379aef155e0c21b5d82d8dc713c62792e4f30Eric Laurent     */
2109ce379aef155e0c21b5d82d8dc713c62792e4f30Eric Laurent    public static final String EXTRA_PREV_VOLUME_STREAM_VALUE =
2119ce379aef155e0c21b5d82d8dc713c62792e4f30Eric Laurent        "android.media.EXTRA_PREV_VOLUME_STREAM_VALUE";
2120dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood
2130dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    /**
2140dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * @hide The new master volume value for the master volume changed intent.
2150dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * Value is integer between 0 and 100 inclusive.
2160dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     */
2170dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    public static final String EXTRA_MASTER_VOLUME_VALUE =
2180dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood        "android.media.EXTRA_MASTER_VOLUME_VALUE";
2190dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood
2200dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    /**
2210dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * @hide The previous master volume value for the master volume changed intent.
2220dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * Value is integer between 0 and 100 inclusive.
2230dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     */
2240dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    public static final String EXTRA_PREV_MASTER_VOLUME_VALUE =
2250dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood        "android.media.EXTRA_PREV_MASTER_VOLUME_VALUE";
2260dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood
2270dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    /**
2280dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * @hide The new master volume mute state for the master mute changed intent.
2290dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     * Value is boolean
2300dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood     */
2310dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood    public static final String EXTRA_MASTER_VOLUME_MUTED =
2320dc37cce9d564ae43883c8dc8672b9266b881e63Mike Lockwood        "android.media.EXTRA_MASTER_VOLUME_MUTED";
2339ce379aef155e0c21b5d82d8dc713c62792e4f30Eric Laurent
234c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
2357c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     * @hide The new stream volume mute state for the stream mute changed intent.
2367c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     * Value is boolean
2377c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik     */
2387c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik    public static final String EXTRA_STREAM_VOLUME_MUTED =
2397c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik        "android.media.EXTRA_STREAM_VOLUME_MUTED";
2407c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik
2417c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik    /**
242c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Broadcast Action: Wired Headset plugged in or unplugged.
243c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *
244c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * You <em>cannot</em> receive this through components declared
245c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * in manifests, only by explicitly registering for it with
246c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
247c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Context.registerReceiver()}.
248c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *
249c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <p>The intent will have the following extra values:
250c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <ul>
251c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
252c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>name</em> - Headset type, human readable string </li>
253c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>microphone</em> - 1 if headset has a microphone, 0 otherwise </li>
254c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
255c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
256c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
257c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
258c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    public static final String ACTION_HEADSET_PLUG =
259c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi            "android.intent.action.HEADSET_PLUG";
260c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
261c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
262c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Broadcast Action: A sticky broadcast indicating an HMDI cable was plugged or unplugged
263c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *
264c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * The intent will have the following extra values: {@link #EXTRA_AUDIO_PLUG_STATE},
265c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * {@link #EXTRA_MAX_CHANNEL_COUNT}, {@link #EXTRA_ENCODINGS}.
266c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <p>It can only be received by explicitly registering for it with
267c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)}.
268c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
269c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
270c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    public static final String ACTION_HDMI_AUDIO_PLUG =
271c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi            "android.media.action.HDMI_AUDIO_PLUG";
272c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
273c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
274c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to communicate whether HDMI is plugged in
275c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * or unplugged.
276c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * An integer value of 1 indicates a plugged-in state, 0 is unplugged.
277c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
278deddda5d62498bbaa9789c622be7a08be83f2f51Jean-Michel Trivi    public static final String EXTRA_AUDIO_PLUG_STATE = "android.media.extra.AUDIO_PLUG_STATE";
279c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
280c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
281c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to define the maximum number of channels
282c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * supported by the HDMI device.
283c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * The corresponding integer value is only available when the device is plugged in (as expressed
284c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * by {@link #EXTRA_AUDIO_PLUG_STATE}).
285c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
286deddda5d62498bbaa9789c622be7a08be83f2f51Jean-Michel Trivi    public static final String EXTRA_MAX_CHANNEL_COUNT = "android.media.extra.MAX_CHANNEL_COUNT";
287c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
288c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
289c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to define the audio encodings supported by
290c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * the connected HDMI device.
291c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * The corresponding array of encoding values is only available when the device is plugged in
292c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * (as expressed by {@link #EXTRA_AUDIO_PLUG_STATE}). Encoding values are defined in
293c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * {@link AudioFormat} (for instance see {@link AudioFormat#ENCODING_PCM_16BIT}). Use
294c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * {@link android.content.Intent#getIntArrayExtra(String)} to retrieve the encoding values.
295c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
296deddda5d62498bbaa9789c622be7a08be83f2f51Jean-Michel Trivi    public static final String EXTRA_ENCODINGS = "android.media.extra.ENCODINGS";
297c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
298c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
299c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Broadcast Action: An analog audio speaker/headset plugged in or unplugged.
300c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *
301c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <p>The intent will have the following extra values:
302c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <ul>
303c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
304c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>name</em> - Headset type, human readable string </li>
305c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
306c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
307c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * @hide
308c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
309c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
310c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    public static final String ACTION_ANALOG_AUDIO_DOCK_PLUG =
311c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi            "android.media.action.ANALOG_AUDIO_DOCK_PLUG";
312c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
313c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
314c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Broadcast Action: A digital audio speaker/headset plugged in or unplugged.
315c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *
316c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <p>The intent will have the following extra values:
317c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <ul>
318c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
319c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>name</em> - Headset type, human readable string </li>
320c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
321c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
322c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * @hide
323c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
324c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
325c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    public static final String ACTION_DIGITAL_AUDIO_DOCK_PLUG =
326c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi            "android.media.action.DIGITAL_AUDIO_DOCK_PLUG";
327c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
328c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
329c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Broadcast Action: A USB audio accessory was plugged in or unplugged.
330c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *
331c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <p>The intent will have the following extra values:
332c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <ul>
333c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
334c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>card</em> - ALSA card number (integer) </li>
335c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>device</em> - ALSA device number (integer) </li>
336c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
337c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
338c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * @hide
339c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
340c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
341c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG =
342c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi            "android.media.action.USB_AUDIO_ACCESSORY_PLUG";
343c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
344c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    /**
345c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * Broadcast Action: A USB audio device was plugged in or unplugged.
346c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *
347c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <p>The intent will have the following extra values:
348c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * <ul>
349c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
350c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>card</em> - ALSA card number (integer) </li>
351c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     *   <li><em>device</em> - ALSA device number (integer) </li>
352c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
353c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * </ul>
354c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     * @hide
355c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi     */
356c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
357c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi    public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
358c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi            "android.media.action.USB_AUDIO_DEVICE_PLUG";
359c5258433dd353769ccfa2e5e769a7379378a3a0bJean-Michel Trivi
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The audio stream for phone calls */
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The audio stream for system sounds */
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The audio stream for the phone ring */
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int STREAM_RING = AudioSystem.STREAM_RING;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The audio stream for music playback */
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The audio stream for alarms */
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** The audio stream for notifications */
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION;
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** @hide The audio stream for phone calls when connected to bluetooth */
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO;
374a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    /** @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */
375a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED;
376a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    /** The audio stream for DTMF Tones */
377a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF;
378a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    /** @hide The audio stream for text to speech (TTS) */
379a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    public static final int STREAM_TTS = AudioSystem.STREAM_TTS;
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Number of audio streams */
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @deprecated Use AudioSystem.getNumStreamTypes() instead
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
384a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public static final int NUM_STREAMS = AudioSystem.NUM_STREAMS;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Increase the ringer volume.
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustVolume(int, int)
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustStreamVolume(int, int, int)
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int ADJUST_RAISE = 1;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Decrease the ringer volume.
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustVolume(int, int)
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustStreamVolume(int, int, int)
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int ADJUST_LOWER = -1;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Maintain the previous ringer volume. This may be useful when needing to
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * show the volume toast without actually modifying the volume.
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustVolume(int, int)
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustStreamVolume(int, int, int)
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int ADJUST_SAME = 0;
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Flags should be powers of 2!
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Show a toast containing the current volume.
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustStreamVolume(int, int, int)
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustVolume(int, int)
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setStreamVolume(int, int, int)
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setRingerMode(int)
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FLAG_SHOW_UI = 1 << 0;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Whether to include ringer modes as possible options when changing volume.
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For example, if true and volume level is 0 and the volume is adjusted
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with {@link #ADJUST_LOWER}, then the ringer mode may switch the silent or
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * vibrate mode.
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * By default this is on for the ring stream. If this flag is included,
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this behavior will be present regardless of the stream type being
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * affected by the ringer mode.
432105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustVolume(int, int)
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustStreamVolume(int, int, int)
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FLAG_ALLOW_RINGER_MODES = 1 << 1;
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Whether to play a sound when changing the volume.
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If this is given to {@link #adjustVolume(int, int)} or
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #adjustSuggestedStreamVolume(int, int, int)}, it may be ignored
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in some cases (for example, the decided stream type is not
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link AudioManager#STREAM_RING}, or the volume is being adjusted
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * downward).
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustStreamVolume(int, int, int)
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustVolume(int, int)
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setStreamVolume(int, int, int)
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FLAG_PLAY_SOUND = 1 << 2;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Removes any sounds/vibrate that may be in the queue, or are playing (related to
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * changing volume).
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FLAG_REMOVE_SOUND_AND_VIBRATE = 1 << 3;
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Whether to vibrate if going into the vibrate ringer mode.
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FLAG_VIBRATE = 1 << 4;
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4654bbcc6549738f3d69831b2bd9eb4accec3e9920eEric Laurent     * Indicates to VolumePanel that the volume slider should be disabled as user
4664bbcc6549738f3d69831b2bd9eb4accec3e9920eEric Laurent     * cannot change the stream volume
4674bbcc6549738f3d69831b2bd9eb4accec3e9920eEric Laurent     * @hide
4684bbcc6549738f3d69831b2bd9eb4accec3e9920eEric Laurent     */
4694bbcc6549738f3d69831b2bd9eb4accec3e9920eEric Laurent    public static final int FLAG_FIXED_VOLUME = 1 << 5;
4704bbcc6549738f3d69831b2bd9eb4accec3e9920eEric Laurent
4714bbcc6549738f3d69831b2bd9eb4accec3e9920eEric Laurent    /**
472c9d1d5f35091226e96fcfa91817480f589eb36e2Matthew Xie     * Indicates the volume set/adjust call is for Bluetooth absolute volume
473c9d1d5f35091226e96fcfa91817480f589eb36e2Matthew Xie     * @hide
474c9d1d5f35091226e96fcfa91817480f589eb36e2Matthew Xie     */
475c9d1d5f35091226e96fcfa91817480f589eb36e2Matthew Xie    public static final int FLAG_BLUETOOTH_ABS_VOLUME = 1 << 6;
476c9d1d5f35091226e96fcfa91817480f589eb36e2Matthew Xie
477c9d1d5f35091226e96fcfa91817480f589eb36e2Matthew Xie    /**
478a11b4affcad3d255aa723a89b768ea222506f2e8John Spurlock     * Adjusting the volume was prevented due to silent mode, display a hint in the UI.
479a11b4affcad3d255aa723a89b768ea222506f2e8John Spurlock     * @hide
480a11b4affcad3d255aa723a89b768ea222506f2e8John Spurlock     */
481a11b4affcad3d255aa723a89b768ea222506f2e8John Spurlock    public static final int FLAG_SHOW_SILENT_HINT = 1 << 7;
482a11b4affcad3d255aa723a89b768ea222506f2e8John Spurlock
483a11b4affcad3d255aa723a89b768ea222506f2e8John Spurlock    /**
48441d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang     * Indicates the volume call is for Hdmi Cec system audio volume
48541d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang     * @hide
48641d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang     */
48741d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang    public static final int FLAG_HDMI_SYSTEM_AUDIO_VOLUME = 1 << 8;
48841d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang
48941d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang    /**
4903c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik     * Indicates that this should only be handled if media is actively playing.
4913c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik     * @hide
4923c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik     */
4933c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik    public static final int FLAG_ACTIVE_MEDIA_ONLY = 1 << 9;
4943c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik
4953c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik    /**
496351346092acdfbfcc1d9ebf98d539d2a1196c5e8John Spurlock     * Like FLAG_SHOW_UI, but only dialog warnings and confirmations, no sliders.
497351346092acdfbfcc1d9ebf98d539d2a1196c5e8John Spurlock     * @hide
498351346092acdfbfcc1d9ebf98d539d2a1196c5e8John Spurlock     */
499351346092acdfbfcc1d9ebf98d539d2a1196c5e8John Spurlock    public static final int FLAG_SHOW_UI_WARNINGS = 1 << 10;
500351346092acdfbfcc1d9ebf98d539d2a1196c5e8John Spurlock
501351346092acdfbfcc1d9ebf98d539d2a1196c5e8John Spurlock    /**
502661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     * Adjusting the volume down from vibrated was prevented, display a hint in the UI.
503661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     * @hide
504661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     */
505661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    public static final int FLAG_SHOW_VIBRATE_HINT = 1 << 11;
506661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock
507661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    private static final String[] FLAG_NAMES = {
508661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_SHOW_UI",
509661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_ALLOW_RINGER_MODES",
510661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_PLAY_SOUND",
511661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_REMOVE_SOUND_AND_VIBRATE",
512661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_VIBRATE",
513661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_FIXED_VOLUME",
514661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_BLUETOOTH_ABS_VOLUME",
515661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_SHOW_SILENT_HINT",
516661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_HDMI_SYSTEM_AUDIO_VOLUME",
517661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_ACTIVE_MEDIA_ONLY",
518661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_SHOW_UI_WARNINGS",
519661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        "FLAG_SHOW_VIBRATE_HINT",
520661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    };
521661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock
522661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    /** @hide */
523661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    public static String flagsToString(int flags) {
524661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        final StringBuilder sb = new StringBuilder();
525661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        for (int i = 0; i < FLAG_NAMES.length; i++) {
526661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            final int flag = 1 << i;
527661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            if ((flags & flag) != 0) {
528661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock                if (sb.length() > 0) {
529661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock                    sb.append(',');
530661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock                }
531661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock                sb.append(FLAG_NAMES[i]);
532661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock                flags &= ~flag;
533661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            }
534661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        }
535661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        if (flags != 0) {
536661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            if (sb.length() > 0) {
537661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock                sb.append(',');
538661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            }
539661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            sb.append(flags);
540661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        }
541661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        return sb.toString();
542661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    }
543661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock
544661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    /**
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ringer mode that will be silent and will not vibrate. (This overrides the
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * vibrate setting.)
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setRingerMode(int)
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getRingerMode()
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int RINGER_MODE_SILENT = 0;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ringer mode that will be silent and will vibrate. (This will cause the
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * phone ringer to always vibrate, but the notification vibrate to only
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * vibrate if set.)
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setRingerMode(int)
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getRingerMode()
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int RINGER_MODE_VIBRATE = 1;
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ringer mode that may be audible and may vibrate. It will be audible if
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the volume before changing out of this mode was audible. It will vibrate
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if the vibrate setting is on.
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setRingerMode(int)
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getRingerMode()
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int RINGER_MODE_NORMAL = 2;
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5739755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock    /**
5749755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock     * Maximum valid ringer mode value. Values must start from 0 and be contiguous.
5759755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock     * @hide
5769755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock     */
5779755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock    public static final int RINGER_MODE_MAX = RINGER_MODE_NORMAL;
57872668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Vibrate type that corresponds to the ringer.
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVibrateSetting(int, int)
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getVibrateSetting(int)
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #shouldVibrate(int)
585cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
586cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode that can be queried via {@link #getRingerMode()}.
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int VIBRATE_TYPE_RINGER = 0;
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Vibrate type that corresponds to notifications.
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVibrateSetting(int, int)
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getVibrateSetting(int)
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #shouldVibrate(int)
596cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
597cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode that can be queried via {@link #getRingerMode()}.
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int VIBRATE_TYPE_NOTIFICATION = 1;
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Vibrate setting that suggests to never vibrate.
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVibrateSetting(int, int)
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getVibrateSetting(int)
606cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
607cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode that can be queried via {@link #getRingerMode()}.
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int VIBRATE_SETTING_OFF = 0;
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Vibrate setting that suggests to vibrate when possible.
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVibrateSetting(int, int)
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getVibrateSetting(int)
616cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
617cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode that can be queried via {@link #getRingerMode()}.
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int VIBRATE_SETTING_ON = 1;
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Vibrate setting that suggests to only vibrate when in the vibrate ringer
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mode.
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVibrateSetting(int, int)
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getVibrateSetting(int)
627cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
628cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode that can be queried via {@link #getRingerMode()}.
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int VIBRATE_SETTING_ONLY_SILENT = 2;
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Suggests using the default stream type. This may not be used in all
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * places a stream type is needed.
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE;
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static IAudioService sService;
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AudioManager(Context context) {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
645cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood        mUseMasterVolume = mContext.getResources().getBoolean(
646cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                com.android.internal.R.bool.config_useMasterVolume);
647b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate        mUseVolumeKeySounds = mContext.getResources().getBoolean(
648b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                com.android.internal.R.bool.config_useVolumeKeySounds);
649ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent        mUseFixedVolume = mContext.getResources().getBoolean(
650ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent                com.android.internal.R.bool.config_useFixedVolume);
651f076db407029e734703d8676f806bea94393e824Eric Laurent        sAudioPortEventHandler.init();
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static IAudioService getService()
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sService != null) {
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return sService;
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sService = IAudioService.Stub.asInterface(b);
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return sService;
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
665a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * Sends a simulated key event for a media button.
666a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * To simulate a key press, you must first send a KeyEvent built with a
667a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP}
668a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * action.
669a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * <p>The key event will be sent to the current media key event consumer which registered with
670a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}.
671a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * @param keyEvent a {@link KeyEvent} instance whose key code is one of
672a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MUTE},
673a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_HEADSETHOOK},
674a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY},
675a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_PAUSE},
676a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE},
677a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_STOP},
678a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_NEXT},
679a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS},
680a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_REWIND},
681a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_RECORD},
682a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD},
683a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_CLOSE},
684a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     {@link KeyEvent#KEYCODE_MEDIA_EJECT},
685a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     *     or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}.
686a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     */
687a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi    public void dispatchMediaKeyEvent(KeyEvent keyEvent) {
688430fc48865e5a371b08f180390946b96d73848feRoboErik        MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext);
689430fc48865e5a371b08f180390946b96d73848feRoboErik        helper.sendMediaButtonEvent(keyEvent, false);
6907ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    }
6917ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi
6927ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    /**
6937ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi     * @hide
69486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato     */
695ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    public void preDispatchKeyEvent(KeyEvent event, int stream) {
69686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato        /*
69786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato         * If the user hits another key within the play sound delay, then
69886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato         * cancel the sound
69986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato         */
700ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        int keyCode = event.getKeyCode();
70186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato        if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP
70286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE
7033346a802087f621c6441bc512dfcc17b07143fc6John Spurlock                && mVolumeKeyUpTime + AudioService.PLAY_SOUND_DELAY
70486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                        > SystemClock.uptimeMillis()) {
70586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato            /*
70686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato             * The user has hit another key during the delay (e.g., 300ms)
70786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato             * since the last volume key up, so cancel any sounds.
70886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato             */
709cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood            if (mUseMasterVolume) {
7108dc1dabd254249b7ddb8743e88fdb96580ffc585Mike Lockwood                adjustMasterVolume(ADJUST_SAME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
711cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood            } else {
712cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                adjustSuggestedStreamVolume(ADJUST_SAME,
71386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                        stream, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
714cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood            }
71586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato        }
71686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato    }
71786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato
71886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato    /**
71986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato     * @hide
72086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato     */
721ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    public void handleKeyDown(KeyEvent event, int stream) {
722ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        int keyCode = event.getKeyCode();
72386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato        switch (keyCode) {
72486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato            case KeyEvent.KEYCODE_VOLUME_UP:
72586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato            case KeyEvent.KEYCODE_VOLUME_DOWN:
72686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                /*
72786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                 * Adjust the volume in on key down since it is more
72886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                 * responsive to the user.
72986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                 */
730402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent                int flags = FLAG_SHOW_UI | FLAG_VIBRATE;
731b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate
732cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                if (mUseMasterVolume) {
733cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                    adjustMasterVolume(
734cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                            keyCode == KeyEvent.KEYCODE_VOLUME_UP
735cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                                    ? ADJUST_RAISE
7368dc1dabd254249b7ddb8743e88fdb96580ffc585Mike Lockwood                                    : ADJUST_LOWER,
7378dc1dabd254249b7ddb8743e88fdb96580ffc585Mike Lockwood                            flags);
738cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                } else {
739cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                    adjustSuggestedStreamVolume(
740cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                            keyCode == KeyEvent.KEYCODE_VOLUME_UP
741cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                                    ? ADJUST_RAISE
742cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                                    : ADJUST_LOWER,
743cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                            stream,
744cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                            flags);
745402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent                }
74686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                break;
74786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato            case KeyEvent.KEYCODE_VOLUME_MUTE:
748ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood                if (event.getRepeatCount() == 0) {
7497c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik                    MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(event, false);
750ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood                }
75186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                break;
75286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato        }
75386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato    }
75486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato
75586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato    /**
75686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato     * @hide
75786f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato     */
758ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    public void handleKeyUp(KeyEvent event, int stream) {
759ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        int keyCode = event.getKeyCode();
76086f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato        switch (keyCode) {
76186f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato            case KeyEvent.KEYCODE_VOLUME_UP:
76286f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato            case KeyEvent.KEYCODE_VOLUME_DOWN:
76386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                /*
76486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                 * Play a sound. This is done on key up since we don't want the
76586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                 * sound to play when a user holds down volume down to mute.
76686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                 */
767b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                if (mUseVolumeKeySounds) {
768b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                    if (mUseMasterVolume) {
769c4b78d206ffcdccac01e3436a4a3462bef9672edChristopher Tate                        adjustMasterVolume(ADJUST_SAME, FLAG_PLAY_SOUND);
770b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                    } else {
771b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                        int flags = FLAG_PLAY_SOUND;
772b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                        adjustSuggestedStreamVolume(
773b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                                ADJUST_SAME,
774b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                                stream,
775b89ce434993cca883818ab38f98c0b29d77e7aa2Christopher Tate                                flags);
776cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood                    }
777402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent                }
77886f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                mVolumeKeyUpTime = SystemClock.uptimeMillis();
77986f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato                break;
7807c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik            case KeyEvent.KEYCODE_VOLUME_MUTE:
7817c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik                MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(event, false);
7827c82ced4fc5b66c09a19eed9a5499039530142fbRoboErik                break;
78386f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato        }
78486f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato    }
78586f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato
78686f6786032b1a0380cf089aeeceef7e9d8982ef8Joe Onorato    /**
787ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * Indicates if the device implements a fixed volume policy.
788ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <p>Some devices may not have volume control and may operate at a fixed volume,
789ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * and may not enable muting or changing the volume of audio streams.
790ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * This method will return true on such devices.
791ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <p>The following APIs have no effect when volume is fixed:
792ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <ul>
793ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *   <li> {@link #adjustVolume(int, int)}
794ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *   <li> {@link #adjustSuggestedStreamVolume(int, int, int)}
795ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *   <li> {@link #adjustStreamVolume(int, int, int)}
796ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *   <li> {@link #setStreamVolume(int, int, int)}
797ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *   <li> {@link #setRingerMode(int)}
798ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *   <li> {@link #setStreamSolo(int, boolean)}
799ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *   <li> {@link #setStreamMute(int, boolean)}
800ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * </ul>
801ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     */
802ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent    public boolean isVolumeFixed() {
803ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent        return mUseFixedVolume;
804ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent    }
805ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent
806ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent    /**
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adjusts the volume of a particular stream by one step in a direction.
808fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
809fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * This method should only be used by applications that replace the platform-wide
810fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * management of audio settings or the main telephony application.
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC} or
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #STREAM_ALARM}
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param direction The direction to adjust the volume. One of
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #ADJUST_SAME}.
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags One or more flags.
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustVolume(int, int)
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setStreamVolume(int, int, int)
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void adjustStreamVolume(int streamType, int direction, int flags) {
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
8254767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            if (mUseMasterVolume) {
82695d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
8274767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            } else {
828ba50b97cff80e73620a0e3d13cae169e095974a7Dianne Hackborn                service.adjustStreamVolume(streamType, direction, flags,
82995d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn                        mContext.getOpPackageName());
8304767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            }
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in adjustStreamVolume", e);
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adjusts the volume of the most relevant stream. For example, if a call is
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * active, it will have the highest priority regardless of if the in-call
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * screen is showing. Another example, if music is playing in the background
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and a call is not active, the music stream will be adjusted.
841fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
842fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * This method should only be used by applications that replace the platform-wide
843fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * management of audio settings or the main telephony application.
844ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <p>This method has no effect if the device implements a fixed volume policy
845ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * as indicated by {@link #isVolumeFixed()}.
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param direction The direction to adjust the volume. One of
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #ADJUST_SAME}.
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags One or more flags.
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustSuggestedStreamVolume(int, int, int)
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustStreamVolume(int, int, int)
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setStreamVolume(int, int, int)
853ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * @see #isVolumeFixed()
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void adjustVolume(int direction, int flags) {
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
8584767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            if (mUseMasterVolume) {
85995d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
8604767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            } else {
861430fc48865e5a371b08f180390946b96d73848feRoboErik                MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext);
862430fc48865e5a371b08f180390946b96d73848feRoboErik                helper.sendAdjustVolumeBy(USE_DEFAULT_STREAM_TYPE, direction, flags);
8634767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            }
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in adjustVolume", e);
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adjusts the volume of the most relevant stream, or the given fallback
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * stream.
872fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
873fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * This method should only be used by applications that replace the platform-wide
874fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * management of audio settings or the main telephony application.
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
876ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <p>This method has no effect if the device implements a fixed volume policy
877ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * as indicated by {@link #isVolumeFixed()}.
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param direction The direction to adjust the volume. One of
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #ADJUST_SAME}.
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param suggestedStreamType The stream type that will be used if there
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is valid here.
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags One or more flags.
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustVolume(int, int)
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #adjustStreamVolume(int, int, int)
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setStreamVolume(int, int, int)
887ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * @see #isVolumeFixed()
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
8924767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            if (mUseMasterVolume) {
89395d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
8944767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            } else {
895430fc48865e5a371b08f180390946b96d73848feRoboErik                MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext);
896430fc48865e5a371b08f180390946b96d73848feRoboErik                helper.sendAdjustVolumeBy(suggestedStreamType, direction, flags);
8974767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            }
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
899cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood            Log.e(TAG, "Dead object in adjustSuggestedStreamVolume", e);
900cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood        }
901cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    }
902cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood
903cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    /**
904cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood     * Adjusts the master volume for the device's audio amplifier.
905cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood     * <p>
906cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood     *
9076c798970ccb8759d1e613b57111daa8da0ab44c7Lei Zhang     * @param steps The number of volume steps to adjust. A positive
9086c798970ccb8759d1e613b57111daa8da0ab44c7Lei Zhang     *            value will raise the volume.
9098dc1dabd254249b7ddb8743e88fdb96580ffc585Mike Lockwood     * @param flags One or more flags.
910e3f5979307fa52898459d9d09ee11bc1d65a4f7fJason Simmons     * @hide
911cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood     */
9126c798970ccb8759d1e613b57111daa8da0ab44c7Lei Zhang    public void adjustMasterVolume(int steps, int flags) {
913cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood        IAudioService service = getService();
914cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood        try {
91595d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn            service.adjustMasterVolume(steps, flags, mContext.getOpPackageName());
916cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood        } catch (RemoteException e) {
917cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood            Log.e(TAG, "Dead object in adjustMasterVolume", e);
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the current ringtone mode.
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The current ringtone mode, one of {@link #RINGER_MODE_NORMAL},
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}.
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setRingerMode(int)
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getRingerMode() {
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
931661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            return service.getRingerModeExternal();
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in getRingerMode", e);
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return RINGER_MODE_NORMAL;
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
93972668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent     * Checks valid ringer mode values.
94072668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent     *
94172668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent     * @return true if the ringer mode indicated is valid, false otherwise.
94272668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent     *
94372668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent     * @see #setRingerMode(int)
94472668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent     * @hide
94572668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent     */
94672668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent    public static boolean isValidRingerMode(int ringerMode) {
94772668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent        if (ringerMode < 0 || ringerMode > RINGER_MODE_MAX) {
94872668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent            return false;
94972668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent        }
9509755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock        IAudioService service = getService();
9519755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock        try {
9529755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock            return service.isValidRingerMode(ringerMode);
9539755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock        } catch (RemoteException e) {
9549755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock            Log.e(TAG, "Dead object in isValidRingerMode", e);
9559755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock            return false;
9569755937ed90f06db45ff5fe4510950ae1516f8f9John Spurlock        }
95772668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent    }
95872668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent
95972668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent    /**
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum volume index for a particular stream.
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param streamType The stream type whose maximum volume index is returned.
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum valid volume index for the stream.
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getStreamVolume(int)
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getStreamMaxVolume(int streamType) {
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
9694767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            if (mUseMasterVolume) {
9704767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood                return service.getMasterMaxVolume();
9714767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            } else {
9724767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood                return service.getStreamMaxVolume(streamType);
9734767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            }
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in getStreamMaxVolume", e);
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the current volume index for a particular stream.
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param streamType The stream type whose volume index is returned.
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The current volume index for the stream.
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getStreamMaxVolume(int)
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setStreamVolume(int, int, int)
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getStreamVolume(int streamType) {
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
9914767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            if (mUseMasterVolume) {
9924767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood                return service.getMasterVolume();
9934767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            } else {
9944767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood                return service.getStreamVolume(streamType);
9954767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            }
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in getStreamVolume", e);
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
100325101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent     * Get last audible volume before stream was muted.
100425101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent     *
100525101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent     * @hide
100625101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent     */
100725101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    public int getLastAudibleStreamVolume(int streamType) {
100825101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        IAudioService service = getService();
100925101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        try {
10104767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            if (mUseMasterVolume) {
1011ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood                return service.getLastAudibleMasterVolume();
10124767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            } else {
10134767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood                return service.getLastAudibleStreamVolume(streamType);
10144767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            }
101525101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        } catch (RemoteException e) {
101625101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent            Log.e(TAG, "Dead object in getLastAudibleStreamVolume", e);
101725101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent            return 0;
101825101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        }
101925101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    }
102025101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent
102125101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    /**
10226d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent     * Get the stream type whose volume is driving the UI sounds volume.
10236d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent     * UI sounds are screen lock/unlock, camera shutter, key clicks...
10244f0f120316cfcee5880191264885772677fff921John Spurlock     * It is assumed that this stream type is also tied to ringer mode changes.
10256d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent     * @hide
10266d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent     */
10276d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent    public int getMasterStreamType() {
10286d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent        IAudioService service = getService();
10296d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent        try {
10306d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent            return service.getMasterStreamType();
10316d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent        } catch (RemoteException e) {
10326d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent            Log.e(TAG, "Dead object in getMasterStreamType", e);
10336d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent            return STREAM_RING;
10346d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent        }
10356d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent    }
10366d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent
10376d5176638c2189595cede38fb92c3e7e8700e221Eric Laurent    /**
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the ringer mode.
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Silent mode will mute the volume and will not vibrate. Vibrate mode will
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mute the volume and vibrate. Normal mode will be audible and may vibrate
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * according to user settings.
1043ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <p>This method has no effect if the device implements a fixed volume policy
1044ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * as indicated by {@link #isVolumeFixed()}.
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param ringerMode The ringer mode, one of {@link #RINGER_MODE_NORMAL},
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}.
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getRingerMode()
1048ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * @see #isVolumeFixed()
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setRingerMode(int ringerMode) {
105172668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent        if (!isValidRingerMode(ringerMode)) {
105272668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent            return;
105372668b2c040b581b298b069f3b5af5ed7f212d89Eric Laurent        }
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1056661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            service.setRingerModeExternal(ringerMode, mContext.getOpPackageName());
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in setRingerMode", e);
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the volume index for a particular stream.
1064ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <p>This method has no effect if the device implements a fixed volume policy
1065ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * as indicated by {@link #isVolumeFixed()}.
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param streamType The stream whose volume index should be set.
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param index The volume index to set. See
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #getStreamMaxVolume(int)} for the largest valid value.
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags One or more flags.
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getStreamMaxVolume(int)
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getStreamVolume(int)
1072ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * @see #isVolumeFixed()
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setStreamVolume(int streamType, int index, int flags) {
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
10774767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            if (mUseMasterVolume) {
107895d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn                service.setMasterVolume(index, flags, mContext.getOpPackageName());
10794767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            } else {
108095d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn                service.setStreamVolume(streamType, index, flags, mContext.getOpPackageName());
10814767690f09ea3447b8c5c32fb28d27650aa18e00Mike Lockwood            }
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in setStreamVolume", e);
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1088fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * Returns the maximum volume index for master volume.
1089fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     *
1090fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * @hide
1091fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     */
1092fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    public int getMasterMaxVolume() {
1093fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        IAudioService service = getService();
1094fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        try {
1095fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            return service.getMasterMaxVolume();
1096fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        } catch (RemoteException e) {
1097fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            Log.e(TAG, "Dead object in getMasterMaxVolume", e);
1098fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            return 0;
1099fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        }
1100fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    }
1101fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood
1102fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    /**
1103fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * Returns the current volume index for master volume.
1104fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     *
1105fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * @return The current volume index for master volume.
1106fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * @hide
1107fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     */
1108fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    public int getMasterVolume() {
1109fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        IAudioService service = getService();
1110fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        try {
1111fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            return service.getMasterVolume();
1112fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        } catch (RemoteException e) {
1113fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            Log.e(TAG, "Dead object in getMasterVolume", e);
1114fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            return 0;
1115fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        }
1116fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    }
1117fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood
1118fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    /**
1119fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * Get last audible volume before master volume was muted.
1120fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     *
1121fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * @hide
1122fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     */
1123fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    public int getLastAudibleMasterVolume() {
1124fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        IAudioService service = getService();
1125fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        try {
1126fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            return service.getLastAudibleMasterVolume();
1127fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        } catch (RemoteException e) {
1128fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            Log.e(TAG, "Dead object in getLastAudibleMasterVolume", e);
1129fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            return 0;
1130fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        }
1131fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    }
1132fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood
1133fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    /**
1134fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * Sets the volume index for master volume.
1135fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     *
1136fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * @param index The volume index to set. See
1137ba50b97cff80e73620a0e3d13cae169e095974a7Dianne Hackborn     *            {@link #getMasterMaxVolume()} for the largest valid value.
1138fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * @param flags One or more flags.
1139ba50b97cff80e73620a0e3d13cae169e095974a7Dianne Hackborn     * @see #getMasterMaxVolume()
1140ba50b97cff80e73620a0e3d13cae169e095974a7Dianne Hackborn     * @see #getMasterVolume()
1141fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     * @hide
1142fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood     */
1143fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    public void setMasterVolume(int index, int flags) {
1144fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        IAudioService service = getService();
1145fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        try {
114695d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn            service.setMasterVolume(index, flags, mContext.getOpPackageName());
1147fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        } catch (RemoteException e) {
1148fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood            Log.e(TAG, "Dead object in setMasterVolume", e);
1149fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood        }
1150fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    }
1151fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood
1152fa7b06147c2d0f0c64fa334ed5a971cbad7cdbe5Mike Lockwood    /**
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Solo or unsolo a particular stream. All other streams are muted.
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The solo command is protected against client process death: if a process
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with an active solo request on a stream dies, all streams that were muted
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * because of this request will be unmuted automatically.
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The solo requests for a given stream are cumulative: the AudioManager
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can receive several solo requests from one or more clients and the stream
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be unsoloed only when the same number of unsolo requests are received.
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For a better user experience, applications MUST unsolo a soloed stream
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in onPause() and solo is again in onResume() if appropriate.
1165ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <p>This method has no effect if the device implements a fixed volume policy
1166ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * as indicated by {@link #isVolumeFixed()}.
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param streamType The stream to be soloed/unsoloed.
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param state The required solo state: true for solo ON, false for solo OFF
1170ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *
1171ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * @see #isVolumeFixed()
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setStreamSolo(int streamType, boolean state) {
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            service.setStreamSolo(streamType, state, mICallBack);
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in setStreamSolo", e);
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Mute or unmute an audio stream.
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The mute command is protected against client process death: if a process
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with an active mute request on a stream dies, this stream will be unmuted
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * automatically.
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The mute requests for a given stream are cumulative: the AudioManager
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can receive several mute requests from one or more clients and the stream
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be unmuted only when the same number of unmute requests are received.
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For a better user experience, applications MUST unmute a muted stream
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in onPause() and mute is again in onResume() if appropriate.
1195fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
1196fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * This method should only be used by applications that replace the platform-wide
1197fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * management of audio settings or the main telephony application.
1198ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * <p>This method has no effect if the device implements a fixed volume policy
1199ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * as indicated by {@link #isVolumeFixed()}.
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param streamType The stream to be muted/unmuted.
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param state The required mute state: true for mute ON, false for mute OFF
1203ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     *
1204ba207e76b2c5ebc01ececff351107d19a3134f3aEric Laurent     * @see #isVolumeFixed()
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setStreamMute(int streamType, boolean state) {
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            service.setStreamMute(streamType, state, mICallBack);
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in setStreamMute", e);
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
121625101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent     * get stream mute state.
121725101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent     *
121825101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent     * @hide
121925101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent     */
122025101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    public boolean isStreamMute(int streamType) {
122125101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        IAudioService service = getService();
122225101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        try {
122325101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent            return service.isStreamMute(streamType);
122425101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        } catch (RemoteException e) {
122525101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent            Log.e(TAG, "Dead object in isStreamMute", e);
122625101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent            return false;
122725101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        }
122825101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    }
122925101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent
123025101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    /**
1231ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood     * set master mute state.
1232ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood     *
1233ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood     * @hide
1234ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood     */
1235ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    public void setMasterMute(boolean state) {
12360273af55cf68d54d26d154b44d105d40fed79701Justin Koh        setMasterMute(state, FLAG_SHOW_UI);
12370273af55cf68d54d26d154b44d105d40fed79701Justin Koh    }
12380273af55cf68d54d26d154b44d105d40fed79701Justin Koh
12390273af55cf68d54d26d154b44d105d40fed79701Justin Koh    /**
12400273af55cf68d54d26d154b44d105d40fed79701Justin Koh     * set master mute state with optional flags.
12410273af55cf68d54d26d154b44d105d40fed79701Justin Koh     *
12420273af55cf68d54d26d154b44d105d40fed79701Justin Koh     * @hide
12430273af55cf68d54d26d154b44d105d40fed79701Justin Koh     */
12440273af55cf68d54d26d154b44d105d40fed79701Justin Koh    public void setMasterMute(boolean state, int flags) {
1245ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        IAudioService service = getService();
1246ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        try {
12474a21b25fad62e4f19d13ba814263841c931f56efJulia Reynolds            service.setMasterMute(state, flags, mContext.getOpPackageName(), mICallBack);
1248ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        } catch (RemoteException e) {
1249ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood            Log.e(TAG, "Dead object in setMasterMute", e);
1250ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        }
1251ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    }
1252ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood
1253ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    /**
1254ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood     * get master mute state.
1255ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood     *
1256ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood     * @hide
1257ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood     */
1258ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    public boolean isMasterMute() {
1259ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        IAudioService service = getService();
1260ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        try {
1261ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood            return service.isMasterMute();
1262ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        } catch (RemoteException e) {
1263ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood            Log.e(TAG, "Dead object in isMasterMute", e);
1264ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood            return false;
1265ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood        }
1266ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    }
1267ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood
1268ce952c8e13c535bedde77bcdb94dfcc7508475aaMike Lockwood    /**
1269402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent     * forces the stream controlled by hard volume keys
1270402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent     * specifying streamType == -1 releases control to the
1271402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent     * logic.
1272402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent     *
1273402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent     * @hide
1274402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent     */
1275402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent    public void forceVolumeControlStream(int streamType) {
127657d766f533f212d30c542cee98f31ca9630681a8Jinsuk Kim        if (mUseMasterVolume) {
127757d766f533f212d30c542cee98f31ca9630681a8Jinsuk Kim            return;
127857d766f533f212d30c542cee98f31ca9630681a8Jinsuk Kim        }
127945c90cefd13a03b852bb4b8da4be218876cbbb32Eric Laurent        IAudioService service = getService();
128045c90cefd13a03b852bb4b8da4be218876cbbb32Eric Laurent        try {
128145c90cefd13a03b852bb4b8da4be218876cbbb32Eric Laurent            service.forceVolumeControlStream(streamType, mICallBack);
128245c90cefd13a03b852bb4b8da4be218876cbbb32Eric Laurent        } catch (RemoteException e) {
128345c90cefd13a03b852bb4b8da4be218876cbbb32Eric Laurent            Log.e(TAG, "Dead object in forceVolumeControlStream", e);
128445c90cefd13a03b852bb4b8da4be218876cbbb32Eric Laurent        }
1285402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent    }
1286402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent
1287402f7f29634a9f68e7929be828a927a3e2f5efe9Eric Laurent    /**
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns whether a particular type should vibrate according to user
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * settings and the current ringer mode.
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This shouldn't be needed by most clients that use notifications to
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * vibrate. The notification manager will not vibrate if the policy doesn't
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * allow it, so the client should always set a vibrate pattern and let the
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * notification manager control whether or not to actually vibrate.
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vibrateType The type of vibrate. One of
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_TYPE_NOTIFICATION} or
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_TYPE_RINGER}.
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Whether the type should vibrate at the instant this method is
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         called.
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVibrateSetting(int, int)
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getVibrateSetting(int)
1303cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
1304cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode that can be queried via {@link #getRingerMode()}.
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean shouldVibrate(int vibrateType) {
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return service.shouldVibrate(vibrateType);
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in shouldVibrate", e);
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns whether the user's vibrate setting for a vibrate type.
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This shouldn't be needed by most clients that want to vibrate, instead
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * see {@link #shouldVibrate(int)}.
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vibrateType The type of vibrate. One of
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_TYPE_NOTIFICATION} or
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_TYPE_RINGER}.
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The vibrate setting, one of {@link #VIBRATE_SETTING_ON},
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         {@link #VIBRATE_SETTING_OFF}, or
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         {@link #VIBRATE_SETTING_ONLY_SILENT}.
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setVibrateSetting(int, int)
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #shouldVibrate(int)
1330cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
1331cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode that can be queried via {@link #getRingerMode()}.
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getVibrateSetting(int vibrateType) {
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return service.getVibrateSetting(vibrateType);
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in getVibrateSetting", e);
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return VIBRATE_SETTING_OFF;
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the setting for when the vibrate type should vibrate.
1345fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
1346fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * This method should only be used by applications that replace the platform-wide
1347fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * management of audio settings or the main telephony application.
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vibrateType The type of vibrate. One of
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_TYPE_NOTIFICATION} or
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_TYPE_RINGER}.
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param vibrateSetting The vibrate setting, one of
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_SETTING_ON},
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_SETTING_OFF}, or
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #VIBRATE_SETTING_ONLY_SILENT}.
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getVibrateSetting(int)
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #shouldVibrate(int)
1358cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * @deprecated Applications should maintain their own vibrate policy based on
1359cd1cd73baec1f93d21f67fdded5466e507431ebaEric Laurent     * current ringer mode that can be queried via {@link #getRingerMode()}.
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setVibrateSetting(int vibrateType, int vibrateSetting) {
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            service.setVibrateSetting(vibrateType, vibrateSetting);
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in setVibrateSetting", e);
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the speakerphone on or off.
1372fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
1373fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * This method should only be used by applications that replace the platform-wide
1374fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * management of audio settings or the main telephony application.
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param on set <var>true</var> to turn on speakerphone;
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *           <var>false</var> to turn it off
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setSpeakerphoneOn(boolean on){
1380c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        IAudioService service = getService();
1381c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        try {
1382c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent            service.setSpeakerphoneOn(on);
1383c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        } catch (RemoteException e) {
1384c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent            Log.e(TAG, "Dead object in setSpeakerphoneOn", e);
1385a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Checks whether the speakerphone is on or off.
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if speakerphone is on, false if it's off
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isSpeakerphoneOn() {
1394c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        IAudioService service = getService();
1395c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        try {
1396c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent            return service.isSpeakerphoneOn();
1397c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        } catch (RemoteException e) {
1398c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent            Log.e(TAG, "Dead object in isSpeakerphoneOn", e);
1399a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            return false;
1400a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     }
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14033def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    //====================================================================
14043def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    // Bluetooth SCO control
14053def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    /**
14063def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * Sticky broadcast intent action indicating that the bluetoooth SCO audio
140795b88fbe744d8ce53b5f54f6fcd90c55094a8d14Eric Laurent     * connection state has changed. The intent contains on extra {@link #EXTRA_SCO_AUDIO_STATE}
14083def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * indicating the new state which is either {@link #SCO_AUDIO_STATE_DISCONNECTED}
14093def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * or {@link #SCO_AUDIO_STATE_CONNECTED}
14103def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     *
14113def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * @see #startBluetoothSco()
1412dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * @deprecated Use  {@link #ACTION_SCO_AUDIO_STATE_UPDATED} instead
14133def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     */
1414dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent    @Deprecated
14153def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
14163def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    public static final String ACTION_SCO_AUDIO_STATE_CHANGED =
14173def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent            "android.media.SCO_AUDIO_STATE_CHANGED";
1418dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent
1419dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     /**
1420dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * Sticky broadcast intent action indicating that the bluetoooth SCO audio
1421dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * connection state has been updated.
1422dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <p>This intent has two extras:
1423dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <ul>
1424dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> {@link #EXTRA_SCO_AUDIO_STATE} - The new SCO audio state. </li>
1425dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE}- The previous SCO audio state. </li>
1426dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * </ul>
1427dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <p> EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE can be any of:
1428dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <ul>
1429dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> {@link #SCO_AUDIO_STATE_DISCONNECTED}, </li>
1430dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> {@link #SCO_AUDIO_STATE_CONNECTING} or </li>
1431dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> {@link #SCO_AUDIO_STATE_CONNECTED}, </li>
1432dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * </ul>
1433dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * @see #startBluetoothSco()
1434dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     */
1435dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1436dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent    public static final String ACTION_SCO_AUDIO_STATE_UPDATED =
1437dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent            "android.media.ACTION_SCO_AUDIO_STATE_UPDATED";
1438dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent
14393def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    /**
1440dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_CHANGED} or
1441dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the new bluetooth SCO connection state.
14423def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     */
14433def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    public static final String EXTRA_SCO_AUDIO_STATE =
14443def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent            "android.media.extra.SCO_AUDIO_STATE";
14453def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent
14463def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    /**
1447dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the previous
1448dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * bluetooth SCO connection state.
1449dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     */
1450dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent    public static final String EXTRA_SCO_AUDIO_PREVIOUS_STATE =
1451dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent            "android.media.extra.SCO_AUDIO_PREVIOUS_STATE";
1452dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent
1453dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent    /**
1454dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE
1455dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * indicating that the SCO audio channel is not established
14563def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     */
14573def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    public static final int SCO_AUDIO_STATE_DISCONNECTED = 0;
14583def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    /**
1459dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * Value for extra {@link #EXTRA_SCO_AUDIO_STATE} or {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE}
1460dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * indicating that the SCO audio channel is established
14613def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     */
14623def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    public static final int SCO_AUDIO_STATE_CONNECTED = 1;
14633def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    /**
1464dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE
1465dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * indicating that the SCO audio channel is being established
1466dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     */
1467dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent    public static final int SCO_AUDIO_STATE_CONNECTING = 2;
1468dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent    /**
1469dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * Value for extra EXTRA_SCO_AUDIO_STATE indicating that
14703def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * there was an error trying to obtain the state
14713def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     */
14723def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    public static final int SCO_AUDIO_STATE_ERROR = -1;
14733def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent
14743def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent
14753def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    /**
14763def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * Indicates if current platform supports use of SCO for off call use cases.
14773def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * Application wanted to use bluetooth SCO audio when the phone is not in call
14782ac2afeac989ea1dc326b0db996d6c6c8e00cc29Jean-Michel Trivi     * must first call this method to make sure that the platform supports this
14793def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * feature.
14803def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * @return true if bluetooth SCO can be used for audio when not in call
14813def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     *         false otherwise
14823def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * @see #startBluetoothSco()
14833def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    */
14843def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    public boolean isBluetoothScoAvailableOffCall() {
14853def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        return mContext.getResources().getBoolean(
14863def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent               com.android.internal.R.bool.config_bluetooth_sco_off_call);
14873def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    }
14883def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent
14893def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    /**
14903def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * Start bluetooth SCO audio connection.
14913def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * <p>Requires Permission:
14923def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
14933def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * <p>This method can be used by applications wanting to send and received audio
14943def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * to/from a bluetooth SCO headset while the phone is not in call.
14953def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * <p>As the SCO connection establishment can take several seconds,
14963def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * applications should not rely on the connection to be available when the method
1497dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * returns but instead register to receive the intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED}
14983def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * and wait for the state to be {@link #SCO_AUDIO_STATE_CONNECTED}.
1499dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <p>As the ACTION_SCO_AUDIO_STATE_UPDATED intent is sticky, the application can check the SCO
1500dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * audio state before calling startBluetoothSco() by reading the intent returned by the receiver
1501dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * registration. If the state is already CONNECTED, no state change will be received via the
1502dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * intent after calling startBluetoothSco(). It is however useful to call startBluetoothSco()
1503dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * so that the connection stays active in case the current initiator stops the connection.
1504dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <p>Unless the connection is already active as described above, the state will always
1505dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * transition from DISCONNECTED to CONNECTING and then either to CONNECTED if the connection
1506dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * succeeds or back to DISCONNECTED if the connection fails (e.g no headset is connected).
1507dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <p>When finished with the SCO connection or if the establishment fails, the application must
1508dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection.
15093def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * <p>Even if a SCO connection is established, the following restrictions apply on audio
15103def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * output streams so that they can be routed to SCO headset:
1511dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <ul>
1512dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> the stream type must be {@link #STREAM_VOICE_CALL} </li>
1513dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> the format must be mono </li>
1514dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> the sampling must be 16kHz or 8kHz </li>
1515dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * </ul>
15163def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * <p>The following restrictions apply on input streams:
1517dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * <ul>
1518dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> the format must be mono </li>
1519dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     *   <li> the sampling must be 8kHz </li>
1520dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * </ul>
15213def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * <p>Note that the phone application always has the priority on the usage of the SCO
15223def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * connection for telephony. If this method is called while the phone is in call
15233def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * it will be ignored. Similarly, if a call is received or sent while an application
15243def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * is using the SCO connection, the connection will be lost for the application and NOT
15253def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * returned automatically when the call ends.
152683900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * <p>NOTE: up to and including API version
152783900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual
152883900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * voice call to the bluetooth headset.
152983900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio
153083900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * connection is established.
15313def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * @see #stopBluetoothSco()
1532dc03c61fe3cd8d0805480e48a974986439977a60Eric Laurent     * @see #ACTION_SCO_AUDIO_STATE_UPDATED
15333def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     */
15343def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    public void startBluetoothSco(){
15353def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        IAudioService service = getService();
15363def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        try {
1537c18c9138cee0f0859bcab636a004ce92ca4a9ab5Eric Laurent            service.startBluetoothSco(mICallBack, mContext.getApplicationInfo().targetSdkVersion);
15383def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        } catch (RemoteException e) {
15393def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent            Log.e(TAG, "Dead object in startBluetoothSco", e);
15403def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        }
15413def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    }
15423def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent
15433def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    /**
15440daab220b2379aad33321364e8a39d2e3d4c3551Jean-Michel Trivi     * @hide
154583900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * Start bluetooth SCO audio connection in virtual call mode.
154683900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * <p>Requires Permission:
154783900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
154883900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * <p>Similar to {@link #startBluetoothSco()} with explicit selection of virtual call mode.
154983900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * Telephony and communication applications (VoIP, Video Chat) should preferably select
155083900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * virtual call mode.
155183900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * Applications using voice input for search or commands should first try raw audio connection
155283900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * with {@link #startBluetoothSco()} and fall back to startBluetoothScoVirtualCall() in case of
155383900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * failure.
155483900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * @see #startBluetoothSco()
155583900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * @see #stopBluetoothSco()
155683900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     * @see #ACTION_SCO_AUDIO_STATE_UPDATED
155783900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent     */
155883900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent    public void startBluetoothScoVirtualCall() {
155983900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent        IAudioService service = getService();
156083900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent        try {
156183900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent            service.startBluetoothScoVirtualCall(mICallBack);
156283900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent        } catch (RemoteException e) {
156383900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent            Log.e(TAG, "Dead object in startBluetoothScoVirtualCall", e);
156483900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent        }
156583900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent    }
156683900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent
156783900754f357616b9e56eaf7fc85f49b8906e987Eric Laurent    /**
15683def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * Stop bluetooth SCO audio connection.
15693def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * <p>Requires Permission:
15703def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
15713def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * <p>This method must be called by applications having requested the use of
15720daab220b2379aad33321364e8a39d2e3d4c3551Jean-Michel Trivi     * bluetooth SCO audio with {@link #startBluetoothSco()} when finished with the SCO
15730daab220b2379aad33321364e8a39d2e3d4c3551Jean-Michel Trivi     * connection or if connection fails.
15743def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     * @see #startBluetoothSco()
15753def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent     */
15760daab220b2379aad33321364e8a39d2e3d4c3551Jean-Michel Trivi    // Also used for connections started with {@link #startBluetoothScoVirtualCall()}
15773def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    public void stopBluetoothSco(){
15783def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        IAudioService service = getService();
15793def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        try {
15803def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent            service.stopBluetoothSco(mICallBack);
15813def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        } catch (RemoteException e) {
15823def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent            Log.e(TAG, "Dead object in stopBluetoothSco", e);
15833def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent        }
15843def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent    }
15853def1eec2baed0b8845ec32c871e249dc533a9d9Eric Laurent
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1587a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * Request use of Bluetooth SCO headset for communications.
1588fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
1589fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * This method should only be used by applications that replace the platform-wide
1590fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * management of audio settings or the main telephony application.
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1592a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * @param on set <var>true</var> to use bluetooth SCO for communications;
1593a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     *               <var>false</var> to not use bluetooth SCO for communications
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBluetoothScoOn(boolean on){
1596c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        IAudioService service = getService();
1597c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        try {
1598c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent            service.setBluetoothScoOn(on);
1599c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        } catch (RemoteException e) {
1600c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent            Log.e(TAG, "Dead object in setBluetoothScoOn", e);
1601a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1605a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * Checks whether communications use Bluetooth SCO.
16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1607a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * @return true if SCO is used for communications;
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         false if otherwise
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isBluetoothScoOn() {
1611c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        IAudioService service = getService();
1612c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        try {
1613c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent            return service.isBluetoothScoOn();
1614c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent        } catch (RemoteException e) {
1615c42ac9d4d03f62c3a1ba197a28a81fda44bd8b7fEric Laurent            Log.e(TAG, "Dead object in isBluetoothScoOn", e);
1616a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            return false;
1617a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1621242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent     * @param on set <var>true</var> to route A2DP audio to/from Bluetooth
1622242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent     *           headset; <var>false</var> disable A2DP audio
1623a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * @deprecated Do not use.
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1625a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public void setBluetoothA2dpOn(boolean on){
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1629242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent     * Checks whether A2DP audio routing to the Bluetooth headset is on or off.
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1631242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent     * @return true if A2DP audio is being routed to/from Bluetooth headset;
1632242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent     *         false if otherwise
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isBluetoothA2dpOn() {
1635242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent        if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"")
1636242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent            == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
1637a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            return false;
1638242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent        } else {
1639242b33870b51ea962a1d5c077d71c648eccc2b7aEric Laurent            return true;
1640a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets audio routing to the wired headset on or off.
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param on set <var>true</var> to route audio to/from wired
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *           headset; <var>false</var> disable wired headset audio
1648a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * @deprecated Do not use.
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1650a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public void setWiredHeadsetOn(boolean on){
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1654497b3fe7257d5bbee7762455c6988915bde21601Eric Laurent     * Checks whether a wired headset is connected or not.
1655497b3fe7257d5bbee7762455c6988915bde21601Eric Laurent     * <p>This is not a valid indication that audio playback is
1656497b3fe7257d5bbee7762455c6988915bde21601Eric Laurent     * actually over the wired headset as audio routing depends on other conditions.
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1658497b3fe7257d5bbee7762455c6988915bde21601Eric Laurent     * @return true if a wired headset is connected.
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         false if otherwise
1660497b3fe7257d5bbee7762455c6988915bde21601Eric Laurent     * @deprecated Use only to check is a headset is connected or not.
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isWiredHeadsetOn() {
16638b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"")
16646015a9715421a339c2b7bb63f9166504e3488179Eric Laurent                == AudioSystem.DEVICE_STATE_UNAVAILABLE &&
16658b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten            AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"")
1666a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
1667a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            return false;
1668a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        } else {
1669a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            return true;
1670a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the microphone mute on or off.
1675fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
1676fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * This method should only be used by applications that replace the platform-wide
1677fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * management of audio settings or the main telephony application.
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param on set <var>true</var> to mute the microphone;
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *           <var>false</var> to turn mute off
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setMicrophoneMute(boolean on){
168322c921a910d236abf3a1705a02541a49fdaf3a14Emily Bernier        IAudioService service = getService();
168422c921a910d236abf3a1705a02541a49fdaf3a14Emily Bernier        try {
168522c921a910d236abf3a1705a02541a49fdaf3a14Emily Bernier            service.setMicrophoneMute(on, mContext.getOpPackageName());
168622c921a910d236abf3a1705a02541a49fdaf3a14Emily Bernier        } catch (RemoteException e) {
168722c921a910d236abf3a1705a02541a49fdaf3a14Emily Bernier            Log.e(TAG, "Dead object in setMicrophoneMute", e);
168822c921a910d236abf3a1705a02541a49fdaf3a14Emily Bernier        }
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Checks whether the microphone mute is on or off.
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if microphone is muted, false if it's not
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isMicrophoneMute() {
1697a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem.isMicrophoneMuted();
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the audio mode.
1702fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * <p>
1703fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * The audio mode encompasses audio routing AND the behavior of
1704fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * the telephony layer. Therefore this method should only be used by applications that
1705fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * replace the platform-wide management of audio settings or the main telephony application.
1706fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * In particular, the {@link #MODE_IN_CALL} mode should only be used by the telephony
1707fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * application when it places a phone call, as it will cause signals from the radio layer
1708fccb25d2074358c54d4c60eb321aeaa08a5de59aJean-Michel Trivi     * to feed the platform mixer.
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17108aa798b244e32e227bad97d40ddfd7d3557030a3Jean-Michel Trivi     * @param mode  the requested audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE},
17118aa798b244e32e227bad97d40ddfd7d3557030a3Jean-Michel Trivi     *              {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}).
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              Informs the HAL about the current audio state so that
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              it can route the audio appropriately.
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setMode(int mode) {
17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
17189272b4b4a44fe1f33e3030810618194f817caaecEric Laurent            service.setMode(mode, mICallBack);
17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in setMode", e);
17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the current audio mode.
17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17278aa798b244e32e227bad97d40ddfd7d3557030a3Jean-Michel Trivi     * @return      the current audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE},
17288aa798b244e32e227bad97d40ddfd7d3557030a3Jean-Michel Trivi     *              {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}).
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              Returns the current current audio state from the HAL.
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMode() {
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return service.getMode();
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in getMode", e);
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return MODE_INVALID;
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* modes for setMode/getMode/setRoute/getRoute */
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Audio harware modes.
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Invalid audio mode.
17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_INVALID            = AudioSystem.MODE_INVALID;
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Current audio mode. Used to apply audio routing to current mode.
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_CURRENT            = AudioSystem.MODE_CURRENT;
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Normal audio mode: not ringing and no call established.
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_NORMAL             = AudioSystem.MODE_NORMAL;
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ringing audio mode. An incoming is being signaled.
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_RINGTONE           = AudioSystem.MODE_RINGTONE;
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17628f677d66d9c3ba34c97e69b2bb9e161f129af0eeJean-Michel Trivi     * In call audio mode. A telephony call is established.
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_IN_CALL            = AudioSystem.MODE_IN_CALL;
17658f677d66d9c3ba34c97e69b2bb9e161f129af0eeJean-Michel Trivi    /**
17668f677d66d9c3ba34c97e69b2bb9e161f129af0eeJean-Michel Trivi     * In communication audio mode. An audio/video chat or VoIP call is established.
17678f677d66d9c3ba34c97e69b2bb9e161f129af0eeJean-Michel Trivi     */
17688f677d66d9c3ba34c97e69b2bb9e161f129af0eeJean-Michel Trivi    public static final int MODE_IN_COMMUNICATION   = AudioSystem.MODE_IN_COMMUNICATION;
17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Routing bits for setRouting/getRouting API */
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Routing audio output to earpiece
17734a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
17744a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * setBluetoothScoOn() methods instead.
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1776a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public static final int ROUTE_EARPIECE          = AudioSystem.ROUTE_EARPIECE;
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17784a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * Routing audio output to speaker
17794a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
17804a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * setBluetoothScoOn() methods instead.
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1782a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public static final int ROUTE_SPEAKER           = AudioSystem.ROUTE_SPEAKER;
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @deprecated use {@link #ROUTE_BLUETOOTH_SCO}
17854a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
17864a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * setBluetoothScoOn() methods instead.
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Deprecated public static final int ROUTE_BLUETOOTH = AudioSystem.ROUTE_BLUETOOTH_SCO;
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Routing audio output to bluetooth SCO
17914a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
17924a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * setBluetoothScoOn() methods instead.
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1794a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public static final int ROUTE_BLUETOOTH_SCO     = AudioSystem.ROUTE_BLUETOOTH_SCO;
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Routing audio output to headset
17974a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
17984a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * setBluetoothScoOn() methods instead.
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1800a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public static final int ROUTE_HEADSET           = AudioSystem.ROUTE_HEADSET;
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Routing audio output to bluetooth A2DP
18034a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
18044a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * setBluetoothScoOn() methods instead.
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1806a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public static final int ROUTE_BLUETOOTH_A2DP    = AudioSystem.ROUTE_BLUETOOTH_A2DP;
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used for mask parameter of {@link #setRouting(int,int,int)}.
18094a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
18104a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn     * setBluetoothScoOn() methods instead.
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1812a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public static final int ROUTE_ALL               = AudioSystem.ROUTE_ALL;
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the audio routing for a specified mode
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode   audio mode to change route. E.g., MODE_RINGTONE.
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param routes bit vector of routes requested, created from one or
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               more of ROUTE_xxx types. Set bits indicate that route should be on
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mask   bit vector of routes to change, created from one or more of
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ROUTE_xxx types. Unset bits indicate the route should be left unchanged
1822b9c9d260f21b321527c4622a123af9767630d94dEric Laurent     *
1823b9c9d260f21b321527c4622a123af9767630d94dEric Laurent     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
1824a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * setBluetoothScoOn() methods instead.
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1826a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setRouting(int mode, int routes, int mask) {
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the current audio routing bit vector for a specified mode.
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode audio mode to get route (e.g., MODE_RINGTONE)
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return an audio route bit vector that can be compared with ROUTE_xxx
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * bits
1836b9c9d260f21b321527c4622a123af9767630d94dEric Laurent     * @deprecated   Do not query audio routing directly, use isSpeakerphoneOn(),
1837b9c9d260f21b321527c4622a123af9767630d94dEric Laurent     * isBluetoothScoOn(), isBluetoothA2dpOn() and isWiredHeadsetOn() methods instead.
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1839b9c9d260f21b321527c4622a123af9767630d94dEric Laurent    @Deprecated
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getRouting(int mode) {
1841a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return -1;
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Checks whether any music is active.
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if any music tracks are active.
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isMusicActive() {
185025101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        return AudioSystem.isStreamActive(STREAM_MUSIC, 0);
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18533114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi    /**
18543114ce3861f20f9a5c2c59dd2629197a1f4874a8Jean-Michel Trivi     * @hide
1855679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi     * Checks whether any music or media is actively playing on a remote device (e.g. wireless
1856679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi     *   display). Note that BT audio sinks are not considered remote devices.
1857679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi     * @return true if {@link AudioManager#STREAM_MUSIC} is active on a remote device
1858679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi     */
1859679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi    public boolean isMusicActiveRemotely() {
1860679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi        return AudioSystem.isStreamActiveRemotely(STREAM_MUSIC, 0);
1861679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi    }
1862679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi
1863679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi    /**
1864679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi     * @hide
18652380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * Checks whether the current audio focus is exclusive.
18662380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * @return true if the top of the audio focus stack requested focus
18672380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     *     with {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}
18682380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     */
18692380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi    public boolean isAudioFocusExclusive() {
18702380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi        IAudioService service = getService();
18712380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi        try {
18722380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi            return service.getCurrentAudioFocus() == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
18732380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi        } catch (RemoteException e) {
18742380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi            Log.e(TAG, "Dead object in isAudioFocusExclusive()", e);
18752380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi            return false;
18762380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi        }
18772380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi    }
18782380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi
18792380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi    /**
18808a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi     * Return a new audio session identifier not associated with any player or effect.
18819e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * An audio session identifier is a system wide unique identifier for a set of audio streams
18829e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * (one or more mixed together).
18839e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * <p>The primary use of the audio session ID is to associate audio effects to audio players,
18849e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * such as {@link MediaPlayer} or {@link AudioTrack}: all audio effects sharing the same audio
18859e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * session ID will be applied to the mixed audio content of the players that share the same
18869e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * audio session.
18879e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * <p>This method can for instance be used when creating one of the
18889e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * {@link android.media.audiofx.AudioEffect} objects to define the audio session of the effect,
18899e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * or to specify a session for a speech synthesis utterance
18909e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     * in {@link android.speech.tts.TextToSpeech.Engine}.
18918a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi     * @return a new unclaimed and unused audio session identifier, or {@link #ERROR} when the
18929e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     *   system failed to generate a new session, a condition in which audio playback or recording
18939e477e408433fe1bd0c695b1e7a0738a76009cfdJean-Michel Trivi     *   will subsequently fail as well.
18948a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi     */
1895289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi    public int generateAudioSessionId() {
18968a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi        int session = AudioSystem.newAudioSessionId();
18978a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi        if (session > 0) {
18988a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi            return session;
18998a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi        } else {
1900289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi            Log.e(TAG, "Failure to generate a new audio session ID");
19018a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi            return ERROR;
19028a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi        }
19038a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi    }
19048a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi
1905289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi    /**
1906289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi     * A special audio session ID to indicate that the audio session ID isn't known and the
1907289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi     * framework should generate a new value. This can be used when building a new
1908289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi     * {@link AudioTrack} instance with
1909289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi     * {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}.
1910289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi     */
1911289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi    public static final int AUDIO_SESSION_ID_GENERATE = AudioSystem.AUDIO_SESSION_ALLOCATE;
1912289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi
19138a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets a generic audio configuration parameter. The use of these parameters
19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * are platform dependant, see libaudio
19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ** Temporary interface - DO NOT USE
19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * TODO: Replace with a more generic key:value get/set mechanism
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * param key   name of parameter to set. Must not be null.
19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * param value value of parameter. Must not be null.
19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1927ba50b97cff80e73620a0e3d13cae169e095974a7Dianne Hackborn     * @deprecated Use {@link #setParameters(String)} instead
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1929a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    @Deprecated public void setParameter(String key, String value) {
1930a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        setParameters(key+"="+value);
1931a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
1932a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
1933a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    /**
1934a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * Sets a variable number of parameter values to audio hardware.
1935a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     *
1936a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * @param keyValuePairs list of parameters key value pairs in the form:
1937a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     *    key1=value1;key2=value2;...
1938a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     *
1939a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     */
1940a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    public void setParameters(String keyValuePairs) {
1941a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        AudioSystem.setParameters(keyValuePairs);
1942a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
1943a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
1944a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    /**
1945aac753dcf8862b416773eabaabb9d938a30f5896John Spurlock     * Gets a variable number of parameter values from audio hardware.
1946a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     *
1947a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * @param keys list of parameters
1948a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     * @return list of parameters key value pairs in the form:
1949a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     *    key1=value1;key2=value2;...
1950a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent     */
1951a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    public String getParameters(String keys) {
1952a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem.getParameters(keys);
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Sound effect identifiers */
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Keyboard and direction pad click sound
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_KEY_CLICK = 0;
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Focus has moved up
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_FOCUS_NAVIGATION_UP = 1;
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Focus has moved down
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_FOCUS_NAVIGATION_DOWN = 2;
19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Focus has moved left
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_FOCUS_NAVIGATION_LEFT = 3;
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Focus has moved right
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_FOCUS_NAVIGATION_RIGHT = 4;
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * IME standard keypress sound
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_KEYPRESS_STANDARD = 5;
19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * IME spacebar keypress sound
19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_KEYPRESS_SPACEBAR = 6;
19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * IME delete keypress sound
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_KEYPRESS_DELETE = 7;
19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * IME return_keypress sound
19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #playSoundEffect(int)
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int FX_KEYPRESS_RETURN = 8;
2001cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh
2002cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh    /**
2003cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh     * Invalid keypress sound
2004cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh     * @see #playSoundEffect(int)
2005cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh     */
2006cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh    public static final int FX_KEYPRESS_INVALID = 9;
20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide Number of sound effects
20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2010cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh    public static final int NUM_SOUND_EFFECTS = 10;
20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Plays a sound effect (Key clicks, lid open/close...)
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param effectType The type of sound effect. One of
20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_KEY_CLICK},
20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_FOCUS_NAVIGATION_UP},
20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_FOCUS_NAVIGATION_DOWN},
20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_FOCUS_NAVIGATION_LEFT},
20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_FOCUS_NAVIGATION_RIGHT},
2020105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *            {@link #FX_KEYPRESS_STANDARD},
2021105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *            {@link #FX_KEYPRESS_SPACEBAR},
2022105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *            {@link #FX_KEYPRESS_DELETE},
2023105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *            {@link #FX_KEYPRESS_RETURN},
2024cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh     *            {@link #FX_KEYPRESS_INVALID},
20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * NOTE: This version uses the UI settings to determine
20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * whether sounds are heard or not.
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void  playSoundEffect(int effectType) {
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20330c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        if (!querySoundEffectsEnabled(Process.myUserHandle().getIdentifier())) {
20340c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk            return;
20350c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        }
20360c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk
20370c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        IAudioService service = getService();
20380c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        try {
20390c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk            service.playSoundEffect(effectType);
20400c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        } catch (RemoteException e) {
20410c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk            Log.e(TAG, "Dead object in playSoundEffect"+e);
20420c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        }
20430c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk    }
20440c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk
20450c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk    /**
20460c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     * Plays a sound effect (Key clicks, lid open/close...)
20470c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     * @param effectType The type of sound effect. One of
20480c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_KEY_CLICK},
20490c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_FOCUS_NAVIGATION_UP},
20500c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_FOCUS_NAVIGATION_DOWN},
20510c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_FOCUS_NAVIGATION_LEFT},
20520c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_FOCUS_NAVIGATION_RIGHT},
20530c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_KEYPRESS_STANDARD},
20540c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_KEYPRESS_SPACEBAR},
20550c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_KEYPRESS_DELETE},
20560c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_KEYPRESS_RETURN},
20570c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     *            {@link #FX_KEYPRESS_INVALID},
20580c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     * @param userId The current user to pull sound settings from
20590c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     * NOTE: This version uses the UI settings to determine
20600c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     * whether sounds are heard or not.
20610c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     * @hide
20620c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk     */
20630c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk    public void  playSoundEffect(int effectType, int userId) {
20640c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
20650c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk            return;
20660c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        }
20670c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk
20680c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        if (!querySoundEffectsEnabled(userId)) {
20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            service.playSoundEffect(effectType);
20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in playSoundEffect"+e);
20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Plays a sound effect (Key clicks, lid open/close...)
20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param effectType The type of sound effect. One of
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_KEY_CLICK},
20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_FOCUS_NAVIGATION_UP},
20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_FOCUS_NAVIGATION_DOWN},
20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_FOCUS_NAVIGATION_LEFT},
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link #FX_FOCUS_NAVIGATION_RIGHT},
2088105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *            {@link #FX_KEYPRESS_STANDARD},
2089105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *            {@link #FX_KEYPRESS_SPACEBAR},
2090105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *            {@link #FX_KEYPRESS_DELETE},
2091105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *            {@link #FX_KEYPRESS_RETURN},
2092cacfe69b6845dd1c1c8682f67c3c52ef35214b2cJustin Koh     *            {@link #FX_KEYPRESS_INVALID},
2093a2ef57dba9ac77d8eccacd646b2b8a8d99fe9d8bEric Laurent     * @param volume Sound effect volume.
2094a2ef57dba9ac77d8eccacd646b2b8a8d99fe9d8bEric Laurent     * The volume value is a raw scalar so UI controls should be scaled logarithmically.
2095a2ef57dba9ac77d8eccacd646b2b8a8d99fe9d8bEric Laurent     * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used.
20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * NOTE: This version is for applications that have their own
20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * settings panel for enabling and controlling volume.
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void  playSoundEffect(int effectType, float volume) {
21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            service.playSoundEffectVolume(effectType, volume);
21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in playSoundEffect"+e);
21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Settings has an in memory cache, so this is fast.
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21150c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk    private boolean querySoundEffectsEnabled(int user) {
21160c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk        return Settings.System.getIntForUser(mContext.getContentResolver(),
21170c37ba318847a44cb9256e55eca1160dc1fffd4dJason Monk                Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  Load Sound effects.
21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  This method must be called when sound effects are enabled.
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void loadSoundEffects() {
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            service.loadSoundEffects();
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in loadSoundEffects"+e);
21319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  Unload Sound effects.
21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  This method can be called to free some memory when
21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  sound effects are disabled.
21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void unloadSoundEffects() {
21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IAudioService service = getService();
21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            service.unloadSoundEffects();
21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Dead object in unloadSoundEffects"+e);
21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21484050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent    /**
21492380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * @hide
21502380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * Used to indicate no audio focus has been gained or lost.
21512380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     */
21522380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi    public static final int AUDIOFOCUS_NONE = 0;
21532380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi
21542380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi    /**
2155d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration.
21567f7e67f1b60b7840011236097baad9df6dd74c20Jean-Michel Trivi     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
2157d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
2158d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2159d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public static final int AUDIOFOCUS_GAIN = 1;
2160d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
2161d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * Used to indicate a temporary gain or request of audio focus, anticipated to last a short
2162d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * amount of time. Examples of temporary changes are the playback of driving directions, or an
2163d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * event notification.
21647f7e67f1b60b7840011236097baad9df6dd74c20Jean-Michel Trivi     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
2165d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
2166d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2167d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2;
2168078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi    /**
2169078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     * Used to indicate a temporary request of audio focus, anticipated to last a short
2170983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi     * amount of time, and where it is acceptable for other audio applications to keep playing
2171983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi     * after having lowered their output level (also referred to as "ducking").
2172078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     * Examples of temporary changes are the playback of driving directions where playback of music
2173078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     * in the background is acceptable.
21747f7e67f1b60b7840011236097baad9df6dd74c20Jean-Michel Trivi     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
2175078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
2176078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     */
2177078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi    public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3;
2178078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi    /**
21792380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * Used to indicate a temporary request of audio focus, anticipated to last a short
21802380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * amount of time, during which no other applications, or system components, should play
21812380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * anything. Examples of exclusive and transient audio focus requests are voice
21822380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * memo recording and speech recognition, during which the system shouldn't play any
21832380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * notifications, and media playback should have paused.
21842380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
21852380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi     */
21862380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi    public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE = 4;
21872380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi    /**
2188078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     * Used to indicate a loss of audio focus of unknown duration.
21897f7e67f1b60b7840011236097baad9df6dd74c20Jean-Michel Trivi     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
2190078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     */
2191078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi    public static final int AUDIOFOCUS_LOSS = -1 * AUDIOFOCUS_GAIN;
2192078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi    /**
2193078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     * Used to indicate a transient loss of audio focus.
21947f7e67f1b60b7840011236097baad9df6dd74c20Jean-Michel Trivi     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
2195078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     */
2196078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi    public static final int AUDIOFOCUS_LOSS_TRANSIENT = -1 * AUDIOFOCUS_GAIN_TRANSIENT;
2197078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi    /**
2198078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     * Used to indicate a transient loss of audio focus where the loser of the audio focus can
2199983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi     * lower its output volume if it wants to continue playing (also referred to as "ducking"), as
2200983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi     * the new focus owner doesn't require others to be silent.
22017f7e67f1b60b7840011236097baad9df6dd74c20Jean-Michel Trivi     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
2202078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     */
2203078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi    public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK =
2204078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi            -1 * AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
2205d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2206d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
2207d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * Interface definition for a callback to be invoked when the audio focus of the system is
2208d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * updated.
2209d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2210d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public interface OnAudioFocusChangeListener {
2211d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        /**
2212d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi         * Called on the listener to notify it the audio focus for this listener has been changed.
2213d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi         * The focusChange value indicates whether the focus was gained,
2214d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi         * whether the focus was lost, and whether that loss is transient, or whether the new focus
2215d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi         * holder will hold it for an unknown amount of time.
2216983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi         * When losing focus, listeners can use the focus change information to decide what
2217983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi         * behavior to adopt when losing focus. A music player could for instance elect to lower
2218983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi         * the volume of its music stream (duck) for transient focus losses, and pause otherwise.
2219983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi         * @param focusChange the type of focus change, one of {@link AudioManager#AUDIOFOCUS_GAIN},
2220078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi         *   {@link AudioManager#AUDIOFOCUS_LOSS}, {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT}
2221983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi         *   and {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
2222d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi         */
22237f7e67f1b60b7840011236097baad9df6dd74c20Jean-Michel Trivi        public void onAudioFocusChange(int focusChange);
2224d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    }
2225d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2226d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
2227d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * Map to convert focus event listener IDs, as used in the AudioService audio focus stack,
2228d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * to actual listener objects.
2229d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
223030c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten    private final HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap =
2231d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            new HashMap<String, OnAudioFocusChangeListener>();
2232d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
2233d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * Lock to prevent concurrent changes to the list of focus listeners for this AudioManager
2234d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * instance.
2235d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2236d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    private final Object mFocusListenerLock = new Object();
2237d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2238d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    private OnAudioFocusChangeListener findFocusListener(String id) {
2239d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi        return mAudioFocusIdListenerMap.get(id);
2240d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    }
2241d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2242d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
2243d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * Handler for audio focus events coming from the audio service.
2244d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
224530c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten    private final FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate =
2246d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi            new FocusEventHandlerDelegate();
2247078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi
2248d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
2249d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     * Helper class to handle the forwarding of audio focus events to the appropriate listener
2250d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2251d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    private class FocusEventHandlerDelegate {
2252d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        private final Handler mHandler;
2253d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2254d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        FocusEventHandlerDelegate() {
2255d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            Looper looper;
2256d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            if ((looper = Looper.myLooper()) == null) {
2257d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                looper = Looper.getMainLooper();
2258d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            }
2259d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2260d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            if (looper != null) {
2261d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                // implement the event handler delegate to receive audio focus events
2262d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                mHandler = new Handler(looper) {
2263d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                    @Override
2264d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                    public void handleMessage(Message msg) {
2265d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                        OnAudioFocusChangeListener listener = null;
2266d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                        synchronized(mFocusListenerLock) {
2267d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                            listener = findFocusListener((String)msg.obj);
2268d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                        }
2269d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                        if (listener != null) {
2270fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                            Log.d(TAG, "AudioManager dispatching onAudioFocusChange("
2271fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                                    + msg.what + ") for " + msg.obj);
22727f7e67f1b60b7840011236097baad9df6dd74c20Jean-Michel Trivi                            listener.onAudioFocusChange(msg.what);
2273d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                        }
2274d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                    }
2275d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                };
2276d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            } else {
2277d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                mHandler = null;
2278d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            }
2279d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        }
2280d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2281d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        Handler getHandler() {
2282d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            return mHandler;
2283d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        }
2284d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    }
2285d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
228630c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten    private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() {
2287d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2288d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        public void dispatchAudioFocusChange(int focusChange, String id) {
2289d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi            Message m = mAudioFocusEventHandlerDelegate.getHandler().obtainMessage(focusChange, id);
2290d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi            mAudioFocusEventHandlerDelegate.getHandler().sendMessage(m);
2291d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        }
2292d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2293d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    };
2294d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2295d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi    private String getIdForAudioFocusListener(OnAudioFocusChangeListener l) {
2296d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        if (l == null) {
2297308e9a5d0975489982f93fd1f3728e6ed7a778d0Jean-Michel Trivi            return new String(this.toString());
2298d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        } else {
2299d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            return new String(this.toString() + l.toString());
2300d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        }
2301d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    }
2302d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2303d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
23045f53f0883a507b9d4b9b9891af560a64f746d149Xavier Ducrohet     * @hide
230546b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * Registers a listener to be called when audio focus changes. Calling this method is optional
230646b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * before calling {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, as it
230746b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * will register the listener as well if it wasn't registered already.
230846b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * @param l the listener to be notified of audio focus changes.
2309d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2310d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public void registerAudioFocusListener(OnAudioFocusChangeListener l) {
2311d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        synchronized(mFocusListenerLock) {
2312d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi            if (mAudioFocusIdListenerMap.containsKey(getIdForAudioFocusListener(l))) {
2313d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi                return;
2314d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi            }
2315d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi            mAudioFocusIdListenerMap.put(getIdForAudioFocusListener(l), l);
2316d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        }
2317d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    }
2318d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2319d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
23205f53f0883a507b9d4b9b9891af560a64f746d149Xavier Ducrohet     * @hide
232146b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * Causes the specified listener to not be called anymore when focus is gained or lost.
232246b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * @param l the listener to unregister.
2323d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2324d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public void unregisterAudioFocusListener(OnAudioFocusChangeListener l) {
2325392a2bbb52688ebd25768a7784d9edca7f498110Jean-Michel Trivi
2326d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        // remove locally
2327d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        synchronized(mFocusListenerLock) {
2328d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi            mAudioFocusIdListenerMap.remove(getIdForAudioFocusListener(l));
2329d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        }
2330d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    }
2331d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2332d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2333d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
233446b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * A failed focus change request.
2335d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2336d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public static final int AUDIOFOCUS_REQUEST_FAILED = 0;
2337d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
233846b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * A successful focus change request.
2339d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2340d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public static final int AUDIOFOCUS_REQUEST_GRANTED = 1;
2341fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     /**
2342fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi      * @hide
2343fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi      * A focus change request whose granting is delayed: the request was successful, but the
2344fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi      * requester will only be granted audio focus once the condition that prevented immediate
2345fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi      * granting has ended.
2346fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi      * See {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
2347fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi      */
2348fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi    public static final int AUDIOFOCUS_REQUEST_DELAYED = 2;
2349d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2350d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2351d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
2352d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     *  Request audio focus.
235346b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     *  Send a request to obtain the audio focus
2354d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     *  @param l the listener to be notified of audio focus changes
2355d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     *  @param streamType the main audio stream type affected by the focus request
2356d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     *  @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request
2357d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     *      is temporary, and focus will be abandonned shortly. Examples of transient requests are
2358078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     *      for the playback of driving directions, or notifications sounds.
2359983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi     *      Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for
2360983ac2b8cff85dda1f55b0d7779a33248b3fa7cfJean-Michel Trivi     *      the previous focus owner to keep playing if it ducks its audio output.
23619171db279826ee91d64eb9538a504ffed5e53b38Jean-Michel Trivi     *      Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request
23629171db279826ee91d64eb9538a504ffed5e53b38Jean-Michel Trivi     *      that benefits from the system not playing disruptive sounds like notifications, for
23639171db279826ee91d64eb9538a504ffed5e53b38Jean-Michel Trivi     *      usecases such as voice memo recording, or speech recognition.
2364078fd47e91d495175927d1a4a8b9aad039a7ba4eJean-Michel Trivi     *      Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such
2365d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     *      as the playback of a song or a video.
2366d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
2367d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2368d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) {
2369d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        int status = AUDIOFOCUS_REQUEST_FAILED;
2370fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi
2371fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        try {
2372fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            // status is guaranteed to be either AUDIOFOCUS_REQUEST_FAILED or
2373fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            // AUDIOFOCUS_REQUEST_GRANTED as focus is requested without the
2374fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            // AUDIOFOCUS_FLAG_DELAY_OK flag
2375fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            status = requestAudioFocus(l,
2376fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                    new AudioAttributes.Builder()
2377fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                            .setInternalLegacyStreamType(streamType).build(),
2378fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                    durationHint,
2379fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                    0 /* flags, legacy behavior */);
2380fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        } catch (IllegalArgumentException e) {
2381fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            Log.e(TAG, "Audio focus request denied due to ", e);
2382fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        }
2383fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi
2384fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        return status;
2385fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi    }
2386fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi
2387958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    // when adding new flags, add them to the relevant AUDIOFOCUS_FLAGS_APPS or SYSTEM masks
23880212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi    /**
23890212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * @hide
23900212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * Use this flag when requesting audio focus to indicate it is ok for the requester to not be
23910212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * granted audio focus immediately (as indicated by {@link #AUDIOFOCUS_REQUEST_DELAYED}) when
23920212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * the system is in a state where focus cannot change, but be granted focus later when
23930212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * this condition ends.
23940212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     */
2395958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    @SystemApi
2396fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi    public static final int AUDIOFOCUS_FLAG_DELAY_OK = 0x1 << 0;
23970212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi    /**
23980212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * @hide
23990212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * Use this flag when requesting audio focus to indicate that the requester
24000212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * will pause its media playback (if applicable) when losing audio focus with
24010212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * {@link #AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}, rather than ducking.
24020212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * <br>On some platforms, the ducking may be handled without the application being aware of it
24030212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * (i.e. it will not transiently lose focus). For applications that for instance play spoken
24040212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * content, such as audio book or podcast players, ducking may never be acceptable, and will
24050212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * thus always pause. This flag enables them to be declared as such whenever they request focus.
24060212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     */
24070212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi    @SystemApi
24080212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi    public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 0x1 << 1;
24090212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi    /**
24100212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * @hide
24110212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * Use this flag to lock audio focus so granting is temporarily disabled.
24120212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * <br>This flag can only be used by owners of a registered
24130212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * {@link android.media.audiopolicy.AudioPolicy} in
24140212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int, AudioPolicy)}
24150212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     */
2416958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    @SystemApi
24170212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi    public static final int AUDIOFOCUS_FLAG_LOCK     = 0x1 << 2;
2418958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    /** @hide */
24190212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi    public static final int AUDIOFOCUS_FLAGS_APPS = AUDIOFOCUS_FLAG_DELAY_OK
24200212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi            | AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS;
2421958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    /** @hide */
2422958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    public static final int AUDIOFOCUS_FLAGS_SYSTEM = AUDIOFOCUS_FLAG_DELAY_OK
24230212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi            | AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS | AUDIOFOCUS_FLAG_LOCK;
2424fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi
2425fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi    /**
2426fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     * @hide
2427958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * Request audio focus.
2428958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * Send a request to obtain the audio focus. This method differs from
2429958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)} in that it can express
2430958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * that the requester accepts delayed grants of audio focus.
2431fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     * @param l the listener to be notified of audio focus changes. It is not allowed to be null
2432fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *     when the request is flagged with {@link #AUDIOFOCUS_FLAG_DELAY_OK}.
2433fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     * @param requestAttributes non null {@link AudioAttributes} describing the main reason for
2434fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *     requesting audio focus.
2435fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     * @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request
2436fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      is temporary, and focus will be abandonned shortly. Examples of transient requests are
2437fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      for the playback of driving directions, or notifications sounds.
2438fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for
2439fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      the previous focus owner to keep playing if it ducks its audio output.
2440fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request
2441fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      that benefits from the system not playing disruptive sounds like notifications, for
2442fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      usecases such as voice memo recording, or speech recognition.
2443fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such
2444fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *      as the playback of a song or a video.
24450212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     * @param flags 0 or a combination of {link #AUDIOFOCUS_FLAG_DELAY_OK}
24460212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     *     and {@link #AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS}.
2447958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     <br>Use 0 when not using any flags for the request, which behaves like
2448958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, where either audio
2449958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     focus is granted immediately, or the grant request fails because the system is in a
2450958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     state where focus cannot change (e.g. a phone call).
2451fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     * @return {@link #AUDIOFOCUS_REQUEST_FAILED}, {@link #AUDIOFOCUS_REQUEST_GRANTED}
2452fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *     or {@link #AUDIOFOCUS_REQUEST_DELAYED}.
2453fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *     The return value is never {@link #AUDIOFOCUS_REQUEST_DELAYED} when focus is requested
2454fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     *     without the {@link #AUDIOFOCUS_FLAG_DELAY_OK} flag.
2455fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     * @throws IllegalArgumentException
2456fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi     */
2457958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    @SystemApi
2458fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi    public int requestAudioFocus(OnAudioFocusChangeListener l,
2459958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            @NonNull AudioAttributes requestAttributes,
2460fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            int durationHint,
2461fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            int flags) throws IllegalArgumentException {
2462958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi        if (flags != (flags & AUDIOFOCUS_FLAGS_APPS)) {
2463958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            throw new IllegalArgumentException("Invalid flags 0x"
2464958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                    + Integer.toHexString(flags).toUpperCase());
2465958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi        }
2466958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi        return requestAudioFocus(l, requestAttributes, durationHint,
2467958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                flags & AUDIOFOCUS_FLAGS_APPS,
2468958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                null /* no AudioPolicy*/);
2469958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    }
2470958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi
2471958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    /**
2472958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @hide
2473958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * Request or lock audio focus.
2474958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * This method is to be used by system components that have registered an
2475958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * {@link android.media.audiopolicy.AudioPolicy} to request audio focus, but also to "lock" it
2476958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * so focus granting is temporarily disabled.
2477958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @param l see the description of the same parameter in
2478958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
2479958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @param requestAttributes non null {@link AudioAttributes} describing the main reason for
2480958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     requesting audio focus.
2481958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @param durationHint see the description of the same parameter in
2482958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
2483958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @param flags 0 or a combination of {link #AUDIOFOCUS_FLAG_DELAY_OK},
24840212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi     *     {@link #AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS}, and {@link #AUDIOFOCUS_FLAG_LOCK}.
2485958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     <br>Use 0 when not using any flags for the request, which behaves like
2486958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, where either audio
2487958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     focus is granted immediately, or the grant request fails because the system is in a
2488958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     state where focus cannot change (e.g. a phone call).
2489958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @param ap a registered {@link android.media.audiopolicy.AudioPolicy} instance when locking
2490958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     focus, or null.
2491958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @return see the description of the same return value in
2492958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
2493958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @throws IllegalArgumentException
2494958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     */
24951b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    @SystemApi
2496958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    public int requestAudioFocus(OnAudioFocusChangeListener l,
2497958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            @NonNull AudioAttributes requestAttributes,
2498958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            int durationHint,
2499958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            int flags,
2500958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            AudioPolicy ap) throws IllegalArgumentException {
2501fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        // parameter checking
2502fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        if (requestAttributes == null) {
2503fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            throw new IllegalArgumentException("Illegal null AudioAttributes argument");
2504fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        }
25052380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi        if ((durationHint < AUDIOFOCUS_GAIN) ||
25062380566debfc57eb1cc07db1306ccee23b84ddd4Jean-Michel Trivi                (durationHint > AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) {
2507fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            throw new IllegalArgumentException("Invalid duration hint");
2508fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        }
2509958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi        if (flags != (flags & AUDIOFOCUS_FLAGS_SYSTEM)) {
2510fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            throw new IllegalArgumentException("Illegal flags 0x"
2511fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                + Integer.toHexString(flags).toUpperCase());
251255d1bb3483e17a11d122e68044e552d96ab55ff4Jean-Michel Trivi        }
2513fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        if (((flags & AUDIOFOCUS_FLAG_DELAY_OK) == AUDIOFOCUS_FLAG_DELAY_OK) && (l == null)) {
2514fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            throw new IllegalArgumentException(
2515fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                    "Illegal null focus listener when flagged as accepting delayed focus grant");
2516fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        }
2517958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi        if (((flags & AUDIOFOCUS_FLAG_LOCK) == AUDIOFOCUS_FLAG_LOCK) && (ap == null)) {
2518958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            throw new IllegalArgumentException(
2519958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                    "Illegal null audio policy when locking audio focus");
2520958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi        }
2521fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi
2522fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi        int status = AUDIOFOCUS_REQUEST_FAILED;
2523d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        registerAudioFocusListener(l);
2524d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        IAudioService service = getService();
2525d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        try {
2526fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            status = service.requestAudioFocus(requestAttributes, durationHint, mICallBack,
25278f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi                    mAudioFocusDispatcher, getIdForAudioFocusListener(l),
2528958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                    mContext.getOpPackageName() /* package name */, flags,
25290212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi                    ap != null ? ap.cb() : null);
2530d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        } catch (RemoteException e) {
2531958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            Log.e(TAG, "Can't call requestAudioFocus() on AudioService:", e);
2532d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        }
2533d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        return status;
2534d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    }
2535d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
25364dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi    /**
25374dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * @hide
25384dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * Used internally by telephony package to request audio focus. Will cause the focus request
25394dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * to be associated with the "voice communication" identifier only used in AudioService
25404dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * to identify this use case.
25414dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * @param streamType use STREAM_RING for focus requests when ringing, VOICE_CALL for
25424dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     *    the establishment of the call
25434dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so
25444dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     *    media applications resume after a call
25454dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     */
25464dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi    public void requestAudioFocusForCall(int streamType, int durationHint) {
25474dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi        IAudioService service = getService();
25484dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi        try {
2549fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi            service.requestAudioFocus(new AudioAttributes.Builder()
2550fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                        .setInternalLegacyStreamType(streamType).build(),
2551fd6ad747e6c268753d0edf7a5a59b6815b190854Jean-Michel Trivi                    durationHint, mICallBack, null,
2552fa9a69805b001034aa04c3b33989a7ac21522371Jean-Michel Trivi                    MediaFocusControl.IN_VOICE_COMM_FOCUS_ID,
2553958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                    mContext.getOpPackageName(),
2554958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                    AUDIOFOCUS_FLAG_LOCK,
2555958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                    null /* policy token */);
25564dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi        } catch (RemoteException e) {
2557958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService:", e);
25584dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi        }
25594dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi    }
25604dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi
25614dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi    /**
25624dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * @hide
25634dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * Used internally by telephony package to abandon audio focus, typically after a call or
25644dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * when ringing ends and the call is rejected or not answered.
25654dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}.
25664dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi     */
25674dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi    public void abandonAudioFocusForCall() {
25684dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi        IAudioService service = getService();
25694dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi        try {
2570958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            service.abandonAudioFocus(null, MediaFocusControl.IN_VOICE_COMM_FOCUS_ID,
2571958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                    null /*AudioAttributes, legacy behavior*/);
25724dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi        } catch (RemoteException e) {
2573958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            Log.e(TAG, "Can't call abandonAudioFocusForCall() on AudioService:", e);
25744dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi        }
25754dd3674e517051f130fef36d2eb201c68ff61094Jean-Michel Trivi    }
2576d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2577d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    /**
257846b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     *  Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
257946b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     *  @param l the listener with which focus was requested.
2580d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
2581d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi     */
2582d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    public int abandonAudioFocus(OnAudioFocusChangeListener l) {
2583958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi        return abandonAudioFocus(l, null /*AudioAttributes, legacy behavior*/);
2584958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    }
2585958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi
2586958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    /**
2587958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @hide
2588958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
2589958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     *  @param l the listener with which focus was requested.
2590958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @param aa the {@link AudioAttributes} with which audio focus was requested
2591958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
2592958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi     */
2593958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    @SystemApi
2594958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi    public int abandonAudioFocus(OnAudioFocusChangeListener l, AudioAttributes aa) {
2595d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        int status = AUDIOFOCUS_REQUEST_FAILED;
2596392a2bbb52688ebd25768a7784d9edca7f498110Jean-Michel Trivi        unregisterAudioFocusListener(l);
2597d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        IAudioService service = getService();
2598d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        try {
2599d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi            status = service.abandonAudioFocus(mAudioFocusDispatcher,
2600958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi                    getIdForAudioFocusListener(l), aa);
2601d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        } catch (RemoteException e) {
2602958876fe55ea0fdeb73c72240a2f2bab32833443Jean-Michel Trivi            Log.e(TAG, "Can't call abandonAudioFocus() on AudioService:", e);
2603d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        }
2604d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi        return status;
2605d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi    }
2606d5176cfe6eae954e9cef1e2ec17859a5089e1330Jean-Michel Trivi
2607d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi    //====================================================================
2608d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi    // Remote Control
2609d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi    /**
261046b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * Register a component to be the sole receiver of MEDIA_BUTTON intents.
2611d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi     * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
2612d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi     *      that will receive the media button intent. This broadcast receiver must be declared
2613f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     *      in the application manifest. The package of the component must match that of
2614f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     *      the context you're registering from.
2615b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * @deprecated Use {@link MediaSession#setMediaButtonReceiver(PendingIntent)} instead.
2616d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi     */
2617b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik    @Deprecated
2618d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi    public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
26198f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi        if (eventReceiver == null) {
26208f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi            return;
26218f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi        }
2622f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        if (!eventReceiver.getPackageName().equals(mContext.getPackageName())) {
2623f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi            Log.e(TAG, "registerMediaButtonEventReceiver() error: " +
2624f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi                    "receiver and context package names don't match");
2625f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi            return;
2626f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        }
2627f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        // construct a PendingIntent for the media button and register it
2628f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
2629f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        //     the associated intent will be handled by the component being registered
2630f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        mediaButtonIntent.setComponent(eventReceiver);
2631f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        PendingIntent pi = PendingIntent.getBroadcast(mContext,
2632f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi                0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
2633f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        registerMediaButtonIntent(pi, eventReceiver);
2634f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi    }
2635f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi
2636f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi    /**
2637961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     * Register a component to be the sole receiver of MEDIA_BUTTON intents.  This is like
2638961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     * {@link #registerMediaButtonEventReceiver(android.content.ComponentName)}, but allows
2639961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     * the buttons to go to any PendingIntent.  Note that you should only use this form if
2640961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     * you know you will continue running for the full time until unregistering the
2641961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     * PendingIntent.
2642961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     * @param eventReceiver target that will receive media button intents.  The PendingIntent
2643b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * will be sent an {@link Intent#ACTION_MEDIA_BUTTON} event when a media button action
2644b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * occurs, with {@link Intent#EXTRA_KEY_EVENT} added and holding the key code of the
2645b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * media button that was pressed.
2646b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * @deprecated Use {@link MediaSession#setMediaButtonReceiver(PendingIntent)} instead.
2647961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     */
2648b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik    @Deprecated
2649961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn    public void registerMediaButtonEventReceiver(PendingIntent eventReceiver) {
2650961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn        if (eventReceiver == null) {
2651961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn            return;
2652961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn        }
2653961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn        registerMediaButtonIntent(eventReceiver, null);
2654961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn    }
2655961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn
2656961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn    /**
2657f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     * @hide
2658f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     * no-op if (pi == null) or (eventReceiver == null)
2659f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     */
2660f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi    public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) {
2661961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn        if (pi == null) {
2662f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi            Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null parameter");
2663f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi            return;
2664f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        }
2665430fc48865e5a371b08f180390946b96d73848feRoboErik        MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext);
26666f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik        helper.addMediaButtonListener(pi, eventReceiver, mContext);
2667722b808662eb20fa91151f1e3aa05fd911d1d226Jean-Michel Trivi    }
2668722b808662eb20fa91151f1e3aa05fd911d1d226Jean-Michel Trivi
2669722b808662eb20fa91151f1e3aa05fd911d1d226Jean-Michel Trivi    /**
267046b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * Unregister the receiver of MEDIA_BUTTON intents.
267146b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
267246b3a1808a8e6fc60079af3c2292fd784a7bb0fcJean-Michel Trivi     *      that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}.
2673b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * @deprecated Use {@link MediaSession} instead.
2674d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi     */
2675b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik    @Deprecated
2676d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi    public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
26778f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi        if (eventReceiver == null) {
26788f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi            return;
26798f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi        }
2680f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        // construct a PendingIntent for the media button and unregister it
2681f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
2682f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        //     the associated intent will be handled by the component being registered
2683f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        mediaButtonIntent.setComponent(eventReceiver);
2684f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        PendingIntent pi = PendingIntent.getBroadcast(mContext,
2685f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi                0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
2686b839b83c7349533b4cb7278fd3d792b47199ba36Jean-Michel Trivi        unregisterMediaButtonIntent(pi);
2687f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi    }
2688f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi
2689f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi    /**
2690961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     * Unregister the receiver of MEDIA_BUTTON intents.
2691961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     * @param eventReceiver same PendingIntent that was registed with
2692961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     *      {@link #registerMediaButtonEventReceiver(PendingIntent)}.
2693b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * @deprecated Use {@link MediaSession} instead.
2694961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn     */
2695b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik    @Deprecated
2696961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn    public void unregisterMediaButtonEventReceiver(PendingIntent eventReceiver) {
2697961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn        if (eventReceiver == null) {
2698961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn            return;
2699961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn        }
2700b839b83c7349533b4cb7278fd3d792b47199ba36Jean-Michel Trivi        unregisterMediaButtonIntent(eventReceiver);
2701961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn    }
2702961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn
2703961cae92540763226648813d111c5b5c3b0f1597Dianne Hackborn    /**
2704f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     * @hide
2705f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi     */
2706b839b83c7349533b4cb7278fd3d792b47199ba36Jean-Michel Trivi    public void unregisterMediaButtonIntent(PendingIntent pi) {
2707430fc48865e5a371b08f180390946b96d73848feRoboErik        MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(mContext);
2708430fc48865e5a371b08f180390946b96d73848feRoboErik        helper.removeMediaButtonListener(pi);
2709d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi    }
2710d327f21626217aa3c9c0cdb7a84a742c531e59a3Jean-Michel Trivi
2711178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi    /**
2712178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * Registers the remote control client for providing information to display on the remote
2713178889eff7fa3361a5cb08d6d43846a1baf5216bJean-Michel Trivi     * controls.
2714466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * @param rcClient The remote control client from which remote controls will receive
2715466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     *      information to display.
2716466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * @see RemoteControlClient
2717b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * @deprecated Use {@link MediaSession} instead.
27188f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi     */
2719b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik    @Deprecated
27204426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public void registerRemoteControlClient(RemoteControlClient rcClient) {
2721f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
27228f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi            return;
27238f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi        }
2724430fc48865e5a371b08f180390946b96d73848feRoboErik        rcClient.registerWithSession(MediaSessionLegacyHelper.getHelper(mContext));
27258f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi    }
27268f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi
27278f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi    /**
2728fcd693a21d862ea765006f8987b8dd4b125b28c5Jean-Michel Trivi     * Unregisters the remote control client that was providing information to display on the
2729466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * remote controls.
2730466ade5ad66e7bfb1814d5e5ac76a17f8a0bcd3aJean-Michel Trivi     * @param rcClient The remote control client to unregister.
27314426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi     * @see #registerRemoteControlClient(RemoteControlClient)
2732b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * @deprecated Use {@link MediaSession} instead.
27338f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi     */
2734b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik    @Deprecated
27354426e42ac6107bf6b09f7c4cdad39eb161d8b9caJean-Michel Trivi    public void unregisterRemoteControlClient(RemoteControlClient rcClient) {
2736f0cff0456258478ba768097f73d4367ab67fd7a3Jean-Michel Trivi        if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
27378f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi            return;
27388f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi        }
2739430fc48865e5a371b08f180390946b96d73848feRoboErik        rcClient.unregisterWithSession(MediaSessionLegacyHelper.getHelper(mContext));
27408f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi    }
27418f619182cb759718f64ab95fd6d61c16138f6952Jean-Michel Trivi
274244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    /**
2743a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * Registers a {@link RemoteController} instance for it to receive media
2744a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * metadata updates and playback state information from applications using
2745a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * {@link RemoteControlClient}, and control their playback.
2746a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * <p>
2747a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * Registration requires the {@link OnClientUpdateListener} listener to be
2748a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * one of the enabled notification listeners (see
2749f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Trivi     * {@link android.service.notification.NotificationListenerService}).
2750a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     *
2751a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * @param rctlr the object to register.
2752a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * @return true if the {@link RemoteController} was successfully registered,
2753a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     *         false if an error occurred, due to an internal system error, or
2754a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     *         insufficient permissions.
2755b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * @deprecated Use
2756a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     *             {@link MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, ComponentName)}
2757a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     *             and {@link MediaController} instead.
27587ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi     */
2759b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik    @Deprecated
27607ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    public boolean registerRemoteController(RemoteController rctlr) {
27617ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi        if (rctlr == null) {
27627ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi            return false;
27637ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi        }
2764430fc48865e5a371b08f180390946b96d73848feRoboErik        rctlr.startListeningToSessions();
2765430fc48865e5a371b08f180390946b96d73848feRoboErik        return true;
27667ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    }
27677ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi
27687ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    /**
2769a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * Unregisters a {@link RemoteController}, causing it to no longer receive
2770a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * media metadata and playback state information, and no longer be capable
2771a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     * of controlling playback.
2772a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     *
2773a83487e8c618f3c267c3fe3a72d4eb9f1388d07eJean-Michel Trivi     * @param rctlr the object to unregister.
2774b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik     * @deprecated Use
2775a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     *             {@link MediaSessionManager#removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener)}
2776a66c40bf6e0fb79ead6d8a9fc29c5671fa7b1206RoboErik     *             instead.
27777ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi     */
2778b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik    @Deprecated
27797ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    public void unregisterRemoteController(RemoteController rctlr) {
27807ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi        if (rctlr == null) {
27817ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi            return;
27827ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi        }
2783430fc48865e5a371b08f180390946b96d73848feRoboErik        rctlr.stopListeningToSessions();
27847ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    }
27857ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi
27867ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi    /**
27877ddd226e7c6e759feaf2747a90be1cc06acf37a3Jean-Michel Trivi     * @hide
278844413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * Registers a remote control display that will be sent information by remote control clients.
27894a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * Use this method if your IRemoteControlDisplay is not going to display artwork, otherwise
27904a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * use {@link #registerRemoteControlDisplay(IRemoteControlDisplay, int, int)} to pass the
27914a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * artwork size directly, or
27924a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * {@link #remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay, int, int)} later if artwork
27934a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * is not yet needed.
2794f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Trivi     * <p>Registration requires the {@link Manifest.permission#MEDIA_CONTENT_CONTROL} permission.
27954a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * @param rcd the IRemoteControlDisplay
279644413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     */
279744413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    public void registerRemoteControlDisplay(IRemoteControlDisplay rcd) {
27984a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi        // passing a negative value for art work width and height as they are unknown at this stage
27994a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi        registerRemoteControlDisplay(rcd, /*w*/-1, /*h*/ -1);
28004a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi    }
28014a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi
28024a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi    /**
28034a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * @hide
28044a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * Registers a remote control display that will be sent information by remote control clients.
2805f108cdd9ee5efe354d87edd02a07b323298c116cJean-Michel Trivi     * <p>Registration requires the {@link Manifest.permission#MEDIA_CONTENT_CONTROL} permission.
28064a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * @param rcd
28074a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * @param w the maximum width of the expected bitmap. Negative values indicate it is
28084a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     *   useless to send artwork.
28094a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     * @param h the maximum height of the expected bitmap. Negative values indicate it is
28104a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     *   useless to send artwork.
28114a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi     */
28124a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi    public void registerRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h) {
281344413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        if (rcd == null) {
281444413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi            return;
281544413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        }
281644413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        IAudioService service = getService();
281744413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        try {
28184a5700556191c835116ec2a6997a4f16f464ac9dJean-Michel Trivi            service.registerRemoteControlDisplay(rcd, w, h);
281944413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        } catch (RemoteException e) {
282044413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi            Log.e(TAG, "Dead object in registerRemoteControlDisplay " + e);
282144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        }
282244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    }
282344413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi
282444413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    /**
282544413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * @hide
282644413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * Unregisters a remote control display that was sent information by remote control clients.
282744413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * @param rcd
282844413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     */
282944413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    public void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) {
283044413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        if (rcd == null) {
283144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi            return;
283244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        }
283344413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        IAudioService service = getService();
283444413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        try {
283544413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi            service.unregisterRemoteControlDisplay(rcd);
283644413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        } catch (RemoteException e) {
283744413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi            Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
283844413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        }
283944413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    }
284044413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi
284144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    /**
284244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * @hide
284344413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * Sets the artwork size a remote control display expects when receiving bitmaps.
284444413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * @param rcd
284544413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * @param w the maximum width of the expected bitmap. Negative values indicate it is
284644413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     *   useless to send artwork.
284744413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     * @param h the maximum height of the expected bitmap. Negative values indicate it is
284844413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     *   useless to send artwork.
284944413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi     */
285044413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    public void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) {
285144413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        if (rcd == null) {
285244413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi            return;
285344413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        }
285444413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        IAudioService service = getService();
285544413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        try {
285644413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi            service.remoteControlDisplayUsesBitmapSize(rcd, w, h);
285744413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        } catch (RemoteException e) {
285844413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi            Log.e(TAG, "Dead object in remoteControlDisplayUsesBitmapSize " + e);
285944413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi        }
286044413e5b514a91806a4bb4c7780029ea43be6f81Jean-Michel Trivi    }
2861ced110ec5970c632f523dfc0350b6071461ea9bcNeel Parekh
2862b5f04d6dbf5106140df367ae07f0e7708e1b650eJean-Michel Trivi    /**
28633261b537c5fdec824575a1f6ad6d8942715e82e2Jean-Michel Trivi     * @hide
2864c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     * Controls whether a remote control display needs periodic checks of the RemoteControlClient
2865c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     * playback position to verify that the estimated position has not drifted from the actual
2866c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     * position. By default the check is not performed.
2867c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     * The IRemoteControlDisplay must have been previously registered for this to have any effect.
2868c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled
2869c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     *     or disabled. No effect is null.
2870c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     * @param wantsSync if true, RemoteControlClient instances which expose their playback position
2871c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     *     to the framework will regularly compare the estimated playback position with the actual
2872c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     *     position, and will update the IRemoteControlDisplay implementation whenever a drift is
2873c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     *     detected.
2874c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi     */
2875c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi    public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd,
2876c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi            boolean wantsSync) {
2877c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi        if (rcd == null) {
2878c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi            return;
2879c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi        }
2880c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi        IAudioService service = getService();
2881c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi        try {
2882c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi            service.remoteControlDisplayWantsPlaybackPositionSync(rcd, wantsSync);
2883c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi        } catch (RemoteException e) {
2884c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi            Log.e(TAG, "Dead object in remoteControlDisplayWantsPlaybackPositionSync " + e);
2885c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi        }
2886c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi    }
2887c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi
2888c3c4babf8424f65b3d3d2700f60fae6e94e9cd00Jean-Michel Trivi    /**
2889a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * @hide
2890a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * Register the given {@link AudioPolicy}.
2891a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * This call is synchronous and blocks until the registration process successfully completed
2892a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * or failed to complete.
28931b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi     * @param policy the non-null {@link AudioPolicy} to register.
2894a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * @return {@link #ERROR} if there was an error communicating with the registration service
2895a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     *    or if the user doesn't have the required
2896a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     *    {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission,
2897a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     *    {@link #SUCCESS} otherwise.
2898a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     */
28991b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    @SystemApi
29001b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    public int registerAudioPolicy(@NonNull AudioPolicy policy) {
2901a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        if (policy == null) {
2902a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            throw new IllegalArgumentException("Illegal null AudioPolicy argument");
2903a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
2904a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        IAudioService service = getService();
2905a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        try {
29060212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi            String regId = service.registerAudioPolicy(policy.getConfig(), policy.cb(),
29070212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi                    policy.hasFocusListener());
29088fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi            if (regId == null) {
2909a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi                return ERROR;
29108fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi            } else {
29118fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi                policy.setRegistration(regId);
2912a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            }
29138fdb0d4defb6ee2ca8057d3442ead36b408b6c17Jean-Michel Trivi            // successful registration
2914a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        } catch (RemoteException e) {
2915a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            Log.e(TAG, "Dead object in registerAudioPolicyAsync()", e);
2916a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            return ERROR;
2917a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
2918a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        return SUCCESS;
2919a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    }
2920a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
2921a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    /**
2922a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * @hide
29231b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi     * @param policy the non-null {@link AudioPolicy} to unregister.
2924a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     */
29251b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    @SystemApi
29261b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi    public void unregisterAudioPolicyAsync(@NonNull AudioPolicy policy) {
2927a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        if (policy == null) {
2928a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            throw new IllegalArgumentException("Illegal null AudioPolicy argument");
2929a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
2930a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        IAudioService service = getService();
2931a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        try {
29320212be5150fb9fb3c340f3c7e51f6126372cc6f9Jean-Michel Trivi            service.unregisterAudioPolicyAsync(policy.cb());
29331b3541d5eedb332ea01066b4a78a2d06d5304044Jean-Michel Trivi            policy.setRegistration(null);
2934a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        } catch (RemoteException e) {
2935a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi            Log.e(TAG, "Dead object in unregisterAudioPolicyAsync()", e);
2936a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi        }
2937a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    }
2938a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
2939a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi
2940a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi    /**
29414050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent     *  @hide
29424050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent     *  Reload audio settings. This method is called by Settings backup
29434050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent     *  agent when audio settings are restored and causes the AudioService
29444050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent     *  to read and apply restored settings.
29454050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent     */
29464050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent    public void reloadAudioSettings() {
29474050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent        IAudioService service = getService();
29484050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent        try {
29494050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent            service.reloadAudioSettings();
29504050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent        } catch (RemoteException e) {
29514050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent            Log.e(TAG, "Dead object in reloadAudioSettings"+e);
29524050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent        }
29534050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent    }
29544050c93601b3c3609b21cc1e18a29b64747e7fa9Eric Laurent
29555a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du    /**
29565a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du     * @hide
29575a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du     * Notifies AudioService that it is connected to an A2DP device that supports absolute volume,
29585a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du     * so that AudioService can send volume change events to the A2DP device, rather than handling
29595a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du     * them.
29605a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du     */
29615a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du    public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
29625a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du        IAudioService service = getService();
29635a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du        try {
29645a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du            service.avrcpSupportsAbsoluteVolume(address, support);
29655a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du        } catch (RemoteException e) {
29665a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du            Log.e(TAG, "Dead object in avrcpSupportsAbsoluteVolume", e);
29675a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du        }
29685a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du    }
29695a0cf7a27f3953a1266af48543ccd9024f4cd89fJohn Du
29709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /**
29719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      * {@hide}
29729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      */
297330c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten     private final IBinder mICallBack = new Binder();
29747f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten
29757f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten    /**
29767f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten     * Checks whether the phone is in silent mode, with or without vibrate.
29777f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten     *
29787f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten     * @return true if phone is in silent mode, with or without vibrate.
29797f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten     *
29807f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten     * @see #getRingerMode()
29817f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten     *
29827f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten     * @hide pending API Council approval
29837f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten     */
29847f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten    public boolean isSilentMode() {
29857f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten        int ringerMode = getRingerMode();
29867f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten        boolean silentMode =
29877f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten            (ringerMode == RINGER_MODE_SILENT) ||
29887f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten            (ringerMode == RINGER_MODE_VIBRATE);
29897f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten        return silentMode;
29907f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten    }
29917f9b1fa6719dde575f8ea9858313358733fbd6c9Glenn Kasten
29928b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    // This section re-defines new output device constants from AudioSystem, because the AudioSystem
29938b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    // class is not used by other parts of the framework, which instead use definitions and methods
29948b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    // from AudioManager. AudioSystem is an internal class used by AudioManager and AudioService.
29958b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten
2996948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
2997d7c29189aa639bfac1e6efcd222e65c2c8ecf3f1Wonsik Kim     * The audio device code for representing "no device." */
2998d7c29189aa639bfac1e6efcd222e65c2c8ecf3f1Wonsik Kim    public static final int DEVICE_NONE = AudioSystem.DEVICE_NONE;
2999d7c29189aa639bfac1e6efcd222e65c2c8ecf3f1Wonsik Kim    /** @hide
3000948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *  The audio output device code for the small speaker at the front of the device used
30018b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *  when placing calls.  Does not refer to an in-ear headphone without attached microphone,
30028b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *  such as earbuds, earphones, or in-ear monitors (IEM). Those would be handled as a
30038b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *  {@link #DEVICE_OUT_WIRED_HEADPHONE}.
30048b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     */
30058b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_EARPIECE = AudioSystem.DEVICE_OUT_EARPIECE;
3006948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3007948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *  The audio output device code for the built-in speaker */
30088b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_SPEAKER = AudioSystem.DEVICE_OUT_SPEAKER;
3009948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3010948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for a wired headset with attached microphone */
30118b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_WIRED_HEADSET = AudioSystem.DEVICE_OUT_WIRED_HEADSET;
3012948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3013948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for a wired headphone without attached microphone */
30148b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
3015948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3016948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for generic Bluetooth SCO, for voice */
30178b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
3018948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3019948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for Bluetooth SCO Headset Profile (HSP) and
3020948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * Hands-Free Profile (HFP), for voice
30218b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     */
30228b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET =
30238b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten            AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
3024948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3025948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for Bluetooth SCO car audio, for voice */
30268b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT =
30278b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten            AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
3028948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3029948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for generic Bluetooth A2DP, for music */
30308b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_BLUETOOTH_A2DP = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
3031948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3032948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for Bluetooth A2DP headphones, for music */
30338b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES =
30348b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten            AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
3035948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3036948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for Bluetooth A2DP external speaker, for music */
30378b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER =
30388b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten            AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
3039948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3040948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for S/PDIF (legacy) or HDMI
3041948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * Deprecated: replaced by {@link #DEVICE_OUT_HDMI} */
30428b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_AUX_DIGITAL = AudioSystem.DEVICE_OUT_AUX_DIGITAL;
3043948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3044948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for HDMI */
3045948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_OUT_HDMI = AudioSystem.DEVICE_OUT_HDMI;
3046948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3047948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for an analog wired headset attached via a
30488b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *  docking station
30498b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     */
30508b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET;
3051948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3052948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for a digital wired headset attached via a
30538b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *  docking station
30548b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     */
30558b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET;
3056948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3057948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for a USB audio accessory. The accessory is in USB host
305859f482764e346a5c5ac118ee1f7b24da645c2559Eric Laurent     * mode and the Android device in USB device mode
305959f482764e346a5c5ac118ee1f7b24da645c2559Eric Laurent     */
306059f482764e346a5c5ac118ee1f7b24da645c2559Eric Laurent    public static final int DEVICE_OUT_USB_ACCESSORY = AudioSystem.DEVICE_OUT_USB_ACCESSORY;
3061948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3062948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for a USB audio device. The device is in USB device
306359f482764e346a5c5ac118ee1f7b24da645c2559Eric Laurent     * mode and the Android device in USB host mode
306459f482764e346a5c5ac118ee1f7b24da645c2559Eric Laurent     */
306559f482764e346a5c5ac118ee1f7b24da645c2559Eric Laurent    public static final int DEVICE_OUT_USB_DEVICE = AudioSystem.DEVICE_OUT_USB_DEVICE;
3066948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3067948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for projection output.
3068948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3069948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_OUT_REMOTE_SUBMIX = AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
3070948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3071948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code the telephony voice TX path.
3072948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3073948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_OUT_TELEPHONY_TX = AudioSystem.DEVICE_OUT_TELEPHONY_TX;
3074948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3075948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for an analog jack with line impedance detected.
3076948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3077948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_OUT_LINE = AudioSystem.DEVICE_OUT_LINE;
3078948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3079948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for HDMI Audio Return Channel.
3080948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3081948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_OUT_HDMI_ARC = AudioSystem.DEVICE_OUT_HDMI_ARC;
3082948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3083948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for S/PDIF digital connection.
3084948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3085948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_OUT_SPDIF = AudioSystem.DEVICE_OUT_SPDIF;
3086948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3087948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio output device code for built-in FM transmitter.
3088948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3089948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_OUT_FM = AudioSystem.DEVICE_OUT_FM;
3090948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3091948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * This is not used as a returned value from {@link #getDevicesForStream}, but could be
30928b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *  used in the future in a set method to select whatever default device is chosen by the
30938b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *  platform-specific implementation.
30948b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     */
30958b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public static final int DEVICE_OUT_DEFAULT = AudioSystem.DEVICE_OUT_DEFAULT;
30968b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten
3097948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3098948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for default built-in microphone
3099948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3100948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_BUILTIN_MIC = AudioSystem.DEVICE_IN_BUILTIN_MIC;
3101948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3102948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for a Bluetooth SCO headset
3103948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3104948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_BLUETOOTH_SCO_HEADSET =
3105948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
3106948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3107948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for wired headset microphone
3108948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3109948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_WIRED_HEADSET =
3110948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_WIRED_HEADSET;
3111948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3112948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for HDMI
3113948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3114948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_HDMI =
3115948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_HDMI;
3116948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3117948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for telephony voice RX path
3118948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3119948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_TELEPHONY_RX =
3120948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_TELEPHONY_RX;
3121948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3122948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for built-in microphone pointing to the back
3123948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3124948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_BACK_MIC =
3125948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_BACK_MIC;
3126948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3127948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for analog from a docking station
3128948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3129948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_ANLG_DOCK_HEADSET =
3130948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET;
3131948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3132948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for digital from a docking station
3133948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3134948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_DGTL_DOCK_HEADSET =
3135948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET;
3136948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3137948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for a USB audio accessory. The accessory is in USB host
3138948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * mode and the Android device in USB device mode
3139948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3140948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_USB_ACCESSORY =
3141948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_USB_ACCESSORY;
3142948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3143948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for a USB audio device. The device is in USB device
3144948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * mode and the Android device in USB host mode
3145948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3146948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_USB_DEVICE =
3147948d32748caaac5be06c991ebf00f74265a7849fEric Laurent                                    AudioSystem.DEVICE_IN_USB_DEVICE;
3148948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3149948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for a FM radio tuner
3150948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3151948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_FM_TUNER = AudioSystem.DEVICE_IN_FM_TUNER;
3152948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3153948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for a TV tuner
3154948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3155948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_TV_TUNER = AudioSystem.DEVICE_IN_TV_TUNER;
3156948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3157948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for an analog jack with line impedance detected
3158948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3159948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_LINE = AudioSystem.DEVICE_IN_LINE;
3160948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /** @hide
3161948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * The audio input device code for a S/PDIF digital connection
3162948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3163948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static final int DEVICE_IN_SPDIF = AudioSystem.DEVICE_IN_SPDIF;
3164112c19ee8b459439c3462767199832e5394b37a8Terry Heo    /** @hide
3165112c19ee8b459439c3462767199832e5394b37a8Terry Heo     * The audio input device code for audio loopback
3166112c19ee8b459439c3462767199832e5394b37a8Terry Heo     */
3167112c19ee8b459439c3462767199832e5394b37a8Terry Heo    public static final int DEVICE_IN_LOOPBACK = AudioSystem.DEVICE_IN_LOOPBACK;
3168948d32748caaac5be06c991ebf00f74265a7849fEric Laurent
3169948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /**
3170948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * Return true if the device code corresponds to an output device.
3171948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * @hide
3172948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3173948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static boolean isOutputDevice(int device)
3174948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    {
3175948d32748caaac5be06c991ebf00f74265a7849fEric Laurent        return (device & AudioSystem.DEVICE_BIT_IN) == 0;
3176948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    }
3177948d32748caaac5be06c991ebf00f74265a7849fEric Laurent
3178948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    /**
3179948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * Return true if the device code corresponds to an input device.
3180948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     * @hide
3181948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     */
3182948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    public static boolean isInputDevice(int device)
3183948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    {
3184948d32748caaac5be06c991ebf00f74265a7849fEric Laurent        return (device & AudioSystem.DEVICE_BIT_IN) == AudioSystem.DEVICE_BIT_IN;
3185948d32748caaac5be06c991ebf00f74265a7849fEric Laurent    }
3186948d32748caaac5be06c991ebf00f74265a7849fEric Laurent
3187948d32748caaac5be06c991ebf00f74265a7849fEric Laurent
31888b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    /**
31898b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     * Return the enabled devices for the specified output stream type.
31908b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *
31918b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     * @param streamType The stream type to query. One of
31928b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #STREAM_VOICE_CALL},
31938b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #STREAM_SYSTEM},
31948b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #STREAM_RING},
31958b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #STREAM_MUSIC},
31968b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #STREAM_ALARM},
31978b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #STREAM_NOTIFICATION},
31988b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #STREAM_DTMF}.
31998b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *
32008b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     * @return The bit-mask "or" of audio output device codes for all enabled devices on this
32018b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *         stream. Zero or more of
32028b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_EARPIECE},
32038b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_SPEAKER},
32048b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_WIRED_HEADSET},
32058b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_WIRED_HEADPHONE},
32068b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_BLUETOOTH_SCO},
32078b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_BLUETOOTH_SCO_HEADSET},
32088b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_BLUETOOTH_SCO_CARKIT},
32098b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_BLUETOOTH_A2DP},
32108b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES},
32118b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER},
3212948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_HDMI},
32138b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_ANLG_DOCK_HEADSET},
32148b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_DGTL_DOCK_HEADSET}.
3215948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_USB_ACCESSORY}.
3216948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_USB_DEVICE}.
3217948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_REMOTE_SUBMIX}.
3218948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_TELEPHONY_TX}.
3219948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_LINE}.
3220948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_HDMI_ARC}.
3221948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_SPDIF}.
3222948d32748caaac5be06c991ebf00f74265a7849fEric Laurent     *            {@link #DEVICE_OUT_FM}.
32238b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *            {@link #DEVICE_OUT_DEFAULT} is not used here.
32248b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *
32258b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     * The implementation may support additional device codes beyond those listed, so
32268b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     * the application should ignore any bits which it does not recognize.
32278b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     * Note that the information may be imprecise when the implementation
32288b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     * cannot distinguish whether a particular device is enabled.
32298b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     *
32308b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     * {@hide}
32318b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten     */
32328b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    public int getDevicesForStream(int streamType) {
32338b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        switch (streamType) {
32348b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        case STREAM_VOICE_CALL:
32358b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        case STREAM_SYSTEM:
32368b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        case STREAM_RING:
32378b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        case STREAM_MUSIC:
32388b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        case STREAM_ALARM:
32398b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        case STREAM_NOTIFICATION:
32408b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        case STREAM_DTMF:
32418b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten            return AudioSystem.getDevicesForStream(streamType);
32428b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        default:
32438b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten            return 0;
32448b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        }
32458b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    }
32468b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten
3247b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     /**
3248b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * Indicate wired accessory connection state change.
3249b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
3250b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * @param state  new connection state: 1 connected, 0 disconnected
3251b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * @param name   device name
3252b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * {@hide}
3253b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     */
3254b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent    public void setWiredDeviceConnectionState(int device, int state, String name) {
3255b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        IAudioService service = getService();
3256b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        try {
3257b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent            service.setWiredDeviceConnectionState(device, state, name);
3258b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        } catch (RemoteException e) {
3259b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent            Log.e(TAG, "Dead object in setWiredDeviceConnectionState "+e);
3260b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        }
3261b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent    }
3262b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent
3263b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     /**
32640a40ec2192e4836b2fcb6ba51a7688aa6bd4ee98Mike Lockwood     * Indicate A2DP source or sink connection state change.
3265b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * @param device Bluetooth device connected/disconnected
3266b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * @param state  new connection state (BluetoothProfile.STATE_xxx)
32670a40ec2192e4836b2fcb6ba51a7688aa6bd4ee98Mike Lockwood     * @param profile profile for the A2DP device
32680a40ec2192e4836b2fcb6ba51a7688aa6bd4ee98Mike Lockwood     * (either {@link android.bluetooth.BluetoothProfile.A2DP} or
32690a40ec2192e4836b2fcb6ba51a7688aa6bd4ee98Mike Lockwood     * {@link android.bluetooth.BluetoothProfile.A2DP_SINK})
3270b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * @return a delay in ms that the caller should wait before broadcasting
3271b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent.
3272b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     * {@hide}
3273b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent     */
32740a40ec2192e4836b2fcb6ba51a7688aa6bd4ee98Mike Lockwood    public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state,
32750a40ec2192e4836b2fcb6ba51a7688aa6bd4ee98Mike Lockwood            int profile) {
3276b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        IAudioService service = getService();
3277b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        int delay = 0;
3278b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        try {
32790a40ec2192e4836b2fcb6ba51a7688aa6bd4ee98Mike Lockwood            delay = service.setBluetoothA2dpDeviceConnectionState(device, state, profile);
3280b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        } catch (RemoteException e) {
3281b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent            Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e);
3282b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        } finally {
3283b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent            return delay;
3284b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent        }
3285b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent    }
3286b1fbaaccb656ef09a8770c28df15e3e91a452e64Eric Laurent
3287098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    /** {@hide} */
3288098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    public IRingtonePlayer getRingtonePlayer() {
3289098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        try {
3290098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            return getService().getRingtonePlayer();
3291098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        } catch (RemoteException e) {
3292098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            return null;
3293098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        }
3294098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    }
3295228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten
3296228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten    /**
329762796aac596f556a1871358bb8ce93af9d55c5a5Glenn Kasten     * Used as a key for {@link #getProperty} to request the native or optimal output sample rate
329862796aac596f556a1871358bb8ce93af9d55c5a5Glenn Kasten     * for this device's primary output stream, in decimal Hz.
3299228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten     */
3300228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten    public static final String PROPERTY_OUTPUT_SAMPLE_RATE =
3301228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten            "android.media.property.OUTPUT_SAMPLE_RATE";
3302228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten
3303228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten    /**
330462796aac596f556a1871358bb8ce93af9d55c5a5Glenn Kasten     * Used as a key for {@link #getProperty} to request the native or optimal output buffer size
330562796aac596f556a1871358bb8ce93af9d55c5a5Glenn Kasten     * for this device's primary output stream, in decimal PCM frames.
3306228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten     */
3307228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten    public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER =
3308228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten            "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
3309228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten
3310228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten    /**
331162796aac596f556a1871358bb8ce93af9d55c5a5Glenn Kasten     * Returns the value of the property with the specified key.
3312228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten     * @param key One of the strings corresponding to a property key: either
331362796aac596f556a1871358bb8ce93af9d55c5a5Glenn Kasten     *            {@link #PROPERTY_OUTPUT_SAMPLE_RATE} or
331462796aac596f556a1871358bb8ce93af9d55c5a5Glenn Kasten     *            {@link #PROPERTY_OUTPUT_FRAMES_PER_BUFFER}
3315228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten     * @return A string representing the associated value for that property key,
3316228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten     *         or null if there is no value for that key.
3317228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten     */
3318228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten    public String getProperty(String key) {
3319c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten        if (PROPERTY_OUTPUT_SAMPLE_RATE.equals(key)) {
3320c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten            int outputSampleRate = AudioSystem.getPrimaryOutputSamplingRate();
3321c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten            return outputSampleRate > 0 ? Integer.toString(outputSampleRate) : null;
3322c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten        } else if (PROPERTY_OUTPUT_FRAMES_PER_BUFFER.equals(key)) {
3323c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten            int outputFramesPerBuffer = AudioSystem.getPrimaryOutputFrameCount();
3324c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten            return outputFramesPerBuffer > 0 ? Integer.toString(outputFramesPerBuffer) : null;
3325c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten        } else {
3326c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten            // null or unknown key
3327c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten            return null;
3328c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten        }
3329228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten    }
3330228c9847a31b79f8baa80302731cdbf6a2b3c0d4Glenn Kasten
333161dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman    /**
333261dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman     * Returns the estimated latency for the given stream type in milliseconds.
333361dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman     *
333461dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman     * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need
333561dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman     * a better solution.
333661dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman     * @hide
333761dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman     */
333861dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman    public int getOutputLatency(int streamType) {
333961dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman        return AudioSystem.getOutputLatency(streamType);
334061dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman    }
334161dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman
33423346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    /**
33433346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     * Registers a global volume controller interface.  Currently limited to SystemUI.
33443346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     *
33453346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     * @hide
33463346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     */
33473346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    public void setVolumeController(IVolumeController controller) {
33483346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        try {
33493346a802087f621c6441bc512dfcc17b07143fc6John Spurlock            getService().setVolumeController(controller);
33503346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        } catch (RemoteException e) {
33513346a802087f621c6441bc512dfcc17b07143fc6John Spurlock            Log.w(TAG, "Error setting volume controller", e);
33523346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        }
33533346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    }
33543346a802087f621c6441bc512dfcc17b07143fc6John Spurlock
33553346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    /**
335633f4e04e32fac42f158733d6a731e50490fa9951John Spurlock     * Notify audio manager about volume controller visibility changes.
335733f4e04e32fac42f158733d6a731e50490fa9951John Spurlock     * Currently limited to SystemUI.
335833f4e04e32fac42f158733d6a731e50490fa9951John Spurlock     *
335933f4e04e32fac42f158733d6a731e50490fa9951John Spurlock     * @hide
336033f4e04e32fac42f158733d6a731e50490fa9951John Spurlock     */
336133f4e04e32fac42f158733d6a731e50490fa9951John Spurlock    public void notifyVolumeControllerVisible(IVolumeController controller, boolean visible) {
336233f4e04e32fac42f158733d6a731e50490fa9951John Spurlock        try {
336333f4e04e32fac42f158733d6a731e50490fa9951John Spurlock            getService().notifyVolumeControllerVisible(controller, visible);
336433f4e04e32fac42f158733d6a731e50490fa9951John Spurlock        } catch (RemoteException e) {
336533f4e04e32fac42f158733d6a731e50490fa9951John Spurlock            Log.w(TAG, "Error notifying about volume controller visibility", e);
336633f4e04e32fac42f158733d6a731e50490fa9951John Spurlock        }
336733f4e04e32fac42f158733d6a731e50490fa9951John Spurlock    }
336833f4e04e32fac42f158733d6a731e50490fa9951John Spurlock
336933f4e04e32fac42f158733d6a731e50490fa9951John Spurlock    /**
33703346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     * Only useful for volume controllers.
33713346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     * @hide
33723346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     */
33733346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    public boolean isStreamAffectedByRingerMode(int streamType) {
33743346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        try {
33753346a802087f621c6441bc512dfcc17b07143fc6John Spurlock            return getService().isStreamAffectedByRingerMode(streamType);
33763346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        } catch (RemoteException e) {
33773346a802087f621c6441bc512dfcc17b07143fc6John Spurlock            Log.w(TAG, "Error calling isStreamAffectedByRingerMode", e);
33783346a802087f621c6441bc512dfcc17b07143fc6John Spurlock            return false;
33793346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        }
33803346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    }
33813346a802087f621c6441bc512dfcc17b07143fc6John Spurlock
33823346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    /**
33833346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     * Only useful for volume controllers.
33843346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     * @hide
33853346a802087f621c6441bc512dfcc17b07143fc6John Spurlock     */
33863346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    public void disableSafeMediaVolume() {
33873346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        try {
33883346a802087f621c6441bc512dfcc17b07143fc6John Spurlock            getService().disableSafeMediaVolume();
33893346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        } catch (RemoteException e) {
33903346a802087f621c6441bc512dfcc17b07143fc6John Spurlock            Log.w(TAG, "Error disabling safe media volume", e);
33913346a802087f621c6441bc512dfcc17b07143fc6John Spurlock        }
33923346a802087f621c6441bc512dfcc17b07143fc6John Spurlock    }
3393a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3394a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3395661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     * Only useful for volume controllers.
3396661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     * @hide
3397661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     */
3398661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    public void setRingerModeInternal(int ringerMode) {
3399661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        try {
3400661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            getService().setRingerModeInternal(ringerMode, mContext.getOpPackageName());
3401661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        } catch (RemoteException e) {
3402661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            Log.w(TAG, "Error calling setRingerModeInternal", e);
3403661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        }
3404661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    }
3405661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock
3406661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    /**
3407661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     * Only useful for volume controllers.
3408661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     * @hide
3409661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock     */
3410661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    public int getRingerModeInternal() {
3411661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        try {
3412661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            return getService().getRingerModeInternal();
3413661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        } catch (RemoteException e) {
3414661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            Log.w(TAG, "Error calling getRingerModeInternal", e);
3415661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock            return RINGER_MODE_NORMAL;
3416661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock        }
3417661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    }
3418661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock
3419661f2cf45860d2e10924e6b69966a9afe255f28bJohn Spurlock    /**
342041d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang     * Set Hdmi Cec system audio mode.
342141d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang     *
342241d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang     * @param on whether to be on system audio mode
34236f34f5ab8ab1b1db7887e5405d8b0031e105ab05Jungshik Jang     * @return output device type. 0 (DEVICE_NONE) if failed to set device.
342441d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang     * @hide
342541d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang     */
342612307ca810e8100981b2b60e3f2c6a7e451b9774Jungshik Jang    public int setHdmiSystemAudioSupported(boolean on) {
342741d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang        try {
342812307ca810e8100981b2b60e3f2c6a7e451b9774Jungshik Jang            return getService().setHdmiSystemAudioSupported(on);
342941d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang        } catch (RemoteException e) {
343041d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang            Log.w(TAG, "Error setting system audio mode", e);
34316f34f5ab8ab1b1db7887e5405d8b0031e105ab05Jungshik Jang            return AudioSystem.DEVICE_NONE;
343241d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang        }
343341d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang    }
343441d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang
343541d974631c5f525da49c88d34cecedd5a4cfeda8Jungshik Jang    /**
3436e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo     * Returns true if Hdmi Cec system audio mode is supported.
3437e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo     *
3438e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo     * @hide
3439e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo     */
3440e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo    @SystemApi
3441e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo    public boolean isHdmiSystemAudioSupported() {
3442e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo        try {
3443e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo            return getService().isHdmiSystemAudioSupported();
3444e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo        } catch (RemoteException e) {
3445e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo            Log.w(TAG, "Error querying system audio mode", e);
3446e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo            return false;
3447e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo        }
3448e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo    }
3449e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo
3450e7d6d97f0d95b9e8982b0d4d9f5e8ce688291940Terry Heo    /**
3451a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * Return codes for listAudioPorts(), createAudioPatch() ...
3452a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3453a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3454a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /** @hide
3455a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * CANDIDATE FOR PUBLIC API
3456a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3457a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public static final int SUCCESS = AudioSystem.SUCCESS;
34588a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi    /**
34598a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi     * A default error code.
3460a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3461a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public static final int ERROR = AudioSystem.ERROR;
3462a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /** @hide
3463a8b6bd88cfb010c9e9aa1339e504fd593919e1e0Jean-Michel Trivi     * CANDIDATE FOR PUBLIC API
3464a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3465a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public static final int ERROR_BAD_VALUE = AudioSystem.BAD_VALUE;
3466a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /** @hide
3467a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3468a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public static final int ERROR_INVALID_OPERATION = AudioSystem.INVALID_OPERATION;
3469a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /** @hide
3470a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3471a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public static final int ERROR_PERMISSION_DENIED = AudioSystem.PERMISSION_DENIED;
3472a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /** @hide
3473a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3474a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public static final int ERROR_NO_INIT = AudioSystem.NO_INIT;
3475ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent    /**
3476ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent     * An error code indicating that the object reporting it is no longer valid and needs to
3477ff0d9f098e51c54e1a030ed21fd980680cb7b405Eric Laurent     * be recreated.
3478a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3479a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public static final int ERROR_DEAD_OBJECT = AudioSystem.DEAD_OBJECT;
3480a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3481a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3482a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * Returns a list of descriptors for all audio ports managed by the audio framework.
3483a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * Audio ports are nodes in the audio framework or audio hardware that can be configured
3484a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * or connected and disconnected with createAudioPatch() or releaseAudioPatch().
3485a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * See AudioPort for a list of attributes of each audio port.
3486a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @param ports An AudioPort ArrayList where the list will be returned.
3487a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3488a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3489a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public int listAudioPorts(ArrayList<AudioPort> ports) {
3490b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return updateAudioPortCache(ports, null);
3491a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3492a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3493a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3494a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * Specialized version of listAudioPorts() listing only audio devices (AudioDevicePort)
3495a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @see listAudioPorts(ArrayList<AudioPort>)
3496a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3497a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3498a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public int listAudioDevicePorts(ArrayList<AudioPort> devices) {
3499b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
3500b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        int status = updateAudioPortCache(ports, null);
3501b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (status == SUCCESS) {
3502b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            devices.clear();
3503b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            for (int i = 0; i < ports.size(); i++) {
3504b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                if (ports.get(i) instanceof AudioDevicePort) {
3505b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    devices.add(ports.get(i));
3506b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                }
3507b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
3508b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
3509b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return status;
3510a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3511a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3512a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3513a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * Create a connection between two or more devices. The framework will reject the request if
3514a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * device types are not compatible or the implementation does not support the requested
3515a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * configuration.
3516a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * NOTE: current implementation is limited to one source and one sink per patch.
3517a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @param patch AudioPatch array where the newly created patch will be returned.
3518a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *              As input, if patch[0] is not null, the specified patch will be replaced by the
3519a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *              new patch created. This avoids calling releaseAudioPatch() when modifying a
3520a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *              patch and allows the implementation to optimize transitions.
3521a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @param sources List of source audio ports. All must be AudioPort.ROLE_SOURCE.
3522a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @param sinks   List of sink audio ports. All must be AudioPort.ROLE_SINK.
3523a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *
3524a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @return - {@link #SUCCESS} if connection is successful.
3525a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR_BAD_VALUE} if incompatible device types are passed.
3526a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR_INVALID_OPERATION} if the requested connection is not supported.
3527a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR_PERMISSION_DENIED} if the client does not have permission to create
3528a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         a patch.
3529a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR_DEAD_OBJECT} if the server process is dead
3530a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR} if patch cannot be connected for any other reason.
3531a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *
3532a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         patch[0] contains the newly created patch
3533a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3534a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3535a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public int createAudioPatch(AudioPatch[] patch,
3536a198a29250acb7c3e918f1566727190966bb336fEric Laurent                                 AudioPortConfig[] sources,
3537a198a29250acb7c3e918f1566727190966bb336fEric Laurent                                 AudioPortConfig[] sinks) {
3538b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return AudioSystem.createAudioPatch(patch, sources, sinks);
3539a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3540a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3541a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3542a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * Releases an existing audio patch connection.
3543a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @param patch The audio patch to disconnect.
3544a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @return - {@link #SUCCESS} if disconnection is successful.
3545a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR_BAD_VALUE} if the specified patch does not exist.
3546a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR_PERMISSION_DENIED} if the client does not have permission to release
3547a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         a patch.
3548a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR_DEAD_OBJECT} if the server process is dead
3549a198a29250acb7c3e918f1566727190966bb336fEric Laurent     *         - {@link #ERROR} if patch cannot be released for any other reason.
3550a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3551a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3552a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public int releaseAudioPatch(AudioPatch patch) {
3553b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return AudioSystem.releaseAudioPatch(patch);
3554a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3555a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3556a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3557a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * List all existing connections between audio ports.
3558a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @param patches An AudioPatch array where the list will be returned.
3559a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3560a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3561a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public int listAudioPatches(ArrayList<AudioPatch> patches) {
3562b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return updateAudioPortCache(null, patches);
3563a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3564a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3565a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3566a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * Set the gain on the specified AudioPort. The AudioGainConfig config is build by
3567a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * AudioGain.buildConfig()
3568a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3569a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3570a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public int setAudioPortGain(AudioPort port, AudioGainConfig gain) {
35713a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        if (port == null || gain == null) {
35723a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent            return ERROR_BAD_VALUE;
35733a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        }
35743a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        AudioPortConfig activeConfig = port.activeConfig();
35753a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        AudioPortConfig config = new AudioPortConfig(port, activeConfig.samplingRate(),
35763a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent                                        activeConfig.channelMask(), activeConfig.format(), gain);
35773a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        config.mConfigMask = AudioPortConfig.GAIN;
35783a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        return AudioSystem.setAudioPortConfig(config);
3579a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3580a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3581a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3582a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * Listener registered by client to be notified upon new audio port connections,
3583a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * disconnections or attributes update.
3584a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3585a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3586a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public interface OnAudioPortUpdateListener {
3587a198a29250acb7c3e918f1566727190966bb336fEric Laurent        /**
3588a198a29250acb7c3e918f1566727190966bb336fEric Laurent         * Callback method called upon audio port list update.
3589a198a29250acb7c3e918f1566727190966bb336fEric Laurent         * @param portList the updated list of audio ports
3590a198a29250acb7c3e918f1566727190966bb336fEric Laurent         */
3591fdaed9dcb63171379fd7c5a6208014bac505dbc6Eric Laurent        public void onAudioPortListUpdate(AudioPort[] portList);
3592a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3593a198a29250acb7c3e918f1566727190966bb336fEric Laurent        /**
3594a198a29250acb7c3e918f1566727190966bb336fEric Laurent         * Callback method called upon audio patch list update.
3595a198a29250acb7c3e918f1566727190966bb336fEric Laurent         * @param patchList the updated list of audio patches
3596a198a29250acb7c3e918f1566727190966bb336fEric Laurent         */
3597fdaed9dcb63171379fd7c5a6208014bac505dbc6Eric Laurent        public void onAudioPatchListUpdate(AudioPatch[] patchList);
3598a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3599a198a29250acb7c3e918f1566727190966bb336fEric Laurent        /**
3600a198a29250acb7c3e918f1566727190966bb336fEric Laurent         * Callback method called when the mediaserver dies
3601a198a29250acb7c3e918f1566727190966bb336fEric Laurent         */
3602fdaed9dcb63171379fd7c5a6208014bac505dbc6Eric Laurent        public void onServiceDied();
3603a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3604a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3605a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3606700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent     * Register an audio port list update listener.
3607a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3608a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3609a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public void registerAudioPortUpdateListener(OnAudioPortUpdateListener l) {
3610f076db407029e734703d8676f806bea94393e824Eric Laurent        sAudioPortEventHandler.registerListener(l);
3611a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3612a198a29250acb7c3e918f1566727190966bb336fEric Laurent
3613a198a29250acb7c3e918f1566727190966bb336fEric Laurent    /**
3614700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent     * Unregister an audio port list update listener.
3615a198a29250acb7c3e918f1566727190966bb336fEric Laurent     * @hide
3616a198a29250acb7c3e918f1566727190966bb336fEric Laurent     */
3617a198a29250acb7c3e918f1566727190966bb336fEric Laurent    public void unregisterAudioPortUpdateListener(OnAudioPortUpdateListener l) {
3618f076db407029e734703d8676f806bea94393e824Eric Laurent        sAudioPortEventHandler.unregisterListener(l);
3619a198a29250acb7c3e918f1566727190966bb336fEric Laurent    }
3620b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3621b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    //
3622b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    // AudioPort implementation
3623b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    //
3624b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3625b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    static final int AUDIOPORT_GENERATION_INIT = 0;
3626f076db407029e734703d8676f806bea94393e824Eric Laurent    static Integer sAudioPortGeneration = new Integer(AUDIOPORT_GENERATION_INIT);
3627f076db407029e734703d8676f806bea94393e824Eric Laurent    static ArrayList<AudioPort> sAudioPortsCached = new ArrayList<AudioPort>();
3628f076db407029e734703d8676f806bea94393e824Eric Laurent    static ArrayList<AudioPatch> sAudioPatchesCached = new ArrayList<AudioPatch>();
3629b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3630f076db407029e734703d8676f806bea94393e824Eric Laurent    static int resetAudioPortGeneration() {
3631b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        int generation;
3632f076db407029e734703d8676f806bea94393e824Eric Laurent        synchronized (sAudioPortGeneration) {
3633f076db407029e734703d8676f806bea94393e824Eric Laurent            generation = sAudioPortGeneration;
3634f076db407029e734703d8676f806bea94393e824Eric Laurent            sAudioPortGeneration = AUDIOPORT_GENERATION_INIT;
3635b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
3636b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return generation;
3637b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
3638b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3639f076db407029e734703d8676f806bea94393e824Eric Laurent    static int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches) {
3640f076db407029e734703d8676f806bea94393e824Eric Laurent        synchronized (sAudioPortGeneration) {
3641b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3642f076db407029e734703d8676f806bea94393e824Eric Laurent            if (sAudioPortGeneration == AUDIOPORT_GENERATION_INIT) {
3643b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                int[] patchGeneration = new int[1];
3644b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                int[] portGeneration = new int[1];
3645b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                int status;
3646b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                ArrayList<AudioPort> newPorts = new ArrayList<AudioPort>();
3647b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                ArrayList<AudioPatch> newPatches = new ArrayList<AudioPatch>();
3648b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3649b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                do {
3650b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    newPorts.clear();
3651b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    status = AudioSystem.listAudioPorts(newPorts, portGeneration);
3652b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    if (status != SUCCESS) {
3653b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                        Log.w(TAG, "updateAudioPortCache: listAudioPorts failed");
3654b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                        return status;
3655b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    }
3656b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    newPatches.clear();
3657b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    status = AudioSystem.listAudioPatches(newPatches, patchGeneration);
3658b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    if (status != SUCCESS) {
3659b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                        Log.w(TAG, "updateAudioPortCache: listAudioPatches failed");
3660b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                        return status;
3661b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    }
3662b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                } while (patchGeneration[0] != portGeneration[0]);
3663b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3664b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                for (int i = 0; i < newPatches.size(); i++) {
3665b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    for (int j = 0; j < newPatches.get(i).sources().length; j++) {
3666b4e0909fc4fb08f513cb2b39a919b189621be87cEric Laurent                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sources()[j],
3667b4e0909fc4fb08f513cb2b39a919b189621be87cEric Laurent                                                                   newPorts);
3668b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                        newPatches.get(i).sources()[j] = portCfg;
3669b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    }
3670b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    for (int j = 0; j < newPatches.get(i).sinks().length; j++) {
3671b4e0909fc4fb08f513cb2b39a919b189621be87cEric Laurent                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sinks()[j],
3672b4e0909fc4fb08f513cb2b39a919b189621be87cEric Laurent                                                                   newPorts);
3673b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                        newPatches.get(i).sinks()[j] = portCfg;
3674b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                    }
3675b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                }
3676b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                for (Iterator<AudioPatch> i = newPatches.iterator(); i.hasNext(); ) {
3677b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                    AudioPatch newPatch = i.next();
3678b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                    boolean hasInvalidPort = false;
3679b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                    for (AudioPortConfig portCfg : newPatch.sources()) {
3680b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                        if (portCfg == null) {
3681b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                            hasInvalidPort = true;
3682b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                            break;
3683b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                        }
3684b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                    }
3685b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                    for (AudioPortConfig portCfg : newPatch.sinks()) {
3686b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                        if (portCfg == null) {
3687b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                            hasInvalidPort = true;
3688b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                            break;
3689b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                        }
3690b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                    }
3691b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                    if (hasInvalidPort) {
3692b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                        // Temporarily remove patches with invalid ports. One who created the patch
3693b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                        // is responsible for dealing with the port change.
3694b561ccedd89f92b249c06522e960b135a02107d8Wonsik Kim                        i.remove();
3695b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                    }
3696b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                }
3697b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3698f076db407029e734703d8676f806bea94393e824Eric Laurent                sAudioPortsCached = newPorts;
3699f076db407029e734703d8676f806bea94393e824Eric Laurent                sAudioPatchesCached = newPatches;
3700f076db407029e734703d8676f806bea94393e824Eric Laurent                sAudioPortGeneration = portGeneration[0];
3701b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
3702b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            if (ports != null) {
3703b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                ports.clear();
3704f076db407029e734703d8676f806bea94393e824Eric Laurent                ports.addAll(sAudioPortsCached);
3705b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
3706b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            if (patches != null) {
3707b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                patches.clear();
3708f076db407029e734703d8676f806bea94393e824Eric Laurent                patches.addAll(sAudioPatchesCached);
3709b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
3710b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
3711b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return SUCCESS;
3712b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
3713b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
3714f076db407029e734703d8676f806bea94393e824Eric Laurent    static AudioPortConfig updatePortConfig(AudioPortConfig portCfg, ArrayList<AudioPort> ports) {
3715b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        AudioPort port = portCfg.port();
3716b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        int k;
3717b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        for (k = 0; k < ports.size(); k++) {
3718b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            // compare handles because the port returned by JNI is not of the correct
3719b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            // subclass
3720b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            if (ports.get(k).handle().equals(port.handle())) {
3721b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                port = ports.get(k);
3722b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                break;
3723b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
3724b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
3725b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (k == ports.size()) {
3726b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            // this hould never happen
3727b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            Log.e(TAG, "updatePortConfig port not found for handle: "+port.handle().id());
3728b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            return null;
3729b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
3730b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        AudioGainConfig gainCfg = portCfg.gain();
3731b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (gainCfg != null) {
3732b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            AudioGain gain = port.gain(gainCfg.index());
3733b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            gainCfg = gain.buildConfig(gainCfg.mode(),
3734b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       gainCfg.channelMask(),
3735b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       gainCfg.values(),
3736b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       gainCfg.rampDurationMs());
3737b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
3738b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return port.buildConfig(portCfg.samplingRate(),
3739b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 portCfg.channelMask(),
3740b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 portCfg.format(),
3741b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 gainCfg);
3742b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
37439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3744