Rename "Absolute Volume Control" to "absolute volume behavior"
Currently, the CEC framework uses "Absolute Volume Control" to refer to the state where both of the following are true: 1. The System Audio device supports the <Set Audio Volume Level> message (that is, it supports the CEC "Absolute Volume Control" feature) 2. The HDMI audio output device in AudioService uses "absolute volume behavior" This state is currently named for (1); this CL changes it to be named for (2). This is because we plan to reuse the code path for enabling this state for a new state, where (1) is not true: the System Audio device need not support <Set Audio Volume Level>/"Absolute Volume Control". In this new case, (2) will still be true, as the audio output device will use a variant of absolute volume behavior - adjust-only absolute volume behavior. Bug: 240663266 Test: make Change-Id: I679d5c1e74a1bfd8dcfe9246410ccb3089a5c5ac
This commit is contained in:
@@ -18,10 +18,10 @@ package com.android.server.hdmi;
|
||||
|
||||
/**
|
||||
* Action to query and track the audio status of the System Audio device when enabling or using
|
||||
* Absolute Volume Control. Must be removed when AVC is disabled. Performs two main functions:
|
||||
* 1. When enabling AVC: queries the starting audio status of the System Audio device and
|
||||
* absolute volume behavior. Must be removed when AVB is disabled. Performs two main functions:
|
||||
* 1. When enabling AVB: queries the starting audio status of the System Audio device and
|
||||
* enables the feature upon receiving a response.
|
||||
* 2. While AVC is enabled: monitors <Report Audio Status> messages from the System Audio device and
|
||||
* 2. While AVB is enabled: monitors <Report Audio Status> messages from the System Audio device and
|
||||
* notifies AudioService if the audio status changes.
|
||||
*/
|
||||
final class AbsoluteVolumeAudioStatusAction extends HdmiCecFeatureAction {
|
||||
@@ -83,14 +83,14 @@ final class AbsoluteVolumeAudioStatusAction extends HdmiCecFeatureAction {
|
||||
|
||||
AudioStatus audioStatus = new AudioStatus(volume, mute);
|
||||
if (mState == STATE_WAIT_FOR_INITIAL_AUDIO_STATUS) {
|
||||
localDevice().getService().enableAbsoluteVolumeControl(audioStatus);
|
||||
localDevice().getService().enableAbsoluteVolumeBehavior(audioStatus);
|
||||
mState = STATE_MONITOR_AUDIO_STATUS;
|
||||
} else if (mState == STATE_MONITOR_AUDIO_STATUS) {
|
||||
if (audioStatus.getVolume() != mLastAudioStatus.getVolume()) {
|
||||
localDevice().getService().notifyAvcVolumeChange(audioStatus.getVolume());
|
||||
localDevice().getService().notifyAvbVolumeChange(audioStatus.getVolume());
|
||||
}
|
||||
if (audioStatus.getMute() != mLastAudioStatus.getMute()) {
|
||||
localDevice().getService().notifyAvcMuteChange(audioStatus.getMute());
|
||||
localDevice().getService().notifyAvbMuteChange(audioStatus.getMute());
|
||||
}
|
||||
}
|
||||
mLastAudioStatus = audioStatus;
|
||||
|
||||
@@ -1012,17 +1012,17 @@ abstract class HdmiCecLocalDevice extends HdmiLocalDevice {
|
||||
action.start();
|
||||
}
|
||||
|
||||
void addAvcAudioStatusAction(int targetAddress) {
|
||||
void addAvbAudioStatusAction(int targetAddress) {
|
||||
if (!hasAction(AbsoluteVolumeAudioStatusAction.class)) {
|
||||
addAndStartAction(new AbsoluteVolumeAudioStatusAction(this, targetAddress));
|
||||
}
|
||||
}
|
||||
|
||||
void removeAvcAudioStatusAction() {
|
||||
void removeAvbAudioStatusAction() {
|
||||
removeAction(AbsoluteVolumeAudioStatusAction.class);
|
||||
}
|
||||
|
||||
void updateAvcVolume(int volumeIndex) {
|
||||
void updateAvbVolume(int volumeIndex) {
|
||||
for (AbsoluteVolumeAudioStatusAction action :
|
||||
getActions(AbsoluteVolumeAudioStatusAction.class)) {
|
||||
action.updateVolume(volumeIndex);
|
||||
@@ -1035,7 +1035,7 @@ abstract class HdmiCecLocalDevice extends HdmiLocalDevice {
|
||||
* and send <Set Audio Volume Level> (to see if it gets a <Feature Abort> in response).
|
||||
*/
|
||||
@ServiceThreadOnly
|
||||
void queryAvcSupport(int targetAddress) {
|
||||
void querySetAudioVolumeLevelSupport(int targetAddress) {
|
||||
assertRunOnServiceThread();
|
||||
|
||||
// Send <Give Features> if using CEC 2.0 or above.
|
||||
@@ -1054,7 +1054,7 @@ abstract class HdmiCecLocalDevice extends HdmiLocalDevice {
|
||||
@Override
|
||||
public void onComplete(int result) {
|
||||
if (result == HdmiControlManager.RESULT_SUCCESS) {
|
||||
getService().checkAndUpdateAbsoluteVolumeControlState();
|
||||
getService().checkAndUpdateAbsoluteVolumeBehavior();
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -259,7 +259,7 @@ public class HdmiCecNetwork {
|
||||
// The addition of a local device should not notify listeners
|
||||
return;
|
||||
}
|
||||
mHdmiControlService.checkAndUpdateAbsoluteVolumeControlState();
|
||||
mHdmiControlService.checkAndUpdateAbsoluteVolumeBehavior();
|
||||
if (info.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) {
|
||||
// Don't notify listeners of devices that haven't reported their physical address yet
|
||||
return;
|
||||
@@ -384,7 +384,7 @@ public class HdmiCecNetwork {
|
||||
final void removeCecDevice(HdmiCecLocalDevice localDevice, int address) {
|
||||
assertRunOnServiceThread();
|
||||
HdmiDeviceInfo info = removeDeviceInfo(HdmiDeviceInfo.idForCecDevice(address));
|
||||
mHdmiControlService.checkAndUpdateAbsoluteVolumeControlState();
|
||||
mHdmiControlService.checkAndUpdateAbsoluteVolumeBehavior();
|
||||
localDevice.mCecMessageCache.flushMessagesFrom(address);
|
||||
if (info.getPhysicalAddress() == HdmiDeviceInfo.PATH_INVALID) {
|
||||
// Don't notify listeners of devices that haven't reported their physical address yet
|
||||
@@ -592,7 +592,7 @@ public class HdmiCecNetwork {
|
||||
|
||||
updateCecDevice(newDeviceInfo);
|
||||
|
||||
mHdmiControlService.checkAndUpdateAbsoluteVolumeControlState();
|
||||
mHdmiControlService.checkAndUpdateAbsoluteVolumeBehavior();
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
@@ -625,7 +625,7 @@ public class HdmiCecNetwork {
|
||||
.build();
|
||||
updateCecDevice(newDeviceInfo);
|
||||
|
||||
mHdmiControlService.checkAndUpdateAbsoluteVolumeControlState();
|
||||
mHdmiControlService.checkAndUpdateAbsoluteVolumeBehavior();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -231,8 +231,8 @@ public class HdmiControlService extends SystemService {
|
||||
new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
|
||||
AudioDeviceInfo.TYPE_HDMI_EARC, "");
|
||||
|
||||
// Audio output devices used for Absolute Volume Control
|
||||
private static final List<AudioDeviceAttributes> AVC_AUDIO_OUTPUT_DEVICES =
|
||||
// Audio output devices used for absolute volume behavior
|
||||
private static final List<AudioDeviceAttributes> AVB_AUDIO_OUTPUT_DEVICES =
|
||||
Collections.unmodifiableList(Arrays.asList(AUDIO_OUTPUT_DEVICE_HDMI,
|
||||
AUDIO_OUTPUT_DEVICE_HDMI_ARC, AUDIO_OUTPUT_DEVICE_HDMI_EARC));
|
||||
|
||||
@@ -265,7 +265,7 @@ public class HdmiControlService extends SystemService {
|
||||
@HdmiControlManager.VolumeControl
|
||||
private int mHdmiCecVolumeControl;
|
||||
|
||||
// Caches the volume behaviors of all audio output devices in AVC_AUDIO_OUTPUT_DEVICES.
|
||||
// Caches the volume behaviors of all audio output devices in AVB_AUDIO_OUTPUT_DEVICES.
|
||||
@GuardedBy("mLock")
|
||||
private Map<AudioDeviceAttributes, Integer> mAudioDeviceVolumeBehaviors = new HashMap<>();
|
||||
|
||||
@@ -2751,7 +2751,7 @@ public class HdmiControlService extends SystemService {
|
||||
pw.println("mPowerStatus: " + mPowerStatusController.getPowerStatus());
|
||||
pw.println("mIsCecAvailable: " + mIsCecAvailable);
|
||||
pw.println("mCecVersion: " + mCecVersion);
|
||||
pw.println("mIsAbsoluteVolumeControlEnabled: " + isAbsoluteVolumeControlEnabled());
|
||||
pw.println("mIsAbsoluteVolumeBehaviorEnabled: " + isAbsoluteVolumeBehaviorEnabled());
|
||||
|
||||
// System settings
|
||||
pw.println("System_settings:");
|
||||
@@ -2919,7 +2919,7 @@ public class HdmiControlService extends SystemService {
|
||||
@HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
|
||||
mHdmiCecVolumeControl = hdmiCecVolumeControl;
|
||||
announceHdmiCecVolumeControlFeatureChange(hdmiCecVolumeControl);
|
||||
runOnServiceThread(this::checkAndUpdateAbsoluteVolumeControlState);
|
||||
runOnServiceThread(this::checkAndUpdateAbsoluteVolumeBehavior);
|
||||
}
|
||||
|
||||
// Get the source address to send out commands to devices connected to the current device
|
||||
@@ -3882,7 +3882,7 @@ public class HdmiControlService extends SystemService {
|
||||
synchronized (mLock) {
|
||||
mSystemAudioActivated = on;
|
||||
}
|
||||
runOnServiceThread(this::checkAndUpdateAbsoluteVolumeControlState);
|
||||
runOnServiceThread(this::checkAndUpdateAbsoluteVolumeBehavior);
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
@@ -3993,7 +3993,7 @@ public class HdmiControlService extends SystemService {
|
||||
deviceIsActiveSource, caller);
|
||||
}
|
||||
|
||||
runOnServiceThread(this::checkAndUpdateAbsoluteVolumeControlState);
|
||||
runOnServiceThread(this::checkAndUpdateAbsoluteVolumeBehavior);
|
||||
}
|
||||
|
||||
// This method should only be called when the device can be the active source
|
||||
@@ -4189,17 +4189,17 @@ public class HdmiControlService extends SystemService {
|
||||
|
||||
/**
|
||||
* Listener for changes to the volume behavior of an audio output device. Caches the
|
||||
* volume behavior of devices used for Absolute Volume Control.
|
||||
* volume behavior of devices used for absolute volume behavior.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
@ServiceThreadOnly
|
||||
void onDeviceVolumeBehaviorChanged(AudioDeviceAttributes device, int volumeBehavior) {
|
||||
assertRunOnServiceThread();
|
||||
if (AVC_AUDIO_OUTPUT_DEVICES.contains(device)) {
|
||||
if (AVB_AUDIO_OUTPUT_DEVICES.contains(device)) {
|
||||
synchronized (mLock) {
|
||||
mAudioDeviceVolumeBehaviors.put(device, volumeBehavior);
|
||||
}
|
||||
checkAndUpdateAbsoluteVolumeControlState();
|
||||
checkAndUpdateAbsoluteVolumeBehavior();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4209,7 +4209,7 @@ public class HdmiControlService extends SystemService {
|
||||
*/
|
||||
@AudioManager.DeviceVolumeBehavior
|
||||
private int getDeviceVolumeBehavior(AudioDeviceAttributes device) {
|
||||
if (AVC_AUDIO_OUTPUT_DEVICES.contains(device)) {
|
||||
if (AVB_AUDIO_OUTPUT_DEVICES.contains(device)) {
|
||||
synchronized (mLock) {
|
||||
if (mAudioDeviceVolumeBehaviors.containsKey(device)) {
|
||||
return mAudioDeviceVolumeBehaviors.get(device);
|
||||
@@ -4220,22 +4220,22 @@ public class HdmiControlService extends SystemService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether Absolute Volume Control is enabled or not. This is determined by the
|
||||
* Returns whether absolute volume behavior is enabled or not. This is determined by the
|
||||
* volume behavior of the relevant HDMI audio output device(s) for this device's type.
|
||||
*/
|
||||
public boolean isAbsoluteVolumeControlEnabled() {
|
||||
public boolean isAbsoluteVolumeBehaviorEnabled() {
|
||||
if (!isTvDevice() && !isPlaybackDevice()) {
|
||||
return false;
|
||||
}
|
||||
AudioDeviceAttributes avcAudioOutputDevice = getAvcAudioOutputDevice();
|
||||
if (avcAudioOutputDevice == null) {
|
||||
AudioDeviceAttributes avbAudioOutputDevice = getAvbAudioOutputDevice();
|
||||
if (avbAudioOutputDevice == null) {
|
||||
return false;
|
||||
}
|
||||
return getDeviceVolumeBehavior(avcAudioOutputDevice)
|
||||
return getDeviceVolumeBehavior(avbAudioOutputDevice)
|
||||
== AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
|
||||
}
|
||||
|
||||
private AudioDeviceAttributes getAvcAudioOutputDevice() {
|
||||
private AudioDeviceAttributes getAvbAudioOutputDevice() {
|
||||
if (isTvDevice()) {
|
||||
return tv().getSystemAudioOutputDevice();
|
||||
} else if (isPlaybackDevice()) {
|
||||
@@ -4246,30 +4246,30 @@ public class HdmiControlService extends SystemService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the conditions for Absolute Volume Control (AVC), and enables or disables the feature
|
||||
* if necessary. AVC is enabled precisely when a specific audio output device
|
||||
* Checks the conditions for Absolute Volume Behavior (AVB), and enables or disables the feature
|
||||
* if necessary. AVB is enabled precisely when a specific audio output device
|
||||
* (HDMI for playback devices, and HDMI_ARC or HDMI_EARC for TVs) is using absolute volume
|
||||
* behavior.
|
||||
*
|
||||
* AVC must be enabled on a Playback device or TV precisely when it is playing
|
||||
* AVB must be enabled on a Playback device or TV precisely when it is playing
|
||||
* audio on an external device (the System Audio device) that supports the feature.
|
||||
* This reduces to these conditions:
|
||||
*
|
||||
* 1. If the System Audio Device is an Audio System: System Audio Mode is active
|
||||
* 2. Our HDMI audio output device is using full volume behavior
|
||||
* 3. CEC volume is enabled
|
||||
* 4. The System Audio device supports AVC (i.e. it supports <Set Audio Volume Level>)
|
||||
* 4. The System Audio device supports AVB (i.e. it supports <Set Audio Volume Level>)
|
||||
*
|
||||
* If not all of these conditions are met, this method disables AVC if necessary.
|
||||
* If not all of these conditions are met, this method disables AVB if necessary.
|
||||
*
|
||||
* If all of these conditions are met, this method starts an action to query the System Audio
|
||||
* device's audio status, which enables AVC upon obtaining the audio status.
|
||||
* device's audio status, which enables AVB upon obtaining the audio status.
|
||||
*/
|
||||
@ServiceThreadOnly
|
||||
void checkAndUpdateAbsoluteVolumeControlState() {
|
||||
void checkAndUpdateAbsoluteVolumeBehavior() {
|
||||
assertRunOnServiceThread();
|
||||
|
||||
// Can't enable or disable AVC before we have access to system services
|
||||
// Can't set volume behavior before we have access to system services
|
||||
if (getAudioManager() == null) {
|
||||
return;
|
||||
}
|
||||
@@ -4281,20 +4281,20 @@ public class HdmiControlService extends SystemService {
|
||||
// (Doesn't apply to Playback Devices, where if SAM isn't active, we assume the
|
||||
// TV is the System Audio Device instead.)
|
||||
if (!isSystemAudioActivated()) {
|
||||
disableAbsoluteVolumeControl();
|
||||
disableAbsoluteVolumeBehavior();
|
||||
return;
|
||||
}
|
||||
} else if (isPlaybackDevice() && playback() != null) {
|
||||
localCecDevice = playback();
|
||||
} else {
|
||||
// Either this device type doesn't support AVC, or it hasn't fully initialized yet
|
||||
// Either this device type doesn't support AVB, or it hasn't fully initialized yet
|
||||
return;
|
||||
}
|
||||
|
||||
HdmiDeviceInfo systemAudioDeviceInfo = getHdmiCecNetwork().getSafeCecDeviceInfo(
|
||||
localCecDevice.findAudioReceiverAddress());
|
||||
@AudioManager.DeviceVolumeBehavior int currentVolumeBehavior =
|
||||
getDeviceVolumeBehavior(getAvcAudioOutputDevice());
|
||||
getDeviceVolumeBehavior(getAvbAudioOutputDevice());
|
||||
|
||||
// Condition 2: Already using full or absolute volume behavior
|
||||
boolean alreadyUsingFullOrAbsoluteVolume =
|
||||
@@ -4305,45 +4305,46 @@ public class HdmiControlService extends SystemService {
|
||||
getHdmiCecVolumeControl() == HdmiControlManager.VOLUME_CONTROL_ENABLED;
|
||||
|
||||
if (!cecVolumeEnabled || !alreadyUsingFullOrAbsoluteVolume) {
|
||||
disableAbsoluteVolumeControl();
|
||||
disableAbsoluteVolumeBehavior();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for safety: if the System Audio device is a candidate for AVC, we should already
|
||||
// Check for safety: if the System Audio device is a candidate for AVB, we should already
|
||||
// have received messages from it to trigger the other conditions.
|
||||
if (systemAudioDeviceInfo == null) {
|
||||
disableAbsoluteVolumeControl();
|
||||
disableAbsoluteVolumeBehavior();
|
||||
return;
|
||||
}
|
||||
// Condition 4: The System Audio device supports AVC (i.e. <Set Audio Volume Level>).
|
||||
// Condition 4: The System Audio device supports AVB (i.e. <Set Audio Volume Level>).
|
||||
switch (systemAudioDeviceInfo.getDeviceFeatures().getSetAudioVolumeLevelSupport()) {
|
||||
case DeviceFeatures.FEATURE_SUPPORTED:
|
||||
if (!isAbsoluteVolumeControlEnabled()) {
|
||||
// Start an action that will call {@link #enableAbsoluteVolumeControl}
|
||||
if (!isAbsoluteVolumeBehaviorEnabled()) {
|
||||
// Start an action that will call {@link #enableAbsoluteVolumeBehavior}
|
||||
// once the System Audio device sends <Report Audio Status>
|
||||
localCecDevice.addAvcAudioStatusAction(
|
||||
localCecDevice.addAvbAudioStatusAction(
|
||||
systemAudioDeviceInfo.getLogicalAddress());
|
||||
}
|
||||
return;
|
||||
case DeviceFeatures.FEATURE_NOT_SUPPORTED:
|
||||
disableAbsoluteVolumeControl();
|
||||
disableAbsoluteVolumeBehavior();
|
||||
return;
|
||||
case DeviceFeatures.FEATURE_SUPPORT_UNKNOWN:
|
||||
disableAbsoluteVolumeControl();
|
||||
localCecDevice.queryAvcSupport(systemAudioDeviceInfo.getLogicalAddress());
|
||||
disableAbsoluteVolumeBehavior();
|
||||
localCecDevice.querySetAudioVolumeLevelSupport(
|
||||
systemAudioDeviceInfo.getLogicalAddress());
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void disableAbsoluteVolumeControl() {
|
||||
private void disableAbsoluteVolumeBehavior() {
|
||||
if (isPlaybackDevice()) {
|
||||
playback().removeAvcAudioStatusAction();
|
||||
playback().removeAvbAudioStatusAction();
|
||||
} else if (isTvDevice()) {
|
||||
tv().removeAvcAudioStatusAction();
|
||||
tv().removeAvbAudioStatusAction();
|
||||
}
|
||||
AudioDeviceAttributes device = getAvcAudioOutputDevice();
|
||||
AudioDeviceAttributes device = getAvbAudioOutputDevice();
|
||||
if (getDeviceVolumeBehavior(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
|
||||
getAudioManager().setDeviceVolumeBehavior(device,
|
||||
AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
|
||||
@@ -4351,11 +4352,11 @@ public class HdmiControlService extends SystemService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables Absolute Volume Control. Should only be called when all the conditions for
|
||||
* AVC are met (see {@link #checkAndUpdateAbsoluteVolumeControlState}).
|
||||
* Enables absolute volume behavior. Should only be called when all the conditions for
|
||||
* AVB are met (see {@link #checkAndUpdateAbsoluteVolumeBehavior}).
|
||||
* @param audioStatus The initial audio status to set the audio output device to
|
||||
*/
|
||||
void enableAbsoluteVolumeControl(AudioStatus audioStatus) {
|
||||
void enableAbsoluteVolumeBehavior(AudioStatus audioStatus) {
|
||||
HdmiCecLocalDevice localDevice = isPlaybackDevice() ? playback() : tv();
|
||||
HdmiDeviceInfo systemAudioDevice = getHdmiCecNetwork().getDeviceInfo(
|
||||
localDevice.findAudioReceiverAddress());
|
||||
@@ -4370,9 +4371,9 @@ public class HdmiControlService extends SystemService {
|
||||
|
||||
// AudioService sets the volume of the stream and device based on the input VolumeInfo
|
||||
// when enabling absolute volume behavior, but not the mute state
|
||||
notifyAvcMuteChange(audioStatus.getMute());
|
||||
notifyAvbMuteChange(audioStatus.getMute());
|
||||
getAudioDeviceVolumeManager().setDeviceAbsoluteVolumeBehavior(
|
||||
getAvcAudioOutputDevice(), volumeInfo, mServiceThreadExecutor,
|
||||
getAvbAudioOutputDevice(), volumeInfo, mServiceThreadExecutor,
|
||||
mAbsoluteVolumeChangedListener, true);
|
||||
}
|
||||
|
||||
@@ -4418,8 +4419,8 @@ public class HdmiControlService extends SystemService {
|
||||
if (errorCode == SendMessageResult.SUCCESS) {
|
||||
// Update the volume tracked in our AbsoluteVolumeAudioStatusAction
|
||||
// so it correctly processes incoming <Report Audio Status> messages
|
||||
HdmiCecLocalDevice avcDevice = isTvDevice() ? tv() : playback();
|
||||
avcDevice.updateAvcVolume(volumeInfo.getVolumeIndex());
|
||||
HdmiCecLocalDevice avbDevice = isTvDevice() ? tv() : playback();
|
||||
avbDevice.updateAvbVolume(volumeInfo.getVolumeIndex());
|
||||
} else {
|
||||
sendCecCommand(HdmiCecMessageBuilder.buildGiveAudioStatus(
|
||||
localDeviceAddress,
|
||||
@@ -4477,13 +4478,13 @@ public class HdmiControlService extends SystemService {
|
||||
|
||||
/**
|
||||
* Notifies AudioService of a change in the volume of the System Audio device. Has no effect if
|
||||
* AVC is disabled, or the audio output device for AVC is not playing for STREAM_MUSIC
|
||||
* AVB is disabled, or the audio output device for AVB is not playing for STREAM_MUSIC
|
||||
*/
|
||||
void notifyAvcVolumeChange(int volume) {
|
||||
if (!isAbsoluteVolumeControlEnabled()) return;
|
||||
void notifyAvbVolumeChange(int volume) {
|
||||
if (!isAbsoluteVolumeBehaviorEnabled()) return;
|
||||
List<AudioDeviceAttributes> streamMusicDevices =
|
||||
getAudioManager().getDevicesForAttributes(STREAM_MUSIC_ATTRIBUTES);
|
||||
if (streamMusicDevices.contains(getAvcAudioOutputDevice())) {
|
||||
if (streamMusicDevices.contains(getAvbAudioOutputDevice())) {
|
||||
int flags = AudioManager.FLAG_ABSOLUTE_VOLUME;
|
||||
if (isTvDevice()) {
|
||||
flags |= AudioManager.FLAG_SHOW_UI;
|
||||
@@ -4494,13 +4495,13 @@ public class HdmiControlService extends SystemService {
|
||||
|
||||
/**
|
||||
* Notifies AudioService of a change in the mute status of the System Audio device. Has no
|
||||
* effect if AVC is disabled, or the audio output device for AVC is not playing for STREAM_MUSIC
|
||||
* effect if AVB is disabled, or the audio output device for AVB is not playing for STREAM_MUSIC
|
||||
*/
|
||||
void notifyAvcMuteChange(boolean mute) {
|
||||
if (!isAbsoluteVolumeControlEnabled()) return;
|
||||
void notifyAvbMuteChange(boolean mute) {
|
||||
if (!isAbsoluteVolumeBehaviorEnabled()) return;
|
||||
List<AudioDeviceAttributes> streamMusicDevices =
|
||||
getAudioManager().getDevicesForAttributes(STREAM_MUSIC_ATTRIBUTES);
|
||||
if (streamMusicDevices.contains(getAvcAudioOutputDevice())) {
|
||||
if (streamMusicDevices.contains(getAvbAudioOutputDevice())) {
|
||||
int direction = mute ? AudioManager.ADJUST_MUTE : AudioManager.ADJUST_UNMUTE;
|
||||
int flags = AudioManager.FLAG_ABSOLUTE_VOLUME;
|
||||
if (isTvDevice()) {
|
||||
|
||||
@@ -172,10 +172,10 @@ final class SendKeyAction extends HdmiCecFeatureAction {
|
||||
}
|
||||
|
||||
private void sendKeyUp() {
|
||||
// When using Absolute Volume Control, query audio status after a volume key is released.
|
||||
// When using absolute volume behavior, query audio status after a volume key is released.
|
||||
// This allows us to notify AudioService of the resulting volume or mute status changes.
|
||||
if (HdmiCecKeycode.isVolumeKeycode(mLastKeycode)
|
||||
&& localDevice().getService().isAbsoluteVolumeControlEnabled()) {
|
||||
&& localDevice().getService().isAbsoluteVolumeBehaviorEnabled()) {
|
||||
sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(getSourceAddress(),
|
||||
mTargetAddress),
|
||||
__ -> sendCommand(HdmiCecMessageBuilder.buildGiveAudioStatus(
|
||||
|
||||
@@ -90,7 +90,7 @@ public class SetAudioVolumeLevelDiscoveryAction extends HdmiCecFeatureAction {
|
||||
}
|
||||
|
||||
void handleTimerEvent(int state) {
|
||||
if (updateAvcSupport(FEATURE_SUPPORTED)) {
|
||||
if (updateSetAudioVolumeLevelSupport(FEATURE_SUPPORTED)) {
|
||||
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
|
||||
} else {
|
||||
finishWithCallback(HdmiControlManager.RESULT_EXCEPTION);
|
||||
@@ -104,7 +104,7 @@ public class SetAudioVolumeLevelDiscoveryAction extends HdmiCecFeatureAction {
|
||||
*
|
||||
* @return Whether support was successfully updated in the network.
|
||||
*/
|
||||
private boolean updateAvcSupport(
|
||||
private boolean updateSetAudioVolumeLevelSupport(
|
||||
@DeviceFeatures.FeatureSupportStatus int setAudioVolumeLevelSupport) {
|
||||
HdmiCecNetwork network = localDevice().mService.getHdmiCecNetwork();
|
||||
HdmiDeviceInfo currentDeviceInfo = network.getCecDeviceInfo(mTargetAddress);
|
||||
|
||||
@@ -68,19 +68,19 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Tests that Absolute Volume Control (AVC) is enabled and disabled correctly, and that
|
||||
* Tests that absolute volume behavior (AVB) is enabled and disabled correctly, and that
|
||||
* the device responds correctly to incoming <Report Audio Status> messages and API calls
|
||||
* from AudioService when AVC is active.
|
||||
* from AudioService when AVB is active.
|
||||
*
|
||||
* This is an abstract base class. Concrete subclasses specify the type of the local device, and the
|
||||
* type of the System Audio device. This allows each test to be run for multiple setups.
|
||||
*
|
||||
* We test the following pairs of (local device, System Audio device):
|
||||
* (Playback, TV): {@link PlaybackDeviceToTvAvcTest}
|
||||
* (Playback, Audio System): {@link PlaybackDeviceToAudioSystemAvcTest}
|
||||
* (TV, Audio System): {@link TvToAudioSystemAvcTest}
|
||||
* (Playback, TV): {@link PlaybackDeviceToTvAvbTest}
|
||||
* (Playback, Audio System): {@link PlaybackDeviceToAudioSystemAvbTest}
|
||||
* (TV, Audio System): {@link TvToAudioSystemAvbTest}
|
||||
*/
|
||||
public abstract class BaseAbsoluteVolumeControlTest {
|
||||
public abstract class BaseAbsoluteVolumeBehaviorTest {
|
||||
private HdmiControlService mHdmiControlService;
|
||||
private HdmiCecController mHdmiCecController;
|
||||
private HdmiCecLocalDevice mHdmiCecLocalDevice;
|
||||
@@ -97,12 +97,12 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
protected FakeNativeWrapper mNativeWrapper;
|
||||
|
||||
// Audio Status given by the System Audio device in its initial <Report Audio Status> that
|
||||
// triggers AVC being enabled
|
||||
// triggers AVB being enabled
|
||||
private static final AudioStatus INITIAL_SYSTEM_AUDIO_DEVICE_STATUS =
|
||||
new AudioStatus(50, false);
|
||||
|
||||
// VolumeInfo passed to AudioDeviceVolumeManager#setDeviceAbsoluteVolumeBehavior to enable AVC
|
||||
private static final VolumeInfo ENABLE_AVC_VOLUME_INFO =
|
||||
// VolumeInfo passed to AudioDeviceVolumeManager#setDeviceAbsoluteVolumeBehavior to enable AVB
|
||||
private static final VolumeInfo ENABLE_AVB_VOLUME_INFO =
|
||||
new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
|
||||
.setMuted(INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute())
|
||||
.setVolumeIndex(INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume())
|
||||
@@ -300,9 +300,9 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers all the conditions required to enable Absolute Volume Control.
|
||||
* Triggers all the conditions required to enable absolute volume behavior.
|
||||
*/
|
||||
protected void enableAbsoluteVolumeControl() {
|
||||
protected void enableAbsoluteVolumeBehavior() {
|
||||
setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
|
||||
setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
|
||||
receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
|
||||
@@ -313,8 +313,8 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that AVC was enabled - that is the audio output device's volume behavior was last
|
||||
* set to absolute volume behavior.
|
||||
* Verifies that the audio output device's volume behavior was last set to
|
||||
* absolute volume behavior.
|
||||
*/
|
||||
protected void verifyAbsoluteVolumeEnabled() {
|
||||
InOrder inOrder = inOrder(mAudioManager, mAudioDeviceVolumeManager);
|
||||
@@ -325,8 +325,8 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that AVC was disabled - that is, the audio output device's volume behavior was
|
||||
* last set to something other than absolute volume behavior.
|
||||
* Verifies that the audio output device's volume behavior was last set to something other than
|
||||
* absolute volume behavior.
|
||||
*/
|
||||
protected void verifyAbsoluteVolumeDisabled() {
|
||||
InOrder inOrder = inOrder(mAudioManager, mAudioDeviceVolumeManager);
|
||||
@@ -423,13 +423,13 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giveAudioStatusSent_systemAudioDeviceSendsReportAudioStatus_avcEnabled() {
|
||||
public void giveAudioStatusSent_systemAudioDeviceSendsReportAudioStatus_avbEnabled() {
|
||||
setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
|
||||
enableSystemAudioModeIfNeeded();
|
||||
receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
|
||||
setDeviceVolumeBehavior(getAudioOutputDevice(), AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
|
||||
|
||||
// Verify that AVC was never enabled
|
||||
// Verify that AVB was never enabled
|
||||
verify(mAudioDeviceVolumeManager, never()).setDeviceAbsoluteVolumeBehavior(
|
||||
eq(getAudioOutputDevice()), any(), any(), any(), anyBoolean());
|
||||
receiveInitialReportAudioStatus();
|
||||
@@ -438,7 +438,7 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giveAudioStatusSent_reportAudioStatusVolumeOutOfBounds_avcNotEnabled() {
|
||||
public void giveAudioStatusSent_reportAudioStatusVolumeOutOfBounds_avbNotEnabled() {
|
||||
mAudioManager.setDeviceVolumeBehavior(getAudioOutputDevice(),
|
||||
AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
|
||||
setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
|
||||
@@ -453,24 +453,24 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void avcEnabled_cecVolumeDisabled_absoluteVolumeDisabled() {
|
||||
enableAbsoluteVolumeControl();
|
||||
public void avbEnabled_cecVolumeDisabled_avbDisabled() {
|
||||
enableAbsoluteVolumeBehavior();
|
||||
|
||||
setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_DISABLED);
|
||||
verifyAbsoluteVolumeDisabled();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void avcEnabled_setAudioVolumeLevelNotSupported_absoluteVolumeDisabled() {
|
||||
enableAbsoluteVolumeControl();
|
||||
public void avbEnabled_setAudioVolumeLevelNotSupported_avbDisabled() {
|
||||
enableAbsoluteVolumeBehavior();
|
||||
|
||||
receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_NOT_SUPPORTED);
|
||||
verifyAbsoluteVolumeDisabled();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void avcEnabled_setAudioVolumeLevelFeatureAborted_absoluteVolumeDisabled() {
|
||||
enableAbsoluteVolumeControl();
|
||||
public void avbEnabled_setAudioVolumeLevelFeatureAborted_avbDisabled() {
|
||||
enableAbsoluteVolumeBehavior();
|
||||
|
||||
mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
getSystemAudioDeviceLogicalAddress(), getLogicalAddress(),
|
||||
@@ -480,20 +480,20 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void avcEnabled_systemAudioModeDisabled_absoluteVolumeDisabled() {
|
||||
public void avbEnabled_systemAudioModeDisabled_avbDisabled() {
|
||||
// Only run when the System Audio device is an Audio System.
|
||||
assume().that(getSystemAudioDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
|
||||
enableAbsoluteVolumeControl();
|
||||
enableAbsoluteVolumeBehavior();
|
||||
|
||||
receiveSetSystemAudioMode(false);
|
||||
verifyAbsoluteVolumeDisabled();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void avcEnabled_receiveReportAudioStatus_notifiesVolumeOrMuteChanges() {
|
||||
public void avbEnabled_receiveReportAudioStatus_notifiesVolumeOrMuteChanges() {
|
||||
// Initial <Report Audio Status> has volume=50 and mute=false
|
||||
enableAbsoluteVolumeControl();
|
||||
enableAbsoluteVolumeBehavior();
|
||||
|
||||
// New volume and mute status: sets both
|
||||
receiveReportAudioStatus(20, true);
|
||||
@@ -540,7 +540,7 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
// still cause us to call setStreamVolume()
|
||||
mHdmiControlService.getAbsoluteVolumeChangedListener().onAudioDeviceVolumeChanged(
|
||||
getAudioOutputDevice(),
|
||||
new VolumeInfo.Builder(ENABLE_AVC_VOLUME_INFO)
|
||||
new VolumeInfo.Builder(ENABLE_AVB_VOLUME_INFO)
|
||||
.setVolumeIndex(20)
|
||||
.build()
|
||||
);
|
||||
@@ -553,13 +553,13 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void avcEnabled_audioDeviceVolumeAdjusted_sendsUserControlPressedAndGiveAudioStatus() {
|
||||
enableAbsoluteVolumeControl();
|
||||
public void avbEnabled_audioDeviceVolumeAdjusted_sendsUserControlPressedAndGiveAudioStatus() {
|
||||
enableAbsoluteVolumeBehavior();
|
||||
mNativeWrapper.clearResultMessages();
|
||||
|
||||
mHdmiControlService.getAbsoluteVolumeChangedListener().onAudioDeviceVolumeAdjusted(
|
||||
getAudioOutputDevice(),
|
||||
ENABLE_AVC_VOLUME_INFO,
|
||||
ENABLE_AVB_VOLUME_INFO,
|
||||
AudioManager.ADJUST_RAISE,
|
||||
AudioDeviceVolumeManager.ADJUST_MODE_NORMAL
|
||||
);
|
||||
@@ -577,13 +577,13 @@ public abstract class BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void avcEnabled_audioDeviceVolumeChanged_sendsSetAudioVolumeLevel() {
|
||||
enableAbsoluteVolumeControl();
|
||||
public void avbEnabled_audioDeviceVolumeChanged_sendsSetAudioVolumeLevel() {
|
||||
enableAbsoluteVolumeBehavior();
|
||||
mNativeWrapper.clearResultMessages();
|
||||
|
||||
mHdmiControlService.getAbsoluteVolumeChangedListener().onAudioDeviceVolumeChanged(
|
||||
getAudioOutputDevice(),
|
||||
new VolumeInfo.Builder(ENABLE_AVC_VOLUME_INFO)
|
||||
new VolumeInfo.Builder(ENABLE_AVB_VOLUME_INFO)
|
||||
.setVolumeIndex(20)
|
||||
.build()
|
||||
);
|
||||
@@ -33,13 +33,13 @@ import org.junit.runners.JUnit4;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Tests for Absolute Volume Control where the local device is a Playback device and the
|
||||
* Tests for absolute volume behavior where the local device is a Playback device and the
|
||||
* System Audio device is an Audio System.
|
||||
*/
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@RunWith(JUnit4.class)
|
||||
public class PlaybackDeviceToAudioSystemAvcTest extends BaseAbsoluteVolumeControlTest {
|
||||
public class PlaybackDeviceToAudioSystemAvbTest extends BaseAbsoluteVolumeBehaviorTest {
|
||||
|
||||
@Override
|
||||
protected HdmiCecLocalDevice createLocalDevice(HdmiControlService hdmiControlService) {
|
||||
@@ -72,15 +72,15 @@ public class PlaybackDeviceToAudioSystemAvcTest extends BaseAbsoluteVolumeContro
|
||||
}
|
||||
|
||||
/**
|
||||
* AVC is disabled if the Audio System disables System Audio mode, and the TV has unknown
|
||||
* AVB is disabled if the Audio System disables System Audio mode, and the TV has unknown
|
||||
* support for <Set Audio Volume Level>. It is enabled once the TV confirms support for
|
||||
* <Set Audio Volume Level> and sends <Report Audio Status>.
|
||||
*/
|
||||
@Test
|
||||
public void switchToTv_absoluteVolumeControlDisabledUntilAllConditionsMet() {
|
||||
enableAbsoluteVolumeControl();
|
||||
enableAbsoluteVolumeBehavior();
|
||||
|
||||
// Audio System disables System Audio Mode. AVC should be disabled.
|
||||
// Audio System disables System Audio Mode. AVB should be disabled.
|
||||
receiveSetSystemAudioMode(false);
|
||||
verifyAbsoluteVolumeDisabled();
|
||||
|
||||
@@ -34,13 +34,13 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Tests for Absolute Volume Control where the local device is a Playback device and the
|
||||
* Tests for absolute volume behavior where the local device is a Playback device and the
|
||||
* System Audio device is a TV.
|
||||
*/
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@RunWith(JUnit4.class)
|
||||
public class PlaybackDeviceToTvAvcTest extends BaseAbsoluteVolumeControlTest {
|
||||
public class PlaybackDeviceToTvAvbTest extends BaseAbsoluteVolumeBehaviorTest {
|
||||
|
||||
@Override
|
||||
protected HdmiCecLocalDevice createLocalDevice(HdmiControlService hdmiControlService) {
|
||||
@@ -73,15 +73,15 @@ public class PlaybackDeviceToTvAvcTest extends BaseAbsoluteVolumeControlTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* AVC is disabled when an Audio System with unknown support for <Set Audio Volume Level>
|
||||
* AVB is disabled when an Audio System with unknown support for <Set Audio Volume Level>
|
||||
* becomes the System Audio device. It is enabled once the Audio System reports that it
|
||||
* supports <Set Audio Volume Level> and sends <Report Audio Status>.
|
||||
*/
|
||||
@Test
|
||||
public void switchToAudioSystem_absoluteVolumeControlDisabledUntilAllConditionsMet() {
|
||||
enableAbsoluteVolumeControl();
|
||||
enableAbsoluteVolumeBehavior();
|
||||
|
||||
// Audio System enables System Audio Mode. AVC should be disabled.
|
||||
// Audio System enables System Audio Mode. AVB should be disabled.
|
||||
receiveSetSystemAudioMode(true);
|
||||
verifyAbsoluteVolumeDisabled();
|
||||
|
||||
@@ -152,11 +152,11 @@ public class SetAudioVolumeLevelDiscoveryActionTest {
|
||||
mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
@DeviceFeatures.FeatureSupportStatus int avcSupport =
|
||||
@DeviceFeatures.FeatureSupportStatus int savlSupport =
|
||||
mHdmiControlServiceSpy.getHdmiCecNetwork().getCecDeviceInfo(Constants.ADDR_TV)
|
||||
.getDeviceFeatures().getSetAudioVolumeLevelSupport();
|
||||
|
||||
assertThat(avcSupport).isEqualTo(FEATURE_SUPPORTED);
|
||||
assertThat(savlSupport).isEqualTo(FEATURE_SUPPORTED);
|
||||
assertThat(mTestCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -172,11 +172,11 @@ public class SetAudioVolumeLevelDiscoveryActionTest {
|
||||
Constants.ABORT_UNRECOGNIZED_OPCODE));
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
@DeviceFeatures.FeatureSupportStatus int avcSupport =
|
||||
@DeviceFeatures.FeatureSupportStatus int savlSupport =
|
||||
mHdmiControlServiceSpy.getHdmiCecNetwork().getCecDeviceInfo(Constants.ADDR_TV)
|
||||
.getDeviceFeatures().getSetAudioVolumeLevelSupport();
|
||||
|
||||
assertThat(avcSupport).isEqualTo(FEATURE_NOT_SUPPORTED);
|
||||
assertThat(savlSupport).isEqualTo(FEATURE_NOT_SUPPORTED);
|
||||
assertThat(mTestCallback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -189,11 +189,11 @@ public class SetAudioVolumeLevelDiscoveryActionTest {
|
||||
mPlaybackDevice.addAndStartAction(mAction);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
@DeviceFeatures.FeatureSupportStatus int avcSupport =
|
||||
@DeviceFeatures.FeatureSupportStatus int savlSupport =
|
||||
mHdmiControlServiceSpy.getHdmiCecNetwork().getCecDeviceInfo(Constants.ADDR_TV)
|
||||
.getDeviceFeatures().getSetAudioVolumeLevelSupport();
|
||||
|
||||
assertThat(avcSupport).isEqualTo(FEATURE_SUPPORT_UNKNOWN);
|
||||
assertThat(savlSupport).isEqualTo(FEATURE_SUPPORT_UNKNOWN);
|
||||
assertThat(mTestCallback.getResult()).isEqualTo(
|
||||
HdmiControlManager.RESULT_COMMUNICATION_FAILED);
|
||||
}
|
||||
|
||||
@@ -26,13 +26,13 @@ import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/**
|
||||
* Tests for Absolute Volume Control where the local device is a TV and the System Audio device
|
||||
* Tests for absolute volume behavior where the local device is a TV and the System Audio device
|
||||
* is an Audio System. Assumes that the TV uses ARC (rather than eARC).
|
||||
*/
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@RunWith(JUnit4.class)
|
||||
public class TvToAudioSystemAvcTest extends BaseAbsoluteVolumeControlTest {
|
||||
public class TvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehaviorTest {
|
||||
|
||||
@Override
|
||||
protected HdmiCecLocalDevice createLocalDevice(HdmiControlService hdmiControlService) {
|
||||
Reference in New Issue
Block a user