summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java76
-rw-r--r--services/core/java/com/android/server/audio/AudioServiceEvents.java46
2 files changed, 111 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 7fde0ae8d445..4c6c728d7314 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -162,6 +162,7 @@ import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* The implementation of the volume manager service.
@@ -265,6 +266,7 @@ public class AudioService extends IAudioService.Stub
private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
private static final int MSG_HDMI_VOLUME_CHECK = 28;
+ private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
// start of messages handled under wakelock
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
@@ -1870,9 +1872,15 @@ public class AudioService extends IAudioService.Stub
// Check if volume update should be send to Hearing Aid
if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
- Log.i(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index=" + newIndex
- + " stream=" + streamType);
- mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+ // only modify the hearing aid attenuation when the stream to modify matches
+ // the one expected by the hearing aid
+ if (streamType == getHearingAidStreamType()) {
+ if (DEBUG_VOL) {
+ Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
+ + newIndex + " stream=" + streamType);
+ }
+ mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+ }
}
// Check if volume update should be sent to Hdmi system audio.
@@ -2164,11 +2172,53 @@ public class AudioService extends IAudioService.Stub
return AudioSystem.STREAM_VOICE_CALL;
case AudioSystem.MODE_NORMAL:
default:
+ // other conditions will influence the stream type choice, read on...
break;
}
+ if (mVoiceActive.get()) {
+ return AudioSystem.STREAM_VOICE_CALL;
+ }
return AudioSystem.STREAM_MUSIC;
}
+ private AtomicBoolean mVoiceActive = new AtomicBoolean(false);
+
+ private final IPlaybackConfigDispatcher mVoiceActivityMonitor =
+ new IPlaybackConfigDispatcher.Stub() {
+ @Override
+ public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
+ boolean flush) {
+ sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
+ 0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
+ configs /*obj*/, 0 /*delay*/);
+ }
+ };
+
+ private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
+ boolean voiceActive = false;
+ for (AudioPlaybackConfiguration config : configs) {
+ final int usage = config.getAudioAttributes().getUsage();
+ if ((usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
+ || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
+ && config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+ voiceActive = true;
+ break;
+ }
+ }
+ if (mVoiceActive.getAndSet(voiceActive) != voiceActive) {
+ updateHearingAidVolumeOnVoiceActivityUpdate();
+ }
+ }
+
+ private void updateHearingAidVolumeOnVoiceActivityUpdate() {
+ final int streamType = getHearingAidStreamType();
+ final int index = getStreamVolume(streamType);
+ sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
+ mVoiceActive.get(), streamType, index));
+ mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+
+ }
+
/**
* Manage an audio mode change for audio devices that use an "absolute volume" model,
* i.e. the framework sends the full scale signal, and the actual volume for the use case
@@ -2203,10 +2253,8 @@ public class AudioService extends IAudioService.Stub
// handling of specific interfaces goes here:
if ((device & mAbsVolumeMultiModeCaseDevices) == AudioSystem.DEVICE_OUT_HEARING_AID) {
final int index = getStreamVolume(streamType);
- mModeLogger.log(new AudioEventLogger.StringEvent("setMode to "
- + AudioSystem.modeToString(newMode)
- + " causes setting HEARING_AID volume to idx:" + index
- + " stream:" + AudioSystem.streamToString(streamType)));
+ sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
+ newMode, streamType, index));
mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
}
}
@@ -2272,7 +2320,8 @@ public class AudioService extends IAudioService.Stub
mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
}
- if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
+ if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0
+ && streamType == getHearingAidStreamType()) {
Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
+ " stream=" + streamType);
mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
@@ -4348,6 +4397,11 @@ public class AudioService extends IAudioService.Stub
throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
+ " (dis)connection, got " + state);
}
+ if (state == BluetoothProfile.STATE_CONNECTED) {
+ mPlaybackMonitor.registerPlaybackCallback(mVoiceActivityMonitor, true);
+ } else {
+ mPlaybackMonitor.unregisterPlaybackCallback(mVoiceActivityMonitor);
+ }
mDeviceBroker.postBluetoothHearingAidDeviceConnectionState(
device, state, suppressNoisyIntent, musicDevice, "AudioService");
}
@@ -4853,6 +4907,7 @@ public class AudioService extends IAudioService.Stub
pw.println((mIndexMin + 5) / 10);
pw.print(" Max: ");
pw.println((mIndexMax + 5) / 10);
+ pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType));
pw.print(" Current: ");
for (int i = 0; i < mIndexMap.size(); i++) {
if (i > 0) {
@@ -5429,6 +5484,11 @@ public class AudioService extends IAudioService.Stub
case MSG_HDMI_VOLUME_CHECK:
onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
+ break;
+
+ case MSG_PLAYBACK_CONFIG_CHANGE:
+ onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index d999217bf29b..fcd8701f4ccf 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -95,6 +95,8 @@ public class AudioServiceEvents {
static final int VOL_SET_HEARING_AID_VOL = 3;
static final int VOL_SET_AVRCP_VOL = 4;
static final int VOL_ADJUST_VOL_UID = 5;
+ static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6;
+ static final int VOL_MODE_CHANGE_HEARING_AID = 7;
final int mOp;
final int mStream;
@@ -102,6 +104,10 @@ public class AudioServiceEvents {
final int mVal2;
final String mCaller;
+ /** used for VOL_ADJUST_VOL_UID,
+ * VOL_ADJUST_SUGG_VOL,
+ * VOL_ADJUST_STREAM_VOL,
+ * VOL_SET_STREAM_VOL */
VolumeEvent(int op, int stream, int val1, int val2, String caller) {
mOp = op;
mStream = stream;
@@ -110,24 +116,46 @@ public class AudioServiceEvents {
mCaller = caller;
}
+ /** used for VOL_SET_HEARING_AID_VOL*/
VolumeEvent(int op, int index, int gainDb) {
mOp = op;
mVal1 = index;
mVal2 = gainDb;
- //unused
+ // unused
mStream = -1;
mCaller = null;
}
+ /** used for VOL_SET_AVRCP_VOL */
VolumeEvent(int op, int index) {
mOp = op;
mVal1 = index;
- //unused
+ // unused
mVal2 = 0;
mStream = -1;
mCaller = null;
}
+ /** used for VOL_VOICE_ACTIVITY_HEARING_AID */
+ VolumeEvent(int op, boolean voiceActive, int stream, int index) {
+ mOp = op;
+ mStream = stream;
+ mVal1 = index;
+ mVal2 = voiceActive ? 1 : 0;
+ // unused
+ mCaller = null;
+ }
+
+ /** used for VOL_MODE_CHANGE_HEARING_AID */
+ VolumeEvent(int op, int mode, int stream, int index) {
+ mOp = op;
+ mStream = stream;
+ mVal1 = index;
+ mVal2 = mode;
+ // unused
+ mCaller = null;
+ }
+
@Override
public String eventToString() {
switch (mOp) {
@@ -168,7 +196,19 @@ public class AudioServiceEvents {
.append(" flags:0x").append(Integer.toHexString(mVal2))
.append(") from ").append(mCaller)
.toString();
- default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
+ case VOL_VOICE_ACTIVITY_HEARING_AID:
+ return new StringBuilder("Voice activity change (")
+ .append(mVal2 == 1 ? "active" : "inactive")
+ .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
+ .append(" stream:").append(AudioSystem.streamToString(mStream))
+ .toString();
+ case VOL_MODE_CHANGE_HEARING_AID:
+ return new StringBuilder("setMode(")
+ .append(AudioSystem.modeToString(mVal2))
+ .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
+ .append(" stream:").append(AudioSystem.streamToString(mStream))
+ .toString();
+ default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
}
}
}