summaryrefslogtreecommitdiffstats
path: root/media/java
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2009-07-17 12:17:14 -0700
committerEric Laurent <elaurent@google.com>2009-07-23 06:03:39 -0700
commita553c25b33c99b345cf1c8688f8df0ed8df14e5a (patch)
tree025c461b13e66ad0ceac8d0f8d9b13fd88ae168a /media/java
parentebd7bc54028949619bbf3fa5ed6c1188f588c230 (diff)
downloadframeworks_base-a553c25b33c99b345cf1c8688f8df0ed8df14e5a.zip
frameworks_base-a553c25b33c99b345cf1c8688f8df0ed8df14e5a.tar.gz
frameworks_base-a553c25b33c99b345cf1c8688f8df0ed8df14e5a.tar.bz2
Fix issue 1795088 Improve audio routing code
Initial commit for review. Integrated comments after patch set 1 review. Fixed lockup in AudioFlinger::ThreadBase::exit() Fixed lockup when playing tone with AudioPlocyService startTone()
Diffstat (limited to 'media/java')
-rw-r--r--media/java/android/media/AudioFormat.java55
-rw-r--r--media/java/android/media/AudioManager.java203
-rw-r--r--media/java/android/media/AudioRecord.java36
-rw-r--r--media/java/android/media/AudioService.java701
-rw-r--r--media/java/android/media/AudioSystem.java157
-rw-r--r--media/java/android/media/AudioTrack.java35
-rw-r--r--media/java/android/media/IAudioService.aidl16
-rw-r--r--media/java/android/media/JetPlayer.java2
-rw-r--r--media/java/android/media/ToneGenerator.java4
9 files changed, 595 insertions, 614 deletions
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 0732b61..500f6a4 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -37,15 +37,58 @@ public class AudioFormat {
public static final int ENCODING_PCM_8BIT = 3; // accessed by native code
/** Invalid audio channel configuration */
- public static final int CHANNEL_CONFIGURATION_INVALID = 0;
+ /** @deprecated use CHANNEL_INVALID instead */
+ @Deprecated public static final int CHANNEL_CONFIGURATION_INVALID = 0;
/** Default audio channel configuration */
- public static final int CHANNEL_CONFIGURATION_DEFAULT = 1;
+ /** @deprecated use CHANNEL_OUT_DEFAULT or CHANNEL_IN_DEFAULT instead */
+ @Deprecated public static final int CHANNEL_CONFIGURATION_DEFAULT = 1;
/** Mono audio configuration */
- public static final int CHANNEL_CONFIGURATION_MONO = 2;
+ /** @deprecated use CHANNEL_OUT_MONO or CHANNEL_IN_MONO instead */
+ @Deprecated public static final int CHANNEL_CONFIGURATION_MONO = 2;
/** Stereo (2 channel) audio configuration */
- public static final int CHANNEL_CONFIGURATION_STEREO = 3;
-
-}
+ /** @deprecated use CHANNEL_OUT_STEREO or CHANNEL_IN_STEREO instead */
+ @Deprecated public static final int CHANNEL_CONFIGURATION_STEREO = 3;
+ /** Invalid audio channel mask */
+ public static final int CHANNEL_INVALID = -1;
+ /** Default audio channel mask */
+ // Channel mask definitions must be kept in sync with native values in include/media/AudioSystem.h
+ public static final int CHANNEL_OUT_DEFAULT = 0;
+ public static final int CHANNEL_OUT_FRONT_LEFT = 0x1;
+ public static final int CHANNEL_OUT_FRONT_RIGHT = 0x2;
+ public static final int CHANNEL_OUT_FRONT_CENTER = 0x4;
+ public static final int CHANNEL_OUT_LOW_FREQUENCY = 0x8;
+ public static final int CHANNEL_OUT_BACK_LEFT = 0x10;
+ public static final int CHANNEL_OUT_BACK_RIGHT = 0x20;
+ public static final int CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40;
+ public static final int CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80;
+ public static final int CHANNEL_OUT_BACK_CENTER = 0x100;
+ public static final int CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT;
+ public static final int CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT);
+ public static final int CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT);
+ public static final int CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER);
+ public static final int CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT);
+ public static final int CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+ CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER);
+ public static final int CHANNEL_IN_DEFAULT = 0;
+ public static final int CHANNEL_IN_LEFT = 0x10000;
+ public static final int CHANNEL_IN_RIGHT = 0x20000;
+ public static final int CHANNEL_IN_FRONT = 0x40000;
+ public static final int CHANNEL_IN_BACK = 0x80000;
+ public static final int CHANNEL_IN_LEFT_PROCESSED = 0x100000;
+ public static final int CHANNEL_IN_RIGHT_PROCESSED = 0x200000;
+ public static final int CHANNEL_IN_FRONT_PROCESSED = 0x400000;
+ public static final int CHANNEL_IN_BACK_PROCESSED = 0x800000;
+ public static final int CHANNEL_IN_PRESSURE = 0x1000000;
+ public static final int CHANNEL_IN_X_AXIS = 0x2000000;
+ public static final int CHANNEL_IN_Y_AXIS = 0x4000000;
+ public static final int CHANNEL_IN_Z_AXIS = 0x8000000;
+ public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT;
+ public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT);
+}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index a65a417..040d4bc 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -140,11 +140,17 @@ public class AudioManager {
public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION;
/** @hide The audio stream for phone calls when connected to bluetooth */
public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO;
+ /** @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */
+ public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED;
+ /** The audio stream for DTMF Tones */
+ public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF;
+ /** @hide The audio stream for text to speech (TTS) */
+ public static final int STREAM_TTS = AudioSystem.STREAM_TTS;
/** Number of audio streams */
/**
* @deprecated Use AudioSystem.getNumStreamTypes() instead
*/
- public static final int NUM_STREAMS = AudioSystem.NUM_STREAMS;
+ @Deprecated public static final int NUM_STREAMS = AudioSystem.NUM_STREAMS;
/** @hide Maximum volume index values for audio streams */
@@ -156,6 +162,9 @@ public class AudioManager {
8, // STREAM_ALARM
8, // STREAM_NOTIFICATION
16, // STREAM_BLUETOOTH_SCO
+ 8, // STREAM_SYSTEM_ENFORCED
+ 16, // STREAM_DTMF
+ 16 // STREAM_TTS
};
/** @hide Default volume index values for audio streams */
@@ -166,7 +175,10 @@ public class AudioManager {
11, // STREAM_MUSIC
6, // STREAM_ALARM
5, // STREAM_NOTIFICATION
- 7 // STREAM_BLUETOOTH_SCO
+ 7, // STREAM_BLUETOOTH_SCO
+ 5, // STREAM_SYSTEM_ENFORCED
+ 11, // STREAM_DTMF
+ 11 // STREAM_TTS
};
/**
@@ -637,9 +649,11 @@ public class AudioManager {
* <var>false</var> to turn it off
*/
public void setSpeakerphoneOn(boolean on){
- // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
- // MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
- setRoutingP(MODE_INVALID, on ? ROUTE_SPEAKER: 0, ROUTE_SPEAKER);
+ if (on) {
+ AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_SPEAKER);
+ } else {
+ AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_NONE);
+ }
}
/**
@@ -648,41 +662,47 @@ public class AudioManager {
* @return true if speakerphone is on, false if it's off
*/
public boolean isSpeakerphoneOn() {
- return (getRoutingP(MODE_IN_CALL) & ROUTE_SPEAKER) == 0 ? false : true;
+ if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION) == AudioSystem.FORCE_SPEAKER) {
+ return true;
+ } else {
+ return false;
+ }
}
/**
- * Sets audio routing to the Bluetooth headset on or off.
+ * Request use of Bluetooth SCO headset for communications.
*
- * @param on set <var>true</var> to route SCO (voice) audio to/from Bluetooth
- * headset; <var>false</var> to route audio to/from phone earpiece
+ * @param on set <var>true</var> to use bluetooth SCO for communications;
+ * <var>false</var> to not use bluetooth SCO for communications
*/
public void setBluetoothScoOn(boolean on){
- // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
- // MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
- setRoutingP(MODE_INVALID, on ? ROUTE_BLUETOOTH_SCO: 0, ROUTE_BLUETOOTH_SCO);
+ if (on) {
+ AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_BT_SCO);
+ } else {
+ AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_NONE);
+ }
}
/**
- * Checks whether audio routing to the Bluetooth headset is on or off.
+ * Checks whether communications use Bluetooth SCO.
*
- * @return true if SCO audio is being routed to/from Bluetooth headset;
+ * @return true if SCO is used for communications;
* false if otherwise
*/
public boolean isBluetoothScoOn() {
- return (getRoutingP(MODE_IN_CALL) & ROUTE_BLUETOOTH_SCO) == 0 ? false : true;
+ if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION) == AudioSystem.FORCE_BT_SCO) {
+ return true;
+ } else {
+ return false;
+ }
}
/**
- * Sets A2DP audio routing to the Bluetooth headset on or off.
- *
* @param on set <var>true</var> to route A2DP audio to/from Bluetooth
* headset; <var>false</var> disable A2DP audio
+ * @deprecated Do not use.
*/
- public void setBluetoothA2dpOn(boolean on){
- // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
- // MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
- setRoutingP(MODE_INVALID, on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
+ @Deprecated public void setBluetoothA2dpOn(boolean on){
}
/**
@@ -692,7 +712,12 @@ public class AudioManager {
* false if otherwise
*/
public boolean isBluetoothA2dpOn() {
- return (getRoutingP(MODE_NORMAL) & ROUTE_BLUETOOTH_A2DP) == 0 ? false : true;
+ if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,"")
+ == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
+ return false;
+ } else {
+ return true;
+ }
}
/**
@@ -700,12 +725,9 @@ public class AudioManager {
*
* @param on set <var>true</var> to route audio to/from wired
* headset; <var>false</var> disable wired headset audio
- * @hide
+ * @deprecated Do not use.
*/
- public void setWiredHeadsetOn(boolean on){
- // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
- // MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
- setRoutingP(MODE_INVALID, on ? ROUTE_HEADSET: 0, ROUTE_HEADSET);
+ @Deprecated public void setWiredHeadsetOn(boolean on){
}
/**
@@ -713,10 +735,14 @@ public class AudioManager {
*
* @return true if audio is being routed to/from wired headset;
* false if otherwise
- * @hide
*/
public boolean isWiredHeadsetOn() {
- return (getRoutingP(MODE_NORMAL) & ROUTE_HEADSET) == 0 ? false : true;
+ if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,"")
+ == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
+ return false;
+ } else {
+ return true;
+ }
}
/**
@@ -726,12 +752,7 @@ public class AudioManager {
* <var>false</var> to turn mute off
*/
public void setMicrophoneMute(boolean on){
- IAudioService service = getService();
- try {
- service.setMicrophoneMute(on);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in setMicrophoneMute", e);
- }
+ AudioSystem.muteMicrophone(on);
}
/**
@@ -740,13 +761,7 @@ public class AudioManager {
* @return true if microphone is muted, false if it's not
*/
public boolean isMicrophoneMute() {
- IAudioService service = getService();
- try {
- return service.isMicrophoneMute();
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in isMicrophoneMute", e);
- return false;
- }
+ return AudioSystem.isMicrophoneMuted();
}
/**
@@ -809,32 +824,39 @@ public class AudioManager {
/* Routing bits for setRouting/getRouting API */
/**
* Routing audio output to earpiece
+ * @deprecated
*/
- public static final int ROUTE_EARPIECE = AudioSystem.ROUTE_EARPIECE;
+ @Deprecated public static final int ROUTE_EARPIECE = AudioSystem.ROUTE_EARPIECE;
/**
* Routing audio output to spaker
+ * @deprecated
*/
- public static final int ROUTE_SPEAKER = AudioSystem.ROUTE_SPEAKER;
+ @Deprecated public static final int ROUTE_SPEAKER = AudioSystem.ROUTE_SPEAKER;
/**
* @deprecated use {@link #ROUTE_BLUETOOTH_SCO}
+ * @deprecated
*/
@Deprecated public static final int ROUTE_BLUETOOTH = AudioSystem.ROUTE_BLUETOOTH_SCO;
/**
* Routing audio output to bluetooth SCO
+ * @deprecated
*/
- public static final int ROUTE_BLUETOOTH_SCO = AudioSystem.ROUTE_BLUETOOTH_SCO;
+ @Deprecated public static final int ROUTE_BLUETOOTH_SCO = AudioSystem.ROUTE_BLUETOOTH_SCO;
/**
* Routing audio output to headset
+ * @deprecated
*/
- public static final int ROUTE_HEADSET = AudioSystem.ROUTE_HEADSET;
+ @Deprecated public static final int ROUTE_HEADSET = AudioSystem.ROUTE_HEADSET;
/**
* Routing audio output to bluetooth A2DP
+ * @deprecated
*/
- public static final int ROUTE_BLUETOOTH_A2DP = AudioSystem.ROUTE_BLUETOOTH_A2DP;
+ @Deprecated public static final int ROUTE_BLUETOOTH_A2DP = AudioSystem.ROUTE_BLUETOOTH_A2DP;
/**
* Used for mask parameter of {@link #setRouting(int,int,int)}.
+ * @deprecated
*/
- public static final int ROUTE_ALL = AudioSystem.ROUTE_ALL;
+ @Deprecated public static final int ROUTE_ALL = AudioSystem.ROUTE_ALL;
/**
* Sets the audio routing for a specified mode
@@ -846,16 +868,10 @@ public class AudioManager {
* ROUTE_xxx types. Unset bits indicate the route should be left unchanged
*
* @deprecated Do not set audio routing directly, use setSpeakerphoneOn(),
- * setBluetoothScoOn(), setBluetoothA2dpOn() and setWiredHeadsetOn() methods instead.
+ * setBluetoothScoOn() methods instead.
*/
-
+ @Deprecated
public void setRouting(int mode, int routes, int mask) {
- IAudioService service = getService();
- try {
- service.setRouting(mode, routes, mask);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in setRouting", e);
- }
}
/**
@@ -869,13 +885,7 @@ public class AudioManager {
*/
@Deprecated
public int getRouting(int mode) {
- IAudioService service = getService();
- try {
- return service.getRouting(mode);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in getRouting", e);
- return -1;
- }
+ return -1;
}
/**
@@ -884,13 +894,7 @@ public class AudioManager {
* @return true if any music tracks are active.
*/
public boolean isMusicActive() {
- IAudioService service = getService();
- try {
- return service.isMusicActive();
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in isMusicActive", e);
- return false;
- }
+ return AudioSystem.isMusicActive();
}
/*
@@ -906,14 +910,32 @@ public class AudioManager {
*/
/**
* @hide
+ * @deprecated Use {@link #setPrameters(String)} instead
*/
- public void setParameter(String key, String value) {
- IAudioService service = getService();
- try {
- service.setParameter(key, value);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in setParameter", e);
- }
+ @Deprecated public void setParameter(String key, String value) {
+ setParameters(key+"="+value);
+ }
+
+ /**
+ * Sets a variable number of parameter values to audio hardware.
+ *
+ * @param keyValuePairs list of parameters key value pairs in the form:
+ * key1=value1;key2=value2;...
+ *
+ */
+ public void setParameters(String keyValuePairs) {
+ AudioSystem.setParameters(keyValuePairs);
+ }
+
+ /**
+ * Sets a varaible number of parameter values to audio hardware.
+ *
+ * @param keys list of parameters
+ * @return list of parameters key value pairs in the form:
+ * key1=value1;key2=value2;...
+ */
+ public String getParameters(String keys) {
+ return AudioSystem.getParameters(keys);
}
/* Sound effect identifiers */
@@ -1082,31 +1104,4 @@ public class AudioManager {
* {@hide}
*/
private IBinder mICallBack = new Binder();
-
- /**
- * {@hide}
- */
- private void setRoutingP(int mode, int routes, int mask) {
- IAudioService service = getService();
- try {
- service.setRouting(mode, routes, mask);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in setRouting", e);
- }
- }
-
-
- /**
- * {@hide}
- */
- private int getRoutingP(int mode) {
- IAudioService service = getService();
- try {
- return service.getRouting(mode);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in getRouting", e);
- return -1;
- }
- }
-
}
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 4d1535f..d96331f 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -86,7 +86,7 @@ public class AudioRecord
public static final int ERROR_INVALID_OPERATION = -3;
private static final int AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT = -16;
- private static final int AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT = -17;
+ private static final int AUDIORECORD_ERROR_SETUP_INVALIDCHANNELMASK = -17;
private static final int AUDIORECORD_ERROR_SETUP_INVALIDFORMAT = -18;
private static final int AUDIORECORD_ERROR_SETUP_INVALIDSOURCE = -19;
private static final int AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED = -20;
@@ -135,7 +135,7 @@ public class AudioRecord
/**
* The current audio channel configuration
*/
- private int mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
+ private int mChannelConfiguration = AudioFormat.CHANNEL_IN_MONO;
/**
* The encoding of the audio samples.
* @see AudioFormat#ENCODING_PCM_8BIT
@@ -193,8 +193,8 @@ public class AudioRecord
* @param sampleRateInHz the sample rate expressed in Hertz. Examples of rates are (but
* not limited to) 44100, 22050 and 11025.
* @param channelConfig describes the configuration of the audio channels.
- * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO} and
- * {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}
+ * See {@link AudioFormat#CHANNEL_IN_MONO} and
+ * {@link AudioFormat#CHANNEL_IN_STEREO}
* @param audioFormat the format in which the audio data is represented.
* See {@link AudioFormat#ENCODING_PCM_16BIT} and
* {@link AudioFormat#ENCODING_PCM_8BIT}
@@ -265,18 +265,18 @@ public class AudioRecord
//--------------
// channel config
switch (channelConfig) {
- case AudioFormat.CHANNEL_CONFIGURATION_DEFAULT:
- case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+ case AudioFormat.CHANNEL_IN_DEFAULT:
+ case AudioFormat.CHANNEL_IN_MONO:
mChannelCount = 1;
- mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
+ mChannelConfiguration = AudioFormat.CHANNEL_IN_MONO;
break;
- case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+ case AudioFormat.CHANNEL_IN_STEREO:
mChannelCount = 2;
- mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
+ mChannelConfiguration = AudioFormat.CHANNEL_IN_STEREO;
break;
default:
mChannelCount = 0;
- mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_INVALID;
+ mChannelConfiguration = AudioFormat.CHANNEL_INVALID;
throw (new IllegalArgumentException("Unsupported channel configuration."));
}
@@ -368,8 +368,8 @@ public class AudioRecord
/**
* Returns the configured channel configuration.
- * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO}
- * and {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}.
+ * See {@link AudioFormat#CHANNEL_IN_MONO}
+ * and {@link AudioFormat#CHANNEL_IN_STEREO}.
*/
public int getChannelConfiguration() {
return mChannelConfiguration;
@@ -425,8 +425,8 @@ public class AudioRecord
* will be polled for new data.
* @param sampleRateInHz the sample rate expressed in Hertz.
* @param channelConfig describes the configuration of the audio channels.
- * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO} and
- * {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}
+ * See {@link AudioFormat#CHANNEL_IN_MONO} and
+ * {@link AudioFormat#CHANNEL_IN_STEREO}
* @param audioFormat the format in which the audio data is represented.
* See {@link AudioFormat#ENCODING_PCM_16BIT}.
* @return {@link #ERROR_BAD_VALUE} if the recording parameters are not supported by the
@@ -438,14 +438,14 @@ public class AudioRecord
static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
int channelCount = 0;
switch(channelConfig) {
- case AudioFormat.CHANNEL_CONFIGURATION_DEFAULT:
- case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+ case AudioFormat.CHANNEL_IN_DEFAULT:
+ case AudioFormat.CHANNEL_IN_MONO:
channelCount = 1;
break;
- case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+ case AudioFormat.CHANNEL_IN_STEREO:
channelCount = 2;
break;
- case AudioFormat.CHANNEL_CONFIGURATION_INVALID:
+ case AudioFormat.CHANNEL_INVALID:
default:
loge("getMinBufferSize(): Invalid channel configuration.");
return AudioRecord.ERROR_BAD_VALUE;
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 58c04f3..177a7cf 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -20,6 +20,12 @@ import android.app.ActivityManagerNative;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.bluetooth.BluetoothIntent;
+import android.content.BroadcastReceiver;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothA2dp;
+
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.media.MediaPlayer.OnCompletionListener;
@@ -94,16 +100,10 @@ public class AudioService extends IAudioService.Stub {
/** @see VolumeStreamState */
private VolumeStreamState[] mStreamStates;
private SettingsObserver mSettingsObserver;
-
- private boolean mMicMute;
+
private int mMode;
- private int[] mRoutes = new int[AudioSystem.NUM_MODES];
private Object mSettingsLock = new Object();
private boolean mMediaServerOk;
- private boolean mSpeakerIsOn;
- private boolean mBluetoothScoIsConnected;
- private boolean mHeadsetIsConnected;
- private boolean mBluetoothA2dpIsConnected;
private SoundPool mSoundPool;
private Object mSoundEffectsLock = new Object();
@@ -135,6 +135,23 @@ public class AudioService extends IAudioService.Stub {
{4, -1} // FX_FOCUS_RETURN
};
+ /* STREAM_VOLUME_ALIAS[] indicates for each stream if it uses the volume settings
+ * of another stream: This avoids multiplying the volume settings for hidden
+ * stream types that follow other stream behavior for volume settings
+ * NOTE: do not create loops in aliases! */
+ private int[] STREAM_VOLUME_ALIAS = new int[] {
+ AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
+ AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM
+ AudioSystem.STREAM_RING, // STREAM_RING
+ AudioSystem.STREAM_MUSIC, // STREAM_MUSIC
+ AudioSystem.STREAM_ALARM, // STREAM_ALARM
+ AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION
+ AudioSystem.STREAM_VOICE_CALL, // STREAM_BLUETOOTH_SCO
+ AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM_ENFORCED
+ AudioSystem.STREAM_VOICE_CALL, // STREAM_DTMF
+ AudioSystem.STREAM_MUSIC // STREAM_TTS
+ };
+
private AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
public void onError(int error) {
switch (error) {
@@ -178,6 +195,21 @@ public class AudioService extends IAudioService.Stub {
*/
private int mVibrateSetting;
+ /** @see System#NOTIFICATIONS_USE_RING_VOLUME */
+ private int mNotificationsUseRingVolume;
+
+ // Broadcast receiver for device connections intent broadcasts
+ private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
+
+ //TODO: use common definitions with HeadsetObserver
+ private static final int BIT_HEADSET = (1 << 0);
+ private static final int BIT_HEADSET_NO_MIC = (1 << 1);
+ private static final int BIT_TTY = (1 << 2);
+ private static final int BIT_FM_HEADSET = (1 << 3);
+ private static final int BIT_FM_SPEAKER = (1 << 4);
+
+ private int mHeadsetState;
+
///////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////
@@ -188,18 +220,20 @@ public class AudioService extends IAudioService.Stub {
mContentResolver = context.getContentResolver();
mVolumePanel = new VolumePanel(context, this);
mSettingsObserver = new SettingsObserver();
-
+
createAudioSystemThread();
- createStreamStates();
readPersistedSettings();
- readAudioSettings();
+ createStreamStates();
mMediaServerOk = true;
AudioSystem.setErrorCallback(mAudioSystemCallback);
loadSoundEffects();
- mSpeakerIsOn = false;
- mBluetoothScoIsConnected = false;
- mHeadsetIsConnected = false;
- mBluetoothA2dpIsConnected = false;
+
+ // Register for device connection intent broadcasts.
+ IntentFilter intentFilter =
+ new IntentFilter(Intent.ACTION_HEADSET_PLUG);
+ intentFilter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
+ intentFilter.addAction(BluetoothIntent.HEADSET_AUDIO_STATE_CHANGED_ACTION);
+ context.registerReceiver(mReceiver, intentFilter);
}
private void createAudioSystemThread() {
@@ -223,63 +257,23 @@ public class AudioService extends IAudioService.Stub {
}
private void createStreamStates() {
- final int[] volumeLevelsPhone =
- createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]);
- final int[] volumeLevelsCoarse =
- createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]);
- final int[] volumeLevelsFine =
- createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
- final int[] volumeLevelsBtPhone =
- createVolumeLevels(0,
- AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
-
int numStreamTypes = AudioSystem.getNumStreamTypes();
VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
for (int i = 0; i < numStreamTypes; i++) {
- final int[] levels;
-
- switch (i) {
-
- case AudioSystem.STREAM_MUSIC:
- levels = volumeLevelsFine;
- break;
-
- case AudioSystem.STREAM_VOICE_CALL:
- levels = volumeLevelsPhone;
- break;
-
- case AudioSystem.STREAM_BLUETOOTH_SCO:
- levels = volumeLevelsBtPhone;
- break;
-
- default:
- levels = volumeLevelsCoarse;
- break;
- }
-
- if (i == AudioSystem.STREAM_BLUETOOTH_SCO) {
- streams[i] = new VolumeStreamState(AudioManager.DEFAULT_STREAM_VOLUME[i], i,levels);
- } else {
- streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[i], i, levels);
- }
+ streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[STREAM_VOLUME_ALIAS[i]], i);
}
- }
- private static int[] createVolumeLevels(int offset, int numlevels) {
- double curve = 1.0f; // 1.4f
- int [] volumes = new int[numlevels + offset];
- for (int i = 0; i < offset; i++) {
- volumes[i] = 0;
- }
-
- double val = 0;
- double max = Math.pow(numlevels - 1, curve);
- for (int i = 0; i < numlevels; i++) {
- val = Math.pow(i, curve) / max;
- volumes[offset + i] = (int) (val * 100.0f);
+ // Correct stream index values for streams with aliases
+ for (int i = 0; i < numStreamTypes; i++) {
+ if (STREAM_VOLUME_ALIAS[i] != i) {
+ int index = rescaleIndex(streams[i].mIndex, STREAM_VOLUME_ALIAS[i], i);
+ streams[i].mIndex = streams[i].getValidIndex(index);
+ setStreamVolumeIndex(i, index);
+ index = rescaleIndex(streams[i].mLastAudibleIndex, STREAM_VOLUME_ALIAS[i], i);
+ streams[i].mLastAudibleIndex = streams[i].getValidIndex(index);
+ }
}
- return volumes;
}
private void readPersistedSettings() {
@@ -291,12 +285,19 @@ public class AudioService extends IAudioService.Stub {
mRingerModeAffectedStreams = Settings.System.getInt(cr,
Settings.System.MODE_RINGER_STREAMS_AFFECTED,
- ((1 << AudioManager.STREAM_RING)|(1 << AudioManager.STREAM_NOTIFICATION)|(1 << AudioManager.STREAM_SYSTEM)));
+ ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
+ (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)));
mMuteAffectedStreams = System.getInt(cr,
System.MUTE_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
+ mNotificationsUseRingVolume = System.getInt(cr,
+ Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1);
+
+ if (mNotificationsUseRingVolume == 1) {
+ STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
+ }
// Each stream will read its own persisted settings
// Broadcast the sticky intent
@@ -307,25 +308,13 @@ public class AudioService extends IAudioService.Stub {
broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
}
- private void readAudioSettings() {
- synchronized (mSettingsLock) {
- mMicMute = AudioSystem.isMicrophoneMuted();
- mMode = AudioSystem.getMode();
- for (int mode = 0; mode < AudioSystem.NUM_MODES; mode++) {
- mRoutes[mode] = AudioSystem.getRouting(mode);
- }
- }
+ private void setStreamVolumeIndex(int stream, int index) {
+ AudioSystem.setStreamVolumeIndex(stream, (index + 5)/10);
}
- private void applyAudioSettings() {
- synchronized (mSettingsLock) {
- AudioSystem.muteMicrophone(mMicMute);
- AudioSystem.setMode(mMode);
- for (int mode = 0; mode < AudioSystem.NUM_MODES; mode++) {
- AudioSystem.setRouting(mode, mRoutes[mode], AudioSystem.ROUTE_ALL);
- }
- }
- }
+ private int rescaleIndex(int index, int srcStream, int dstStream) {
+ return (index * mStreamStates[dstStream].getMaxIndex() + mStreamStates[srcStream].getMaxIndex() / 2) / mStreamStates[srcStream].getMaxIndex();
+ }
///////////////////////////////////////////////////////////////////////////
// IPC methods
@@ -354,44 +343,26 @@ public class AudioService extends IAudioService.Stub {
ensureValidDirection(direction);
ensureValidStreamType(streamType);
- boolean notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
- Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1) == 1;
- if (notificationsUseRingVolume && streamType == AudioManager.STREAM_NOTIFICATION) {
- // Redirect the volume change to the ring stream
- streamType = AudioManager.STREAM_RING;
- }
- VolumeStreamState streamState = mStreamStates[streamType];
+ VolumeStreamState streamState = mStreamStates[STREAM_VOLUME_ALIAS[streamType]];
final int oldIndex = streamState.mIndex;
boolean adjustVolume = true;
// If either the client forces allowing ringer modes for this adjustment,
// or the stream type is one that is affected by ringer modes
if ((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0
- || streamType == AudioManager.STREAM_RING) {
+ || streamType == AudioSystem.STREAM_RING) {
// Check if the ringer mode changes with this volume adjustment. If
// it does, it will handle adjusting the volume, so we won't below
adjustVolume = checkForRingerModeChange(oldIndex, direction);
}
if (adjustVolume && streamState.adjustIndex(direction)) {
-
- boolean alsoUpdateNotificationVolume = notificationsUseRingVolume &&
- streamType == AudioManager.STREAM_RING;
- if (alsoUpdateNotificationVolume) {
- mStreamStates[AudioManager.STREAM_NOTIFICATION].adjustIndex(direction);
- }
-
// Post message to set system volume (it in turn will post a message
// to persist). Do not change volume if stream is muted.
if (streamState.muteCount() == 0) {
- sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, streamType, SENDMSG_NOOP, 0, 0,
+ sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, STREAM_VOLUME_ALIAS[streamType], SENDMSG_NOOP, 0, 0,
streamState, 0);
-
- if (alsoUpdateNotificationVolume) {
- sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, AudioManager.STREAM_NOTIFICATION,
- SENDMSG_NOOP, 0, 0, mStreamStates[AudioManager.STREAM_NOTIFICATION], 0);
- }
}
}
@@ -404,9 +375,8 @@ public class AudioService extends IAudioService.Stub {
/** @see AudioManager#setStreamVolume(int, int, int) */
public void setStreamVolume(int streamType, int index, int flags) {
ensureValidStreamType(streamType);
- syncRingerAndNotificationStreamVolume(streamType, index, false);
-
- setStreamVolumeInt(streamType, index, false, true);
+ index = rescaleIndex(index * 10, streamType, STREAM_VOLUME_ALIAS[streamType]);
+ setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, false, true);
// UI, etc.
mVolumePanel.postVolumeChanged(streamType, flags);
@@ -420,37 +390,12 @@ public class AudioService extends IAudioService.Stub {
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, getStreamVolume(streamType));
// Currently, sending the intent only when the stream is BLUETOOTH_SCO
- if (streamType == AudioManager.STREAM_BLUETOOTH_SCO) {
+ if (streamType == AudioSystem.STREAM_BLUETOOTH_SCO) {
mContext.sendBroadcast(intent);
}
}
/**
- * Sync the STREAM_RING and STREAM_NOTIFICATION volumes if mandated by the
- * value in Settings.
- *
- * @param streamType Type of the stream
- * @param index Volume index for the stream
- * @param force If true, set the volume even if the current and desired
- * volume as same
- */
- private void syncRingerAndNotificationStreamVolume(int streamType, int index, boolean force) {
- boolean notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
- Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1) == 1;
- if (notificationsUseRingVolume) {
- if (streamType == AudioManager.STREAM_NOTIFICATION) {
- // Redirect the volume change to the ring stream
- streamType = AudioManager.STREAM_RING;
- }
- if (streamType == AudioManager.STREAM_RING) {
- // One-off to sync notification volume to ringer volume
- setStreamVolumeInt(AudioManager.STREAM_NOTIFICATION, index, force, true);
- }
- }
- }
-
-
- /**
* Sets the stream state's index, and posts a message to set system volume.
* This will not call out to the UI. Assumes a valid stream type.
*
@@ -491,13 +436,13 @@ public class AudioService extends IAudioService.Stub {
/** @see AudioManager#getStreamVolume(int) */
public int getStreamVolume(int streamType) {
ensureValidStreamType(streamType);
- return mStreamStates[streamType].mIndex;
+ return (mStreamStates[streamType].mIndex + 5) / 10;
}
/** @see AudioManager#getStreamMaxVolume(int) */
public int getStreamMaxVolume(int streamType) {
ensureValidStreamType(streamType);
- return mStreamStates[streamType].getMaxIndex();
+ return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
}
/** @see AudioManager#getRingerMode() */
@@ -507,11 +452,12 @@ public class AudioService extends IAudioService.Stub {
/** @see AudioManager#setRingerMode(int) */
public void setRingerMode(int ringerMode) {
- if (ringerMode != mRingerMode) {
- setRingerModeInt(ringerMode, true);
-
- // Send sticky broadcast
- broadcastRingerMode();
+ synchronized (mSettingsLock) {
+ if (ringerMode != mRingerMode) {
+ setRingerModeInt(ringerMode, true);
+ // Send sticky broadcast
+ broadcastRingerMode();
+ }
}
}
@@ -541,7 +487,7 @@ public class AudioService extends IAudioService.Stub {
}
}
}
-
+
// Post a persist ringer mode msg
if (persist) {
sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, SHARED_MSG,
@@ -606,39 +552,28 @@ public class AudioService extends IAudioService.Stub {
return existingValue;
}
- /** @see AudioManager#setMicrophoneMute(boolean) */
- public void setMicrophoneMute(boolean on) {
- if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
- return;
- }
- synchronized (mSettingsLock) {
- if (on != mMicMute) {
- AudioSystem.muteMicrophone(on);
- mMicMute = on;
- }
- }
- }
-
- /** @see AudioManager#isMicrophoneMute() */
- public boolean isMicrophoneMute() {
- return mMicMute;
- }
-
/** @see AudioManager#setMode(int) */
public void setMode(int mode) {
if (!checkAudioSettingsPermission("setMode()")) {
return;
}
+
+ if (mode < AudioSystem.MODE_CURRENT || mode > AudioSystem.MODE_IN_CALL) {
+ return;
+ }
+
synchronized (mSettingsLock) {
+ if (mode == AudioSystem.MODE_CURRENT) {
+ mode = mMode;
+ }
if (mode != mMode) {
- if (AudioSystem.setMode(mode) == AudioSystem.AUDIO_STATUS_OK) {
+ if (AudioSystem.setPhoneState(mode) == AudioSystem.AUDIO_STATUS_OK) {
mMode = mode;
}
}
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
- int index = mStreamStates[streamType].mIndex;
- syncRingerAndNotificationStreamVolume(streamType, index, true);
- setStreamVolumeInt(streamType, index, true, true);
+ int index = mStreamStates[STREAM_VOLUME_ALIAS[streamType]].mIndex;
+ setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, true, true);
}
}
@@ -647,187 +582,6 @@ public class AudioService extends IAudioService.Stub {
return mMode;
}
- /** @see AudioManager#setRouting(int, int, int) */
- public void setRouting(int mode, int routes, int mask) {
- int incallMask = 0;
- int ringtoneMask = 0;
- int normalMask = 0;
-
- if (!checkAudioSettingsPermission("setRouting()")) {
- return;
- }
- synchronized (mSettingsLock) {
- // Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
- // mode AudioSystem.MODE_INVALID is used only by the following AudioManager methods:
- // setWiredHeadsetOn(), setBluetoothA2dpOn(), setBluetoothScoOn() and setSpeakerphoneOn().
- // If applications are using AudioManager.setRouting() that is now deprecated, the routing
- // command will be ignored.
- if (mode == AudioSystem.MODE_INVALID) {
- switch (mask) {
- case AudioSystem.ROUTE_SPEAKER:
- // handle setSpeakerphoneOn()
- if (routes != 0 && !mSpeakerIsOn) {
- mSpeakerIsOn = true;
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
- incallMask = AudioSystem.ROUTE_ALL;
- } else if (routes == 0 && mSpeakerIsOn) {
- mSpeakerIsOn = false;
- if (mBluetoothScoIsConnected) {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_BLUETOOTH_SCO;
- } else if (mHeadsetIsConnected) {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
- } else {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
- }
- incallMask = AudioSystem.ROUTE_ALL;
- }
- break;
-
- case AudioSystem.ROUTE_BLUETOOTH_SCO:
- // handle setBluetoothScoOn()
- if (routes != 0 && !mBluetoothScoIsConnected) {
- mBluetoothScoIsConnected = true;
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_BLUETOOTH_SCO;
- mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- AudioSystem.ROUTE_BLUETOOTH_SCO;
- mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- AudioSystem.ROUTE_BLUETOOTH_SCO;
- incallMask = AudioSystem.ROUTE_ALL;
- // A2DP has higher priority than SCO headset, so headset connect/disconnect events
- // should not affect A2DP routing
- ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- } else if (routes == 0 && mBluetoothScoIsConnected) {
- mBluetoothScoIsConnected = false;
- if (mHeadsetIsConnected) {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
- mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- (AudioSystem.ROUTE_HEADSET|AudioSystem.ROUTE_SPEAKER);
- mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- AudioSystem.ROUTE_HEADSET;
- } else {
- if (mSpeakerIsOn) {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
- } else {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
- }
- mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- AudioSystem.ROUTE_SPEAKER;
- mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- AudioSystem.ROUTE_SPEAKER;
- }
- incallMask = AudioSystem.ROUTE_ALL;
- // A2DP has higher priority than SCO headset, so headset connect/disconnect events
- // should not affect A2DP routing
- ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- }
- break;
-
- case AudioSystem.ROUTE_HEADSET:
- // handle setWiredHeadsetOn()
- if (routes != 0 && !mHeadsetIsConnected) {
- mHeadsetIsConnected = true;
- // do not act upon headset connection if bluetooth SCO is connected to match phone app behavior
- if (!mBluetoothScoIsConnected) {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
- mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- (AudioSystem.ROUTE_HEADSET|AudioSystem.ROUTE_SPEAKER);
- mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- AudioSystem.ROUTE_HEADSET;
- incallMask = AudioSystem.ROUTE_ALL;
- // A2DP has higher priority than wired headset, so headset connect/disconnect events
- // should not affect A2DP routing
- ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- }
- } else if (routes == 0 && mHeadsetIsConnected) {
- mHeadsetIsConnected = false;
- // do not act upon headset disconnection if bluetooth SCO is connected to match phone app behavior
- if (!mBluetoothScoIsConnected) {
- if (mSpeakerIsOn) {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
- } else {
- mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
- }
- mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- AudioSystem.ROUTE_SPEAKER;
- mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
- AudioSystem.ROUTE_SPEAKER;
-
- incallMask = AudioSystem.ROUTE_ALL;
- // A2DP has higher priority than wired headset, so headset connect/disconnect events
- // should not affect A2DP routing
- ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- }
- }
- break;
-
- case AudioSystem.ROUTE_BLUETOOTH_A2DP:
- // handle setBluetoothA2dpOn()
- if (routes != 0 && !mBluetoothA2dpIsConnected) {
- mBluetoothA2dpIsConnected = true;
- mRoutes[AudioSystem.MODE_RINGTONE] |= AudioSystem.ROUTE_BLUETOOTH_A2DP;
- mRoutes[AudioSystem.MODE_NORMAL] |= AudioSystem.ROUTE_BLUETOOTH_A2DP;
- // the audio flinger chooses A2DP as a higher priority,
- // so there is no need to disable other routes.
- ringtoneMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
- normalMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
- } else if (routes == 0 && mBluetoothA2dpIsConnected) {
- mBluetoothA2dpIsConnected = false;
- mRoutes[AudioSystem.MODE_RINGTONE] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- mRoutes[AudioSystem.MODE_NORMAL] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- // the audio flinger chooses A2DP as a higher priority,
- // so there is no need to disable other routes.
- ringtoneMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
- normalMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
- }
- break;
- }
-
- // incallMask is != 0 means we must apply ne routing to MODE_IN_CALL mode
- if (incallMask != 0) {
- AudioSystem.setRouting(AudioSystem.MODE_IN_CALL,
- mRoutes[AudioSystem.MODE_IN_CALL],
- incallMask);
- }
- // ringtoneMask is != 0 means we must apply ne routing to MODE_RINGTONE mode
- if (ringtoneMask != 0) {
- AudioSystem.setRouting(AudioSystem.MODE_RINGTONE,
- mRoutes[AudioSystem.MODE_RINGTONE],
- ringtoneMask);
- }
- // normalMask is != 0 means we must apply ne routing to MODE_NORMAL mode
- if (normalMask != 0) {
- AudioSystem.setRouting(AudioSystem.MODE_NORMAL,
- mRoutes[AudioSystem.MODE_NORMAL],
- normalMask);
- }
-
- int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
- int index = mStreamStates[streamType].mIndex;
- syncRingerAndNotificationStreamVolume(streamType, index, true);
- setStreamVolumeInt(streamType, index, true, true);
- }
- }
- }
-
- /** @see AudioManager#getRouting(int) */
- public int getRouting(int mode) {
- return mRoutes[mode];
- }
-
- /** @see AudioManager#isMusicActive() */
- public boolean isMusicActive() {
- return AudioSystem.isMusicActive();
- }
-
- /** @see AudioManager#setParameter(String, String) */
- public void setParameter(String key, String value) {
- AudioSystem.setParameter(key, value);
- }
-
/** @see AudioManager#playSoundEffect(int) */
public void playSoundEffect(int effectType) {
sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SHARED_MSG, SENDMSG_NOOP,
@@ -930,14 +684,28 @@ public class AudioService extends IAudioService.Stub {
if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) {
String settingName = System.VOLUME_SETTINGS[streamType];
String lastAudibleSettingName = settingName + System.APPEND_FOR_LAST_AUDIBLE;
-
- streamState.mIndex = streamState.getValidIndex(Settings.System.getInt(mContentResolver,
- settingName,
- AudioManager.DEFAULT_STREAM_VOLUME[streamType]));
- streamState.mLastAudibleIndex = streamState.getValidIndex(Settings.System.getInt(mContentResolver,
- lastAudibleSettingName,
- streamState.mIndex > 0 ? streamState.mIndex : AudioManager.DEFAULT_STREAM_VOLUME[streamType]));
+ int index = Settings.System.getInt(mContentResolver,
+ settingName,
+ AudioManager.DEFAULT_STREAM_VOLUME[streamType]);
+ if (STREAM_VOLUME_ALIAS[streamType] != streamType) {
+ index = rescaleIndex(index * 10, STREAM_VOLUME_ALIAS[streamType], streamType);
+ } else {
+ index *= 10;
+ }
+ streamState.mIndex = streamState.getValidIndex(index);
+
+ index = (index + 5) / 10;
+ index = Settings.System.getInt(mContentResolver,
+ lastAudibleSettingName,
+ (index > 0) ? index : AudioManager.DEFAULT_STREAM_VOLUME[streamType]);
+ if (STREAM_VOLUME_ALIAS[streamType] != streamType) {
+ index = rescaleIndex(index * 10, STREAM_VOLUME_ALIAS[streamType], streamType);
+ } else {
+ index *= 10;
+ }
+ streamState.mLastAudibleIndex = streamState.getValidIndex(index);
}
+
// unmute stream that whas muted but is not affect by mute anymore
if (streamState.muteCount() != 0 && !isStreamAffectedByMute(streamType)) {
int size = streamState.mDeathHandlers.size();
@@ -948,7 +716,7 @@ public class AudioService extends IAudioService.Stub {
}
// apply stream volume
if (streamState.muteCount() == 0) {
- AudioSystem.setVolume(streamType, streamState.mVolumes[streamState.mIndex]);
+ setStreamVolumeIndex(streamType, streamState.mIndex);
}
}
@@ -969,7 +737,7 @@ public class AudioService extends IAudioService.Stub {
boolean adjustVolumeIndex = true;
int newRingerMode = mRingerMode;
- if (mRingerMode == AudioManager.RINGER_MODE_NORMAL && oldIndex == 1
+ if (mRingerMode == AudioManager.RINGER_MODE_NORMAL && (oldIndex + 5) / 10 == 1
&& direction == AudioManager.ADJUST_LOWER) {
newRingerMode = AudioManager.RINGER_MODE_VIBRATE;
} else if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
@@ -1026,7 +794,7 @@ public class AudioService extends IAudioService.Stub {
Log.w(TAG, "Couldn't connect to phone service", e);
}
- if ((getRouting(AudioSystem.MODE_IN_CALL) & AudioSystem.ROUTE_BLUETOOTH_SCO) != 0) {
+ if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION) == AudioSystem.FORCE_BT_SCO) {
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
return AudioSystem.STREAM_BLUETOOTH_SCO;
} else if (isOffhook) {
@@ -1110,47 +878,36 @@ public class AudioService extends IAudioService.Stub {
private final String mLastAudibleVolumeIndexSettingName;
private final int mStreamType;
- private final int[] mVolumes;
+ private int mIndexMax;
private int mIndex;
private int mLastAudibleIndex;
private ArrayList<VolumeDeathHandler> mDeathHandlers; //handles mute/solo requests client death
- private VolumeStreamState(String settingName, int streamType, int[] volumes) {
+ private VolumeStreamState(String settingName, int streamType) {
mVolumeIndexSettingName = settingName;
mLastAudibleVolumeIndexSettingName = settingName + System.APPEND_FOR_LAST_AUDIBLE;
mStreamType = streamType;
- mVolumes = volumes;
final ContentResolver cr = mContentResolver;
- mIndex = getValidIndex(Settings.System.getInt(cr, mVolumeIndexSettingName, AudioManager.DEFAULT_STREAM_VOLUME[streamType]));
- mLastAudibleIndex = getValidIndex(Settings.System.getInt(cr,
- mLastAudibleVolumeIndexSettingName, mIndex > 0 ? mIndex : AudioManager.DEFAULT_STREAM_VOLUME[streamType]));
-
- AudioSystem.setVolume(streamType, volumes[mIndex]);
- mDeathHandlers = new ArrayList<VolumeDeathHandler>();
- }
-
- /**
- * Constructor to be used when there is no setting associated with the VolumeStreamState.
- *
- * @param defaultVolume Default volume of the stream to use.
- * @param streamType Type of the stream.
- * @param volumes Volumes levels associated with this stream.
- */
- private VolumeStreamState(int defaultVolume, int streamType, int[] volumes) {
- mVolumeIndexSettingName = null;
- mLastAudibleVolumeIndexSettingName = null;
- mIndex = mLastAudibleIndex = defaultVolume;
- mStreamType = streamType;
- mVolumes = volumes;
- AudioSystem.setVolume(mStreamType, defaultVolume);
+ mIndexMax = AudioManager.MAX_STREAM_VOLUME[streamType];
+ mIndex = Settings.System.getInt(cr,
+ mVolumeIndexSettingName,
+ AudioManager.DEFAULT_STREAM_VOLUME[streamType]);
+ mLastAudibleIndex = Settings.System.getInt(cr,
+ mLastAudibleVolumeIndexSettingName,
+ (mIndex > 0) ? mIndex : AudioManager.DEFAULT_STREAM_VOLUME[streamType]);
+ AudioSystem.initStreamVolume(streamType, 0, mIndexMax);
+ mIndexMax *= 10;
+ mIndex = getValidIndex(10 * mIndex);
+ mLastAudibleIndex = getValidIndex(10 * mLastAudibleIndex);
+ setStreamVolumeIndex(streamType, mIndex);
mDeathHandlers = new ArrayList<VolumeDeathHandler>();
}
public boolean adjustIndex(int deltaIndex) {
- return setIndex(mIndex + deltaIndex, true);
+ return setIndex(mIndex + deltaIndex * 10, true);
}
public boolean setIndex(int index, boolean lastAudible) {
@@ -1161,6 +918,13 @@ public class AudioService extends IAudioService.Stub {
if (lastAudible) {
mLastAudibleIndex = mIndex;
}
+ // Apply change to all streams using this one as alias
+ int numStreamTypes = AudioSystem.getNumStreamTypes();
+ for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
+ if (streamType != mStreamType && STREAM_VOLUME_ALIAS[streamType] == mStreamType) {
+ mStreamStates[streamType].setIndex(rescaleIndex(mIndex, mStreamType, streamType), lastAudible);
+ }
+ }
return true;
} else {
return false;
@@ -1168,7 +932,7 @@ public class AudioService extends IAudioService.Stub {
}
public int getMaxIndex() {
- return mVolumes.length - 1;
+ return mIndexMax;
}
public void mute(IBinder cb, boolean state) {
@@ -1183,8 +947,8 @@ public class AudioService extends IAudioService.Stub {
private int getValidIndex(int index) {
if (index < 0) {
return 0;
- } else if (index >= mVolumes.length) {
- return mVolumes.length - 1;
+ } else if (index > mIndexMax) {
+ return mIndexMax;
}
return index;
@@ -1318,8 +1082,16 @@ public class AudioService extends IAudioService.Stub {
private void setSystemVolume(VolumeStreamState streamState) {
// Adjust volume
- AudioSystem
- .setVolume(streamState.mStreamType, streamState.mVolumes[streamState.mIndex]);
+ setStreamVolumeIndex(streamState.mStreamType, streamState.mIndex);
+
+ // Apply change to all streams using this one as alias
+ int numStreamTypes = AudioSystem.getNumStreamTypes();
+ for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
+ if (streamType != streamState.mStreamType &&
+ STREAM_VOLUME_ALIAS[streamType] == streamState.mStreamType) {
+ setStreamVolumeIndex(streamType, mStreamStates[streamType].mIndex);
+ }
+ }
// Post a persist volume msg
sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, streamState.mStreamType,
@@ -1327,12 +1099,10 @@ public class AudioService extends IAudioService.Stub {
}
private void persistVolume(VolumeStreamState streamState) {
- if (streamState.mStreamType != AudioManager.STREAM_BLUETOOTH_SCO) {
- System.putInt(mContentResolver, streamState.mVolumeIndexSettingName,
- streamState.mIndex);
- System.putInt(mContentResolver, streamState.mLastAudibleVolumeIndexSettingName,
- streamState.mLastAudibleIndex);
- }
+ System.putInt(mContentResolver, streamState.mVolumeIndexSettingName,
+ (streamState.mIndex + 5)/ 10);
+ System.putInt(mContentResolver, streamState.mLastAudibleVolumeIndexSettingName,
+ (streamState.mLastAudibleIndex + 5) / 10);
}
private void persistRingerMode() {
@@ -1426,18 +1196,17 @@ public class AudioService extends IAudioService.Stub {
case MSG_MEDIA_SERVER_STARTED:
Log.e(TAG, "Media server started.");
- // Restore audio routing and stream volumes
- applyAudioSettings();
+ // Restore stream volumes
int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
- int volume;
+ int index;
VolumeStreamState streamState = mStreamStates[streamType];
if (streamState.muteCount() == 0) {
- volume = streamState.mVolumes[streamState.mIndex];
+ index = streamState.mIndex;
} else {
- volume = streamState.mVolumes[0];
+ index = 0;
}
- AudioSystem.setVolume(streamType, volume);
+ setStreamVolumeIndex(streamType, index);
}
setRingerMode(mRingerMode);
mMediaServerOk = true;
@@ -1451,28 +1220,144 @@ public class AudioService extends IAudioService.Stub {
}
private class SettingsObserver extends ContentObserver {
-
+
SettingsObserver() {
super(new Handler());
mContentResolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.NOTIFICATIONS_USE_RING_VOLUME), false, this);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
-
- mRingerModeAffectedStreams = Settings.System.getInt(mContentResolver,
- Settings.System.MODE_RINGER_STREAMS_AFFECTED,
- 0);
+ synchronized (mSettingsLock) {
+ int ringerModeAffectedStreams = Settings.System.getInt(mContentResolver,
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ 0);
+ if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
+ /*
+ * Ensure all stream types that should be affected by ringer mode
+ * are in the proper state.
+ */
+ mRingerModeAffectedStreams = ringerModeAffectedStreams;
+ setRingerModeInt(getRingerMode(), false);
+ }
- /*
- * Ensure all stream types that should be affected by ringer mode
- * are in the proper state.
- */
- setRingerModeInt(getRingerMode(), false);
+ int notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
+ Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
+ 1);
+ if (notificationsUseRingVolume != mNotificationsUseRingVolume) {
+ mNotificationsUseRingVolume = notificationsUseRingVolume;
+ if (mNotificationsUseRingVolume == 1) {
+ STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
+ } else {
+ STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
+ // Persist notification volume volume as it was not persisted while aliased to ring volume
+ sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, AudioSystem.STREAM_NOTIFICATION,
+ SENDMSG_REPLACE, 0, 0, mStreamStates[AudioSystem.STREAM_NOTIFICATION], PERSIST_DELAY);
+ }
+ }
+ }
}
-
}
-
+
+ /**
+ * Receiver for misc intent broadcasts the Phone app cares about.
+ */
+ private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
+ int state = intent.getIntExtra(BluetoothA2dp.SINK_STATE,
+ BluetoothA2dp.STATE_DISCONNECTED);
+ String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
+ if (state == BluetoothA2dp.STATE_DISCONNECTED) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ address);
+ } else if (state == BluetoothA2dp.STATE_CONNECTED){
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ address);
+ }
+ } else if (action.equals(BluetoothIntent.HEADSET_AUDIO_STATE_CHANGED_ACTION)) {
+ int state = intent.getIntExtra(BluetoothIntent.HEADSET_AUDIO_STATE,
+ BluetoothHeadset.STATE_ERROR);
+ String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
+ if (state == BluetoothHeadset.AUDIO_STATE_DISCONNECTED) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ address);
+ } else if (state == BluetoothHeadset.AUDIO_STATE_CONNECTED) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ address);
+ }
+ } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
+ int state = intent.getIntExtra("state", 0);
+ if ((state & BIT_HEADSET) == 0 &&
+ (mHeadsetState & BIT_HEADSET) != 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ "");
+ } else if ((state & BIT_HEADSET) != 0 &&
+ (mHeadsetState & BIT_HEADSET) == 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ "");
+ }
+ if ((state & BIT_HEADSET_NO_MIC) == 0 &&
+ (mHeadsetState & BIT_HEADSET_NO_MIC) != 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ "");
+ } else if ((state & BIT_HEADSET_NO_MIC) != 0 &&
+ (mHeadsetState & BIT_HEADSET_NO_MIC) == 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ "");
+ }
+ if ((state & BIT_TTY) == 0 &&
+ (mHeadsetState & BIT_TTY) != 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_TTY,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ "");
+ } else if ((state & BIT_TTY) != 0 &&
+ (mHeadsetState & BIT_TTY) == 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_TTY,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ "");
+ }
+ if ((state & BIT_FM_HEADSET) == 0 &&
+ (mHeadsetState & BIT_FM_HEADSET) != 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_HEADPHONE,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ "");
+ } else if ((state & BIT_FM_HEADSET) != 0 &&
+ (mHeadsetState & BIT_FM_HEADSET) == 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_HEADPHONE,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ "");
+ }
+ if ((state & BIT_FM_SPEAKER) == 0 &&
+ (mHeadsetState & BIT_FM_SPEAKER) != 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_SPEAKER,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE,
+ "");
+ } else if ((state & BIT_FM_SPEAKER) != 0 &&
+ (mHeadsetState & BIT_FM_SPEAKER) == 0) {
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_SPEAKER,
+ AudioSystem.DEVICE_STATE_AVAILABLE,
+ "");
+ }
+ mHeadsetState = state;
+ }
+ }
+ }
+
+
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 5917ab9..d587f65 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -45,38 +45,21 @@ public class AudioSystem
public static final int STREAM_NOTIFICATION = 5;
/* @hide The audio stream for phone calls when connected on bluetooth */
public static final int STREAM_BLUETOOTH_SCO = 6;
+ /* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */
+ public static final int STREAM_SYSTEM_ENFORCED = 7;
+ /* @hide The audio stream for DTMF tones */
+ public static final int STREAM_DTMF = 8;
+ /* @hide The audio stream for text to speech (TTS) */
+ public static final int STREAM_TTS = 9;
/**
* @deprecated Use {@link #numStreamTypes() instead}
*/
public static final int NUM_STREAMS = 5;
// Expose only the getter method publicly so we can change it in the future
- private static final int NUM_STREAM_TYPES = 7;
+ private static final int NUM_STREAM_TYPES = 10;
public static final int getNumStreamTypes() { return NUM_STREAM_TYPES; }
- /* max and min volume levels */
- /* Maximum volume setting, for use with setVolume(int,int) */
- public static final int MAX_VOLUME = 100;
- /* Minimum volume setting, for use with setVolume(int,int) */
- public static final int MIN_VOLUME = 0;
-
- /*
- * Sets the volume of a specified audio stream.
- *
- * param type the stream type to set the volume of (e.g. STREAM_MUSIC)
- * param volume the volume level to set (0-100)
- * return command completion status see AUDIO_STATUS_OK, see AUDIO_STATUS_ERROR
- */
- public static native int setVolume(int type, int volume);
-
- /*
- * Returns the volume of a specified audio stream.
- *
- * param type the stream type to get the volume of (e.g. STREAM_MUSIC)
- * return the current volume (0-100)
- */
- public static native int getVolume(int type);
-
/*
* Sets the microphone mute on or off.
*
@@ -101,17 +84,22 @@ public class AudioSystem
* it can route the audio appropriately.
* return command completion status see AUDIO_STATUS_OK, see AUDIO_STATUS_ERROR
*/
- public static native int setMode(int mode);
-
+ /** @deprecated use {@link #setPhoneState(int)} */
+ public static int setMode(int mode) {
+ return AUDIO_STATUS_ERROR;
+ }
/*
* Returns the current audio mode.
*
* return the current audio mode (NORMAL, RINGTONE, or IN_CALL).
* Returns the current current audio state from the HAL.
*/
- public static native int getMode();
+ /** @deprecated */
+ public static int getMode() {
+ return MODE_INVALID;
+ }
- /* modes for setMode/getMode/setRoute/getRoute */
+ /* modes for setPhoneState */
public static final int MODE_INVALID = -2;
public static final int MODE_CURRENT = -1;
public static final int MODE_NORMAL = 0;
@@ -121,15 +109,20 @@ public class AudioSystem
/* Routing bits for setRouting/getRouting API */
- public static final int ROUTE_EARPIECE = (1 << 0);
- public static final int ROUTE_SPEAKER = (1 << 1);
-
+ /** @deprecated */
+ @Deprecated public static final int ROUTE_EARPIECE = (1 << 0);
+ /** @deprecated */
+ @Deprecated public static final int ROUTE_SPEAKER = (1 << 1);
/** @deprecated use {@link #ROUTE_BLUETOOTH_SCO} */
@Deprecated public static final int ROUTE_BLUETOOTH = (1 << 2);
- public static final int ROUTE_BLUETOOTH_SCO = (1 << 2);
- public static final int ROUTE_HEADSET = (1 << 3);
- public static final int ROUTE_BLUETOOTH_A2DP = (1 << 4);
- public static final int ROUTE_ALL = 0xFFFFFFFF;
+ /** @deprecated */
+ @Deprecated public static final int ROUTE_BLUETOOTH_SCO = (1 << 2);
+ /** @deprecated */
+ @Deprecated public static final int ROUTE_HEADSET = (1 << 3);
+ /** @deprecated */
+ @Deprecated public static final int ROUTE_BLUETOOTH_A2DP = (1 << 4);
+ /** @deprecated */
+ @Deprecated public static final int ROUTE_ALL = 0xFFFFFFFF;
/*
* Sets the audio routing for a specified mode
@@ -141,7 +134,10 @@ public class AudioSystem
* ROUTE_xxx types. Unset bits indicate the route should be left unchanged
* return command completion status see AUDIO_STATUS_OK, see AUDIO_STATUS_ERROR
*/
- public static native int setRouting(int mode, int routes, int mask);
+ /** @deprecated use {@link #setDeviceConnectionState(int,int,String)} */
+ public static int setRouting(int mode, int routes, int mask) {
+ return AUDIO_STATUS_ERROR;
+ }
/*
* Returns the current audio routing bit vector for a specified mode.
@@ -150,7 +146,10 @@ public class AudioSystem
* return an audio route bit vector that can be compared with ROUTE_xxx
* bits
*/
- public static native int getRouting(int mode);
+ /** @deprecated use {@link #getDeviceConnectionState(int,String)} */
+ public static int getRouting(int mode) {
+ return 0;
+ }
/*
* Checks whether any music is active.
@@ -160,17 +159,23 @@ public class AudioSystem
public static native boolean isMusicActive();
/*
- * Sets a generic audio configuration parameter. The use of these parameters
+ * Sets a group generic audio configuration parameters. The use of these parameters
* are platform dependant, see libaudio
*
- * ** Temporary interface - DO NOT USE
- *
- * TODO: Replace with a more generic key:value get/set mechanism
+ * param keyValuePairs list of parameters key value pairs in the form:
+ * key1=value1;key2=value2;...
+ */
+ public static native int setParameters(String keyValuePairs);
+
+ /*
+ * Gets a group generic audio configuration parameters. The use of these parameters
+ * are platform dependant, see libaudio
*
- * param key name of parameter to set. Must not be null.
- * param value value of parameter. Must not be null.
+ * param keys list of parameters
+ * return value: list of parameters key value pairs in the form:
+ * key1=value1;key2=value2;...
*/
- public static native void setParameter(String key, String value);
+ public static native String getParameters(String keys);
/*
private final static String TAG = "audio";
@@ -220,4 +225,68 @@ public class AudioSystem
mErrorCallback.onError(error);
}
}
+
+ /*
+ * AudioPolicyService methods
+ */
+
+ // output devices
+ public static final int DEVICE_OUT_EARPIECE = 0x1;
+ public static final int DEVICE_OUT_SPEAKER = 0x2;
+ public static final int DEVICE_OUT_WIRED_HEADSET = 0x4;
+ public static final int DEVICE_OUT_WIRED_HEADPHONE = 0x8;
+ public static final int DEVICE_OUT_BLUETOOTH_SCO = 0x10;
+ public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20;
+ public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40;
+ public static final int DEVICE_OUT_BLUETOOTH_A2DP = 0x80;
+ public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100;
+ public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200;
+ public static final int DEVICE_OUT_AUX_DIGITAL = 0x400;
+ public static final int DEVICE_OUT_FM_HEADPHONE = 0x800;
+ public static final int DEVICE_OUT_FM_SPEAKER = 0x1000;
+ public static final int DEVICE_OUT_TTY = 0x2000;
+ public static final int DEVICE_OUT_DEFAULT = 0x8000;
+ // input devices
+ public static final int DEVICE_IN_COMMUNICATION = 0x10000;
+ public static final int DEVICE_IN_AMBIENT = 0x20000;
+ public static final int DEVICE_IN_BUILTIN_MIC1 = 0x40000;
+ public static final int DEVICE_IN_BUILTIN_MIC2 = 0x80000;
+ public static final int DEVICE_IN_MIC_ARRAY = 0x100000;
+ public static final int DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x200000;
+ public static final int DEVICE_IN_WIRED_HEADSET = 0x400000;
+ public static final int DEVICE_IN_AUX_DIGITAL = 0x800000;
+ public static final int DEVICE_IN_DEFAULT = 0x80000000;
+
+ // device states
+ public static final int DEVICE_STATE_UNAVAILABLE = 0;
+ public static final int DEVICE_STATE_AVAILABLE = 1;
+
+ // phone state
+ public static final int PHONE_STATE_OFFCALL = 0;
+ public static final int PHONE_STATE_RINGING = 1;
+ public static final int PHONE_STATE_INCALL = 2;
+
+ // config for setForceUse
+ public static final int FORCE_NONE = 0;
+ public static final int FORCE_SPEAKER = 1;
+ public static final int FORCE_HEADPHONES = 2;
+ public static final int FORCE_BT_SCO = 3;
+ public static final int FORCE_BT_A2DP = 4;
+ public static final int FORCE_WIRED_ACCESSORY = 5;
+ public static final int FORCE_DEFAULT = FORCE_NONE;
+
+ // usage for serForceUse
+ public static final int FOR_COMMUNICATION = 0;
+ public static final int FOR_MEDIA = 1;
+ public static final int FOR_RECORD = 2;
+
+ public static native int setDeviceConnectionState(int device, int state, String device_address);
+ public static native int getDeviceConnectionState(int device, String device_address);
+ public static native int setPhoneState(int state);
+ public static native int setRingerMode(int mode, int mask);
+ public static native int setForceUse(int usage, int config);
+ public static native int getForceUse(int usage);
+ public static native int initStreamVolume(int stream, int indexMin, int indexMax);
+ public static native int setStreamVolumeIndex(int stream, int index);
+ public static native int getStreamVolumeIndex(int stream);
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 5f1be9d..7fbe965 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -120,7 +120,7 @@ public class AudioTrack
public static final int ERROR_INVALID_OPERATION = -3;
private static final int ERROR_NATIVESETUP_AUDIOSYSTEM = -16;
- private static final int ERROR_NATIVESETUP_INVALIDCHANNELCOUNT = -17;
+ private static final int ERROR_NATIVESETUP_INVALIDCHANNELMASK = -17;
private static final int ERROR_NATIVESETUP_INVALIDFORMAT = -18;
private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE = -19;
private static final int ERROR_NATIVESETUP_NATIVEINITFAILED = -20;
@@ -198,7 +198,7 @@ public class AudioTrack
/**
* The current audio channel configuration.
*/
- private int mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
+ private int mChannelConfiguration = AudioFormat.CHANNEL_OUT_MONO;
/**
* The encoding of the audio samples.
* @see AudioFormat#ENCODING_PCM_8BIT
@@ -235,8 +235,8 @@ public class AudioTrack
* @param sampleRateInHz the sample rate expressed in Hertz. Examples of rates are (but
* not limited to) 44100, 22050 and 11025.
* @param channelConfig describes the configuration of the audio channels.
- * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO} and
- * {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}
+ * See {@link AudioFormat#CHANNEL_OUT_MONO} and
+ * {@link AudioFormat#CHANNEL_OUT_STEREO}
* @param audioFormat the format in which the audio data is represented.
* See {@link AudioFormat#ENCODING_PCM_16BIT} and
* {@link AudioFormat#ENCODING_PCM_8BIT}
@@ -298,7 +298,8 @@ public class AudioTrack
&& (streamType != AudioManager.STREAM_RING) && (streamType != AudioManager.STREAM_SYSTEM)
&& (streamType != AudioManager.STREAM_VOICE_CALL)
&& (streamType != AudioManager.STREAM_NOTIFICATION)
- && (streamType != AudioManager.STREAM_BLUETOOTH_SCO)) {
+ && (streamType != AudioManager.STREAM_BLUETOOTH_SCO)
+ && (streamType != AudioManager.STREAM_DTMF)) {
throw (new IllegalArgumentException("Invalid stream type."));
} else {
mStreamType = streamType;
@@ -316,18 +317,18 @@ public class AudioTrack
//--------------
// channel config
switch (channelConfig) {
- case AudioFormat.CHANNEL_CONFIGURATION_DEFAULT:
- case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+ case AudioFormat.CHANNEL_OUT_DEFAULT:
+ case AudioFormat.CHANNEL_OUT_MONO:
mChannelCount = 1;
- mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
+ mChannelConfiguration = AudioFormat.CHANNEL_OUT_MONO;
break;
- case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+ case AudioFormat.CHANNEL_OUT_STEREO:
mChannelCount = 2;
- mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
+ mChannelConfiguration = AudioFormat.CHANNEL_OUT_STEREO;
break;
default:
mChannelCount = 0;
- mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_INVALID;
+ mChannelConfiguration = AudioFormat.CHANNEL_INVALID;
throw(new IllegalArgumentException("Unsupported channel configuration."));
}
@@ -452,8 +453,8 @@ public class AudioTrack
/**
* Returns the configured channel configuration.
- * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO}
- * and {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}.
+ * See {@link AudioFormat#CHANNEL_OUT_MONO}
+ * and {@link AudioFormat#CHANNEL_OUT_STEREO}.
*/
public int getChannelConfiguration() {
return mChannelConfiguration;
@@ -531,8 +532,8 @@ public class AudioTrack
* the expected frequency at which the buffer will be refilled with additional data to play.
* @param sampleRateInHz the sample rate expressed in Hertz.
* @param channelConfig describes the configuration of the audio channels.
- * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO} and
- * {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}
+ * See {@link AudioFormat#CHANNEL_OUT_MONO} and
+ * {@link AudioFormat#CHANNEL_OUT_STEREO}
* @param audioFormat the format in which the audio data is represented.
* See {@link AudioFormat#ENCODING_PCM_16BIT} and
* {@link AudioFormat#ENCODING_PCM_8BIT}
@@ -544,10 +545,10 @@ public class AudioTrack
static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
int channelCount = 0;
switch(channelConfig) {
- case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+ case AudioFormat.CHANNEL_OUT_MONO:
channelCount = 1;
break;
- case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+ case AudioFormat.CHANNEL_OUT_STEREO:
channelCount = 2;
break;
default:
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 9a8264f..bb4252b 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -29,9 +29,9 @@ interface IAudioService {
void setStreamVolume(int streamType, int index, int flags);
- void setStreamSolo(int streamType, boolean state, IBinder cb);
+ void setStreamSolo(int streamType, boolean state, IBinder cb);
- void setStreamMute(int streamType, boolean state, IBinder cb);
+ void setStreamMute(int streamType, boolean state, IBinder cb);
int getStreamVolume(int streamType);
@@ -46,23 +46,11 @@ interface IAudioService {
int getVibrateSetting(int vibrateType);
boolean shouldVibrate(int vibrateType);
-
- void setMicrophoneMute(boolean on);
-
- boolean isMicrophoneMute();
void setMode(int mode);
int getMode();
- void setRouting(int mode, int routes, int mask);
-
- int getRouting(int mode);
-
- boolean isMusicActive();
-
- void setParameter(String key, String value);
-
oneway void playSoundEffect(int effectType);
oneway void playSoundEffectVolume(int effectType, float volume);
diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java
index 4fb0ead..2263605 100644
--- a/media/java/android/media/JetPlayer.java
+++ b/media/java/android/media/JetPlayer.java
@@ -89,7 +89,7 @@ public class JetPlayer
// Jet rendering audio parameters
private static final int JET_OUTPUT_RATE = 22050; // _SAMPLE_RATE_22050 in Android.mk
private static final int JET_OUTPUT_CHANNEL_CONFIG =
- AudioFormat.CHANNEL_CONFIGURATION_STEREO; // NUM_OUTPUT_CHANNELS=2 in Android.mk
+ AudioFormat.CHANNEL_OUT_STEREO; // NUM_OUTPUT_CHANNELS=2 in Android.mk
//--------------------------------------------
diff --git a/media/java/android/media/ToneGenerator.java b/media/java/android/media/ToneGenerator.java
index e5ee9a3..c60a1ac 100644
--- a/media/java/android/media/ToneGenerator.java
+++ b/media/java/android/media/ToneGenerator.java
@@ -724,9 +724,9 @@ public class ToneGenerator
public static final int TONE_CDMA_SIGNAL_OFF = 98;
/** Maximum volume, for use with {@link #ToneGenerator(int,int)} */
- public static final int MAX_VOLUME = AudioSystem.MAX_VOLUME;
+ public static final int MAX_VOLUME = 100;
/** Minimum volume setting, for use with {@link #ToneGenerator(int,int)} */
- public static final int MIN_VOLUME = AudioSystem.MIN_VOLUME;
+ public static final int MIN_VOLUME = 0;
/**