Bug 3352047 Wrong message when adjusting volume
Add hidden AudioManager.getDevicesForStream and output device codes.
Change-Id: I4d1c1d3b6a077cd117720817d1f733dda557b947
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 3bab29f..a67ce17 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -403,7 +403,10 @@
case AudioManager.STREAM_MUSIC: {
// message = MUSIC_VOLUME_TEXT;
// Special case for when Bluetooth is active for music
- if (mAudioManager.isBluetoothA2dpOn()) {
+ if ((mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC) &
+ (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
+ AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+ AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
// additionalMessage =
// com.android.internal.R.string.volume_music_hint_playing_through_bluetooth;
// setLargeIcon(com.android.internal.R.drawable.ic_volume_bluetooth_ad2p);
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 5147cfa..5f3fed2 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -192,6 +192,12 @@
return index;
}
+static jint
+android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
+{
+ return (jint) AudioSystem::getDevicesForStream(static_cast <AudioSystem::stream_type>(stream));
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
@@ -208,7 +214,8 @@
{"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
{"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
{"setStreamVolumeIndex","(II)I", (void *)android_media_AudioSystem_setStreamVolumeIndex},
- {"getStreamVolumeIndex","(I)I", (void *)android_media_AudioSystem_getStreamVolumeIndex}
+ {"getStreamVolumeIndex","(I)I", (void *)android_media_AudioSystem_getStreamVolumeIndex},
+ {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
};
const char* const kClassPathName = "android/media/AudioSystem";
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 03f8944..2dc4beb 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -392,6 +392,7 @@
static status_t getStreamVolumeIndex(stream_type stream, int *index);
static uint32_t getStrategyForStream(stream_type stream);
+ static uint32_t getDevicesForStream(stream_type stream);
static audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
static status_t registerEffect(effect_descriptor_t *desc,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 5afceaa..720a562 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -74,6 +74,7 @@
virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index) = 0;
virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) = 0;
virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream) = 0;
+ virtual uint32_t getDevicesForStream(AudioSystem::stream_type stream) = 0;
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc) = 0;
virtual status_t registerEffect(effect_descriptor_t *desc,
audio_io_handle_t output,
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 5a59ef6..cc2ffa0 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -979,7 +979,7 @@
* false if otherwise
*/
public boolean isBluetoothA2dpOn() {
- if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,"")
+ if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"")
== AudioSystem.DEVICE_STATE_UNAVAILABLE) {
return false;
} else {
@@ -1004,9 +1004,9 @@
* false if otherwise
*/
public boolean isWiredHeadsetOn() {
- if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,"")
+ if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"")
== AudioSystem.DEVICE_STATE_UNAVAILABLE &&
- AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,"")
+ AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"")
== AudioSystem.DEVICE_STATE_UNAVAILABLE) {
return false;
} else {
@@ -1679,4 +1679,105 @@
return silentMode;
}
+ // This section re-defines new output device constants from AudioSystem, because the AudioSystem
+ // class is not used by other parts of the framework, which instead use definitions and methods
+ // from AudioManager. AudioSystem is an internal class used by AudioManager and AudioService.
+
+ /** {@hide} The audio output device code for the small speaker at the front of the device used
+ * when placing calls. Does not refer to an in-ear headphone without attached microphone,
+ * such as earbuds, earphones, or in-ear monitors (IEM). Those would be handled as a
+ * {@link #DEVICE_OUT_WIRED_HEADPHONE}.
+ */
+ public static final int DEVICE_OUT_EARPIECE = AudioSystem.DEVICE_OUT_EARPIECE;
+ /** {@hide} The audio output device code for the built-in speaker */
+ public static final int DEVICE_OUT_SPEAKER = AudioSystem.DEVICE_OUT_SPEAKER;
+ /** {@hide} The audio output device code for a wired headset with attached microphone */
+ public static final int DEVICE_OUT_WIRED_HEADSET = AudioSystem.DEVICE_OUT_WIRED_HEADSET;
+ /** {@hide} The audio output device code for a wired headphone without attached microphone */
+ public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
+ /** {@hide} The audio output device code for generic Bluetooth SCO, for voice */
+ public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
+ /** {@hide} The audio output device code for Bluetooth SCO Headset Profile (HSP) and
+ * Hands-Free Profile (HFP), for voice
+ */
+ public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET =
+ AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+ /** {@hide} The audio output device code for Bluetooth SCO car audio, for voice */
+ public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT =
+ AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+ /** {@hide} The audio output device code for generic Bluetooth A2DP, for music */
+ public static final int DEVICE_OUT_BLUETOOTH_A2DP = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
+ /** {@hide} The audio output device code for Bluetooth A2DP headphones, for music */
+ public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES =
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+ /** {@hide} The audio output device code for Bluetooth A2DP external speaker, for music */
+ public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER =
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+ /** {@hide} The audio output device code for S/PDIF or HDMI */
+ public static final int DEVICE_OUT_AUX_DIGITAL = AudioSystem.DEVICE_OUT_AUX_DIGITAL;
+ /** {@hide} The audio output device code for an analog wired headset attached via a
+ * docking station
+ */
+ public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET;
+ /** {@hide} The audio output device code for a digital wired headset attached via a
+ * docking station
+ */
+ public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET;
+ /** {@hide} This is not used as a returned value from {@link #getDevicesForStream}, but could be
+ * used in the future in a set method to select whatever default device is chosen by the
+ * platform-specific implementation.
+ */
+ public static final int DEVICE_OUT_DEFAULT = AudioSystem.DEVICE_OUT_DEFAULT;
+
+ /**
+ * Return the enabled devices for the specified output stream type.
+ *
+ * @param streamType The stream type to query. One of
+ * {@link #STREAM_VOICE_CALL},
+ * {@link #STREAM_SYSTEM},
+ * {@link #STREAM_RING},
+ * {@link #STREAM_MUSIC},
+ * {@link #STREAM_ALARM},
+ * {@link #STREAM_NOTIFICATION},
+ * {@link #STREAM_DTMF}.
+ *
+ * @return The bit-mask "or" of audio output device codes for all enabled devices on this
+ * stream. Zero or more of
+ * {@link #DEVICE_OUT_EARPIECE},
+ * {@link #DEVICE_OUT_SPEAKER},
+ * {@link #DEVICE_OUT_WIRED_HEADSET},
+ * {@link #DEVICE_OUT_WIRED_HEADPHONE},
+ * {@link #DEVICE_OUT_BLUETOOTH_SCO},
+ * {@link #DEVICE_OUT_BLUETOOTH_SCO_HEADSET},
+ * {@link #DEVICE_OUT_BLUETOOTH_SCO_CARKIT},
+ * {@link #DEVICE_OUT_BLUETOOTH_A2DP},
+ * {@link #DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES},
+ * {@link #DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER},
+ * {@link #DEVICE_OUT_AUX_DIGITAL},
+ * {@link #DEVICE_OUT_ANLG_DOCK_HEADSET},
+ * {@link #DEVICE_OUT_DGTL_DOCK_HEADSET}.
+ * {@link #DEVICE_OUT_DEFAULT} is not used here.
+ *
+ * The implementation may support additional device codes beyond those listed, so
+ * the application should ignore any bits which it does not recognize.
+ * Note that the information may be imprecise when the implementation
+ * cannot distinguish whether a particular device is enabled.
+ *
+ * {@hide}
+ */
+ public int getDevicesForStream(int streamType) {
+ switch (streamType) {
+ case STREAM_VOICE_CALL:
+ case STREAM_SYSTEM:
+ case STREAM_RING:
+ case STREAM_MUSIC:
+ case STREAM_ALARM:
+ case STREAM_NOTIFICATION:
+ case STREAM_DTMF:
+ return AudioSystem.getDevicesForStream(streamType);
+ default:
+ return 0;
+ }
+ }
+
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index e20bb25..92cc960 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -18,7 +18,8 @@
/* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET
- * TO UPDATE THE CORRESPONDING NATIVE GLUE. THANK YOU FOR YOUR COOPERATION
+ * TO UPDATE THE CORRESPONDING NATIVE GLUE AND AudioManager.java.
+ * THANK YOU FOR YOUR COOPERATION.
*/
/**
@@ -29,7 +30,7 @@
/* FIXME: Need to finalize this and correlate with native layer */
/*
* If these are modified, please also update Settings.System.VOLUME_SETTINGS
- * and attrs.xml
+ * and attrs.xml and AudioManager.java.
*/
/* The audio stream for phone calls */
public static final int STREAM_VOICE_CALL = 0;
@@ -232,7 +233,7 @@
* AudioPolicyService methods
*/
- // output devices
+ // output devices, be sure to update AudioManager.java also
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;
@@ -295,4 +296,5 @@
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);
+ public static native int getDevicesForStream(int stream);
}
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 9d9b3c0..2f694ba 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -668,6 +668,13 @@
return aps->getStrategyForStream(stream);
}
+uint32_t AudioSystem::getDevicesForStream(AudioSystem::stream_type stream)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return 0;
+ return aps->getDevicesForStream(stream);
+}
+
audio_io_handle_t AudioSystem::getOutputForEffect(effect_descriptor_t *desc)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 457f7ed..b89a278 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -49,7 +49,8 @@
GET_OUTPUT_FOR_EFFECT,
REGISTER_EFFECT,
UNREGISTER_EFFECT,
- IS_STREAM_ACTIVE
+ IS_STREAM_ACTIVE,
+ GET_DEVICES_FOR_STREAM,
};
class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
@@ -263,6 +264,15 @@
return reply.readInt32();
}
+ virtual uint32_t getDevicesForStream(AudioSystem::stream_type stream)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeInt32(static_cast <uint32_t>(stream));
+ remote()->transact(GET_DEVICES_FOR_STREAM, data, &reply);
+ return (uint32_t) reply.readInt32();
+ }
+
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc)
{
Parcel data, reply;
@@ -495,6 +505,14 @@
return NO_ERROR;
} break;
+ case GET_DEVICES_FOR_STREAM: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ AudioSystem::stream_type stream =
+ static_cast <AudioSystem::stream_type>(data.readInt32());
+ reply->writeInt32(static_cast <int>(getDevicesForStream(stream)));
+ return NO_ERROR;
+ } break;
+
case GET_OUTPUT_FOR_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
effect_descriptor_t desc;
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index 04d63e6..58e9b08 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -1543,6 +1543,20 @@
return (uint32_t)getStrategy(stream);
}
+uint32_t AudioPolicyManagerBase::getDevicesForStream(AudioSystem::stream_type stream) {
+ uint32_t devices;
+ // By checking the range of stream before calling getStrategy, we avoid
+ // getStrategy's behavior for invalid streams. getStrategy would do a LOGE
+ // and then return STRATEGY_MEDIA, but we want to return the empty set.
+ if (stream < (AudioSystem::stream_type) 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
+ devices = 0;
+ } else {
+ AudioPolicyManagerBase::routing_strategy strategy = getStrategy(stream);
+ devices = getDeviceForStrategy(strategy, true);
+ }
+ return devices;
+}
+
AudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy(
AudioSystem::stream_type stream) {
// stream to strategy mapping
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 953ddac..b614c48 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -365,6 +365,14 @@
return mpPolicyManager->getStrategyForStream(stream);
}
+uint32_t AudioPolicyService::getDevicesForStream(AudioSystem::stream_type stream)
+{
+ if (mpPolicyManager == NULL) {
+ return 0;
+ }
+ return mpPolicyManager->getDevicesForStream(stream);
+}
+
audio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc)
{
if (mpPolicyManager == NULL) {
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index 4749b8b..faad893 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -86,6 +86,7 @@
virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index);
virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream);
+ virtual uint32_t getDevicesForStream(AudioSystem::stream_type stream);
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
virtual status_t registerEffect(effect_descriptor_t *desc,