diff options
| author | 2019-04-22 12:21:50 -0700 | |
|---|---|---|
| committer | 2019-04-22 16:35:42 -0700 | |
| commit | b32faaa1cce21b24f20d72d8aaa5bf8dd238a164 (patch) | |
| tree | 0b02bbd49468f60b50f9866505bac2c2d7ee2a09 | |
| parent | a99ff5fa9a7bb43113db51c0069222417accd322 (diff) | |
AudioService: manage hearing aid volume for calls
Add a mechanism to support audio devices that behave like "absolute
volume" in AVRCP, but that support multiple use cases based on
the audio mode.
Treat hearing aid as such a device:
any change in audio mode will cause the volume of the corresponding
dominent use case to be applied.
Fix a typo in SCO client death that caused a class cast issue.
Bug: 131091438
Bug: 129163231
Test: set hearing aid volume to X for media, take phone call and set volume to Y,
end call, verify volume is X for media.
Change-Id: Id778f69b98825c83b7137917bd81e973298ab8bb
| -rw-r--r-- | services/core/java/com/android/server/audio/AudioDeviceBroker.java | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/audio/AudioService.java | 53 |
2 files changed, 53 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 4ce6d91d25b0..05be10068c94 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -771,7 +771,7 @@ import com.android.internal.annotations.GuardedBy; case MSG_L_SCOCLIENT_DIED: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { - mBtHelper.scoClientDied(msg.arg1); + mBtHelper.scoClientDied(msg.obj); } } break; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index b6879a3def03..d3af8f0745d7 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -519,6 +519,10 @@ public class AudioService extends IAudioService.Stub AudioSystem.DEVICE_OUT_AUX_LINE; // Devices for which the volume is always max, no volume panel int mFullVolumeDevices = 0; + // Devices for the which use the "absolute volume" concept (framework sends audio signal + // full scale, and volume control separately) and can be used for multiple use cases reflected + // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL). + int mAbsVolumeMultiModeCaseDevices = AudioSystem.DEVICE_OUT_HEARING_AID; private final boolean mMonitorRotation; @@ -2050,6 +2054,49 @@ public class AudioService extends IAudioService.Stub } } + /** + * 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 + * is communicated separately. + */ + void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) { + if (oldMode == newMode) { + return; + } + int streamType = AudioSystem.STREAM_MUSIC; + switch (newMode) { + case AudioSystem.MODE_IN_COMMUNICATION: + case AudioSystem.MODE_IN_CALL: + streamType = AudioSystem.STREAM_VOICE_CALL; + break; + case AudioSystem.MODE_NORMAL: + streamType = AudioSystem.STREAM_MUSIC; + break; + case AudioSystem.MODE_RINGTONE: + // not changing anything for ringtone + return; + case AudioSystem.MODE_CURRENT: + case AudioSystem.MODE_INVALID: + default: + // don't know what to do in this case, better bail + return; + } + final int device = AudioSystem.getDevicesForStream(streamType); + if ((device & mAbsVolumeMultiModeCaseDevices) == 0) { + return; + } + + // 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))); + mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType); + } + } + private void setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid) { if (DEBUG_VOL) { @@ -3039,9 +3086,9 @@ public class AudioService extends IAudioService.Stub } } - // must be called synchronized on mSetModeLock // setModeInt() returns a valid PID if the audio mode was successfully set to // any mode other than NORMAL. + @GuardedBy("mDeviceBroker.mSetModeLock") private int setModeInt(int mode, IBinder cb, int pid, String caller) { if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", caller=" + caller + ")"); } @@ -3063,6 +3110,7 @@ public class AudioService extends IAudioService.Stub break; } } + final int oldMode = mMode; int status = AudioSystem.AUDIO_STATUS_OK; int actualMode; do { @@ -3134,6 +3182,9 @@ public class AudioService extends IAudioService.Stub setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, caller); updateStreamVolumeAlias(true /*updateVolumes*/, caller); + + // change of mode may require volume to be re-applied on some devices + updateAbsVolumeMultiModeDevices(oldMode, actualMode); } return newModeOwnerPid; } |