Merge "AudioService: hearing aid volume updates for voice vs media" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ed97f7b762
@@ -162,6 +162,7 @@ import java.util.List;
|
|||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implementation of the volume manager service.
|
* 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_SET_DEVICE_STREAM_VOLUME = 26;
|
||||||
private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
|
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_HDMI_VOLUME_CHECK = 28;
|
||||||
|
private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
|
||||||
// start of messages handled under wakelock
|
// start of messages handled under wakelock
|
||||||
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
|
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
|
||||||
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
|
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
|
||||||
@@ -1867,10 +1869,16 @@ public class AudioService extends IAudioService.Stub
|
|||||||
|
|
||||||
// Check if volume update should be send to Hearing Aid
|
// Check if volume update should be send to Hearing Aid
|
||||||
if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
|
if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
|
||||||
Log.i(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index=" + newIndex
|
// only modify the hearing aid attenuation when the stream to modify matches
|
||||||
+ " stream=" + streamType);
|
// 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);
|
mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if volume update should be sent to Hdmi system audio.
|
// Check if volume update should be sent to Hdmi system audio.
|
||||||
if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
|
if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
|
||||||
@@ -2161,11 +2169,53 @@ public class AudioService extends IAudioService.Stub
|
|||||||
return AudioSystem.STREAM_VOICE_CALL;
|
return AudioSystem.STREAM_VOICE_CALL;
|
||||||
case AudioSystem.MODE_NORMAL:
|
case AudioSystem.MODE_NORMAL:
|
||||||
default:
|
default:
|
||||||
|
// other conditions will influence the stream type choice, read on...
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (mVoiceActive.get()) {
|
||||||
|
return AudioSystem.STREAM_VOICE_CALL;
|
||||||
|
}
|
||||||
return AudioSystem.STREAM_MUSIC;
|
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,
|
* 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
|
* i.e. the framework sends the full scale signal, and the actual volume for the use case
|
||||||
@@ -2200,10 +2250,8 @@ public class AudioService extends IAudioService.Stub
|
|||||||
// handling of specific interfaces goes here:
|
// handling of specific interfaces goes here:
|
||||||
if ((device & mAbsVolumeMultiModeCaseDevices) == AudioSystem.DEVICE_OUT_HEARING_AID) {
|
if ((device & mAbsVolumeMultiModeCaseDevices) == AudioSystem.DEVICE_OUT_HEARING_AID) {
|
||||||
final int index = getStreamVolume(streamType);
|
final int index = getStreamVolume(streamType);
|
||||||
mModeLogger.log(new AudioEventLogger.StringEvent("setMode to "
|
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
|
||||||
+ AudioSystem.modeToString(newMode)
|
newMode, streamType, index));
|
||||||
+ " causes setting HEARING_AID volume to idx:" + index
|
|
||||||
+ " stream:" + AudioSystem.streamToString(streamType)));
|
|
||||||
mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
|
mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2269,7 +2317,8 @@ public class AudioService extends IAudioService.Stub
|
|||||||
mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
|
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
|
Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
|
||||||
+ " stream=" + streamType);
|
+ " stream=" + streamType);
|
||||||
mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
|
mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
|
||||||
@@ -4345,6 +4394,11 @@ public class AudioService extends IAudioService.Stub
|
|||||||
throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
|
throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
|
||||||
+ " (dis)connection, got " + state);
|
+ " (dis)connection, got " + state);
|
||||||
}
|
}
|
||||||
|
if (state == BluetoothProfile.STATE_CONNECTED) {
|
||||||
|
mPlaybackMonitor.registerPlaybackCallback(mVoiceActivityMonitor, true);
|
||||||
|
} else {
|
||||||
|
mPlaybackMonitor.unregisterPlaybackCallback(mVoiceActivityMonitor);
|
||||||
|
}
|
||||||
mDeviceBroker.postBluetoothHearingAidDeviceConnectionState(
|
mDeviceBroker.postBluetoothHearingAidDeviceConnectionState(
|
||||||
device, state, suppressNoisyIntent, musicDevice, "AudioService");
|
device, state, suppressNoisyIntent, musicDevice, "AudioService");
|
||||||
}
|
}
|
||||||
@@ -4832,6 +4886,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
pw.println((mIndexMin + 5) / 10);
|
pw.println((mIndexMin + 5) / 10);
|
||||||
pw.print(" Max: ");
|
pw.print(" Max: ");
|
||||||
pw.println((mIndexMax + 5) / 10);
|
pw.println((mIndexMax + 5) / 10);
|
||||||
|
pw.print(" streamVolume:"); pw.println(getStreamVolume(mStreamType));
|
||||||
pw.print(" Current: ");
|
pw.print(" Current: ");
|
||||||
for (int i = 0; i < mIndexMap.size(); i++) {
|
for (int i = 0; i < mIndexMap.size(); i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
@@ -5408,6 +5463,11 @@ public class AudioService extends IAudioService.Stub
|
|||||||
|
|
||||||
case MSG_HDMI_VOLUME_CHECK:
|
case MSG_HDMI_VOLUME_CHECK:
|
||||||
onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
|
onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_PLAYBACK_CONFIG_CHANGE:
|
||||||
|
onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ public class AudioServiceEvents {
|
|||||||
static final int VOL_SET_HEARING_AID_VOL = 3;
|
static final int VOL_SET_HEARING_AID_VOL = 3;
|
||||||
static final int VOL_SET_AVRCP_VOL = 4;
|
static final int VOL_SET_AVRCP_VOL = 4;
|
||||||
static final int VOL_ADJUST_VOL_UID = 5;
|
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 mOp;
|
||||||
final int mStream;
|
final int mStream;
|
||||||
@@ -102,6 +104,10 @@ public class AudioServiceEvents {
|
|||||||
final int mVal2;
|
final int mVal2;
|
||||||
final String mCaller;
|
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) {
|
VolumeEvent(int op, int stream, int val1, int val2, String caller) {
|
||||||
mOp = op;
|
mOp = op;
|
||||||
mStream = stream;
|
mStream = stream;
|
||||||
@@ -110,24 +116,46 @@ public class AudioServiceEvents {
|
|||||||
mCaller = caller;
|
mCaller = caller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** used for VOL_SET_HEARING_AID_VOL*/
|
||||||
VolumeEvent(int op, int index, int gainDb) {
|
VolumeEvent(int op, int index, int gainDb) {
|
||||||
mOp = op;
|
mOp = op;
|
||||||
mVal1 = index;
|
mVal1 = index;
|
||||||
mVal2 = gainDb;
|
mVal2 = gainDb;
|
||||||
//unused
|
// unused
|
||||||
mStream = -1;
|
mStream = -1;
|
||||||
mCaller = null;
|
mCaller = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** used for VOL_SET_AVRCP_VOL */
|
||||||
VolumeEvent(int op, int index) {
|
VolumeEvent(int op, int index) {
|
||||||
mOp = op;
|
mOp = op;
|
||||||
mVal1 = index;
|
mVal1 = index;
|
||||||
//unused
|
// unused
|
||||||
mVal2 = 0;
|
mVal2 = 0;
|
||||||
mStream = -1;
|
mStream = -1;
|
||||||
mCaller = null;
|
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
|
@Override
|
||||||
public String eventToString() {
|
public String eventToString() {
|
||||||
switch (mOp) {
|
switch (mOp) {
|
||||||
@@ -168,6 +196,18 @@ public class AudioServiceEvents {
|
|||||||
.append(" flags:0x").append(Integer.toHexString(mVal2))
|
.append(" flags:0x").append(Integer.toHexString(mVal2))
|
||||||
.append(") from ").append(mCaller)
|
.append(") from ").append(mCaller)
|
||||||
.toString();
|
.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();
|
default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user