Merge "CEC: Make HDMI CEC volume control configurable" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
77576fe964
@@ -649,6 +649,68 @@ public final class HdmiControlManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether volume control commands via HDMI CEC are enabled.
|
||||
*
|
||||
* <p>When disabled:
|
||||
* <ul>
|
||||
* <li>the device will not send any HDMI CEC audio messages
|
||||
* <li>received HDMI CEC audio messages are responded to with {@code <Feature Abort>}
|
||||
* </ul>
|
||||
*
|
||||
* <p>Effects on different device types:
|
||||
* <table>
|
||||
* <tr><th>HDMI CEC device type</th><th>enabled</th><th>disabled</th></tr>
|
||||
* <tr>
|
||||
* <td>TV (type: 0)</td>
|
||||
* <td>Per CEC specification.</td>
|
||||
* <td>TV changes system volume. TV no longer reacts to incoming volume changes via
|
||||
* {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio Status>}
|
||||
* .</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Playback device (type: 4)</td>
|
||||
* <td>Device sends volume commands to TV/Audio system via {@code <User Control
|
||||
* Pressed>}</td><td>Device does not send volume commands via {@code <User Control
|
||||
* Pressed>}.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Audio device (type: 5)</td>
|
||||
* <td>Full "System Audio Control" capabilities.</td>
|
||||
* <td>Audio device no longer reacts to incoming {@code <User Control Pressed>}
|
||||
* volume commands. Audio device no longer reports volume changes via {@code <Report
|
||||
* Audio Status>}.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged.
|
||||
*
|
||||
* @param isHdmiCecVolumeControlEnabled target state of HDMI CEC volume control.
|
||||
* @see Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||||
public void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) {
|
||||
try {
|
||||
mService.setHdmiCecVolumeControlEnabled(isHdmiCecVolumeControlEnabled);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether volume changes via HDMI CEC are enabled.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||||
public boolean isHdmiCecVolumeControlEnabled() {
|
||||
try {
|
||||
return mService.isHdmiCecVolumeControlEnabled();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the system is in system audio mode.
|
||||
*
|
||||
|
||||
@@ -80,6 +80,8 @@ interface IHdmiControlService {
|
||||
void sendMhlVendorCommand(int portId, int offset, int length, in byte[] data);
|
||||
void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener);
|
||||
void setStandbyMode(boolean isStandbyModeOn);
|
||||
void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled);
|
||||
boolean isHdmiCecVolumeControlEnabled();
|
||||
void reportAudioStatus(int deviceType, int volume, int maxVolume, boolean isMute);
|
||||
void setSystemAudioModeOnForAudioOnlySource();
|
||||
}
|
||||
|
||||
@@ -9614,6 +9614,43 @@ public final class Settings {
|
||||
*/
|
||||
public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
|
||||
|
||||
/**
|
||||
* Controls whether volume control commands via HDMI CEC are enabled. (0 = false, 1 =
|
||||
* true).
|
||||
*
|
||||
* <p>Effects on different device types:
|
||||
* <table>
|
||||
* <tr><th>HDMI CEC device type</th><th>0: disabled</th><th>1: enabled</th></tr>
|
||||
* <tr>
|
||||
* <td>TV (type: 0)</td>
|
||||
* <td>Per CEC specification.</td>
|
||||
* <td>TV changes system volume. TV no longer reacts to incoming volume changes
|
||||
* via {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio
|
||||
* Status>}.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Playback device (type: 4)</td>
|
||||
* <td>Device sends volume commands to TV/Audio system via {@code <User Control
|
||||
* Pressed>}</td>
|
||||
* <td>Device does not send volume commands via {@code <User Control Pressed>}.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Audio device (type: 5)</td>
|
||||
* <td>Full "System Audio Control" capabilities.</td>
|
||||
* <td>Audio device no longer reacts to incoming {@code <User Control Pressed>}
|
||||
* volume commands. Audio device no longer reports volume changes via {@code
|
||||
* <Report Audio Status>}.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged.
|
||||
*
|
||||
* @hide
|
||||
* @see android.hardware.hdmi.HdmiControlManager#setHdmiCecVolumeControlEnabled(boolean)
|
||||
*/
|
||||
public static final String HDMI_CONTROL_VOLUME_CONTROL_ENABLED =
|
||||
"hdmi_control_volume_control_enabled";
|
||||
|
||||
/**
|
||||
* Whether HDMI System Audio Control feature is enabled. If enabled, TV will try to turn on
|
||||
* system audio mode if there's a connected CEC-enabled AV Receiver. Then audio stream will
|
||||
|
||||
@@ -354,6 +354,15 @@ public class HdmiAudioSystemClientTest {
|
||||
@Override
|
||||
public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHdmiCecVolumeControlEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -296,6 +296,7 @@ public class SettingsBackupTest {
|
||||
Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
|
||||
Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
|
||||
Settings.Global.HDMI_CONTROL_ENABLED,
|
||||
Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
|
||||
Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
|
||||
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
|
||||
Settings.Global.HIDDEN_API_POLICY,
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.server.hdmi.Constants.LocalActivePort;
|
||||
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
|
||||
@@ -144,7 +145,8 @@ abstract class HdmiCecLocalDevice {
|
||||
|
||||
// A collection of FeatureAction.
|
||||
// Note that access to this collection should happen in service thread.
|
||||
private final ArrayList<HdmiCecFeatureAction> mActions = new ArrayList<>();
|
||||
@VisibleForTesting
|
||||
final ArrayList<HdmiCecFeatureAction> mActions = new ArrayList<>();
|
||||
|
||||
private final Handler mHandler =
|
||||
new Handler() {
|
||||
@@ -544,6 +546,8 @@ abstract class HdmiCecLocalDevice {
|
||||
} else if (mService.isPowerStandbyOrTransient() && isPowerOnOrToggleCommand(message)) {
|
||||
mService.wakeUp();
|
||||
return true;
|
||||
} else if (!mService.isHdmiCecVolumeControlEnabled() && isVolumeOrMuteCommand(message)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final long downTime = SystemClock.uptimeMillis();
|
||||
@@ -618,6 +622,16 @@ abstract class HdmiCecLocalDevice {
|
||||
|| params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION);
|
||||
}
|
||||
|
||||
static boolean isVolumeOrMuteCommand(HdmiCecMessage message) {
|
||||
byte[] params = message.getParams();
|
||||
return message.getOpcode() == Constants.MESSAGE_USER_CONTROL_PRESSED
|
||||
&& (params[0] == HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN
|
||||
|| params[0] == HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP
|
||||
|| params[0] == HdmiCecKeycode.CEC_KEYCODE_MUTE
|
||||
|| params[0] == HdmiCecKeycode.CEC_KEYCODE_MUTE_FUNCTION
|
||||
|| params[0] == HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION);
|
||||
}
|
||||
|
||||
protected boolean handleTextViewOn(HdmiCecMessage message) {
|
||||
return false;
|
||||
}
|
||||
@@ -1038,6 +1052,9 @@ abstract class HdmiCecLocalDevice {
|
||||
@ServiceThreadOnly
|
||||
protected void sendVolumeKeyEvent(int keyCode, boolean isPressed) {
|
||||
assertRunOnServiceThread();
|
||||
if (!mService.isHdmiCecVolumeControlEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (!HdmiCecKeycode.isVolumeKeycode(keyCode)) {
|
||||
Slog.w(TAG, "Not a volume key: " + keyCode);
|
||||
return;
|
||||
|
||||
@@ -575,7 +575,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
@ServiceThreadOnly
|
||||
protected boolean handleGiveAudioStatus(HdmiCecMessage message) {
|
||||
assertRunOnServiceThread();
|
||||
if (isSystemAudioControlFeatureEnabled()) {
|
||||
if (isSystemAudioControlFeatureEnabled() && mService.isHdmiCecVolumeControlEnabled()) {
|
||||
reportAudioStatus(message.getSource());
|
||||
} else {
|
||||
mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
|
||||
@@ -930,6 +930,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
|
||||
void reportAudioStatus(int source) {
|
||||
assertRunOnServiceThread();
|
||||
if (!mService.isHdmiCecVolumeControlEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int volume = mService.getAudioManager().getStreamVolume(AudioManager.STREAM_MUSIC);
|
||||
boolean mute = mService.getAudioManager().isStreamMute(AudioManager.STREAM_MUSIC);
|
||||
|
||||
@@ -678,6 +678,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
@ServiceThreadOnly
|
||||
protected boolean handleReportAudioStatus(HdmiCecMessage message) {
|
||||
assertRunOnServiceThread();
|
||||
if (!mService.isHdmiCecVolumeControlEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean mute = HdmiUtils.isAudioStatusMute(message);
|
||||
int volume = HdmiUtils.getAudioStatusVolume(message);
|
||||
@@ -987,7 +990,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
}
|
||||
|
||||
void setAudioStatus(boolean mute, int volume) {
|
||||
if (!isSystemAudioActivated()) {
|
||||
if (!isSystemAudioActivated() || !mService.isHdmiCecVolumeControlEnabled()) {
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
@@ -1009,7 +1012,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
// On initialization process, getAvrDeviceInfo() may return null and cause exception
|
||||
return;
|
||||
}
|
||||
if (delta == 0 || !isSystemAudioActivated()) {
|
||||
if (delta == 0 || !isSystemAudioActivated() || !mService.isHdmiCecVolumeControlEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1038,7 +1041,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
|
||||
@ServiceThreadOnly
|
||||
void changeMute(boolean mute) {
|
||||
assertRunOnServiceThread();
|
||||
if (getAvrDeviceInfo() == null) {
|
||||
if (getAvrDeviceInfo() == null || !mService.isHdmiCecVolumeControlEnabled()) {
|
||||
// On initialization process, getAvrDeviceInfo() may return null and cause exception
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -177,6 +177,10 @@ public class HdmiControlService extends SystemService {
|
||||
@GuardedBy("mLock")
|
||||
protected final ActiveSource mActiveSource = new ActiveSource();
|
||||
|
||||
// Whether HDMI CEC volume control is enabled or not.
|
||||
@GuardedBy("mLock")
|
||||
private boolean mHdmiCecVolumeControlEnabled;
|
||||
|
||||
// Whether System Audio Mode is activated or not.
|
||||
@GuardedBy("mLock")
|
||||
private boolean mSystemAudioActivated = false;
|
||||
@@ -497,6 +501,8 @@ public class HdmiControlService extends SystemService {
|
||||
mPowerStatus = getInitialPowerStatus();
|
||||
mProhibitMode = false;
|
||||
mHdmiControlEnabled = readBooleanSetting(Global.HDMI_CONTROL_ENABLED, true);
|
||||
mHdmiCecVolumeControlEnabled = readBooleanSetting(
|
||||
Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, true);
|
||||
mMhlInputChangeEnabled = readBooleanSetting(Global.MHL_INPUT_SWITCHING_ENABLED, true);
|
||||
|
||||
if (mCecController == null) {
|
||||
@@ -646,6 +652,7 @@ public class HdmiControlService extends SystemService {
|
||||
ContentResolver resolver = getContext().getContentResolver();
|
||||
String[] settings = new String[] {
|
||||
Global.HDMI_CONTROL_ENABLED,
|
||||
Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
|
||||
Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
|
||||
Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
|
||||
Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
|
||||
@@ -674,6 +681,9 @@ public class HdmiControlService extends SystemService {
|
||||
case Global.HDMI_CONTROL_ENABLED:
|
||||
setControlEnabled(enabled);
|
||||
break;
|
||||
case Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED:
|
||||
setHdmiCecVolumeControlEnabled(enabled);
|
||||
break;
|
||||
case Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED:
|
||||
if (isTvDeviceEnabled()) {
|
||||
tv().setAutoWakeup(enabled);
|
||||
@@ -1273,7 +1283,9 @@ public class HdmiControlService extends SystemService {
|
||||
}
|
||||
|
||||
void setAudioStatus(boolean mute, int volume) {
|
||||
if (!isTvDeviceEnabled() || !tv().isSystemAudioActivated()) {
|
||||
if (!isTvDeviceEnabled()
|
||||
|| !tv().isSystemAudioActivated()
|
||||
|| !isHdmiCecVolumeControlEnabled()) {
|
||||
return;
|
||||
}
|
||||
AudioManager audioManager = getAudioManager();
|
||||
@@ -2186,6 +2198,24 @@ public class HdmiControlService extends SystemService {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHdmiCecVolumeControlEnabled() {
|
||||
enforceAccessPermission();
|
||||
return HdmiControlService.this.isHdmiCecVolumeControlEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHdmiCecVolumeControlEnabled(final boolean isHdmiCecVolumeControlEnabled) {
|
||||
enforceAccessPermission();
|
||||
runOnServiceThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
HdmiControlService.this.setHdmiCecVolumeControlEnabled(
|
||||
isHdmiCecVolumeControlEnabled);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAudioStatus(final int deviceType, final int volume, final int maxVolume,
|
||||
final boolean isMute) {
|
||||
@@ -2250,6 +2280,7 @@ public class HdmiControlService extends SystemService {
|
||||
pw.println("mHdmiControlEnabled: " + mHdmiControlEnabled);
|
||||
pw.println("mMhlInputChangeEnabled: " + mMhlInputChangeEnabled);
|
||||
pw.println("mSystemAudioActivated: " + isSystemAudioActivated());
|
||||
pw.println("mHdmiCecVolumeControlEnabled " + mHdmiCecVolumeControlEnabled);
|
||||
pw.decreaseIndent();
|
||||
|
||||
pw.println("mMhlController: ");
|
||||
@@ -2982,6 +3013,29 @@ public class HdmiControlService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
void setHdmiCecVolumeControlEnabled(boolean isHdmiCecVolumeControlEnabled) {
|
||||
assertRunOnServiceThread();
|
||||
synchronized (mLock) {
|
||||
mHdmiCecVolumeControlEnabled = isHdmiCecVolumeControlEnabled;
|
||||
|
||||
boolean storedValue = readBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
|
||||
true);
|
||||
if (storedValue != isHdmiCecVolumeControlEnabled) {
|
||||
HdmiLogger.debug("Changing HDMI CEC volume control feature state: %s",
|
||||
isHdmiCecVolumeControlEnabled);
|
||||
writeBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
|
||||
isHdmiCecVolumeControlEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isHdmiCecVolumeControlEnabled() {
|
||||
assertRunOnServiceThread();
|
||||
synchronized (mLock) {
|
||||
return mHdmiCecVolumeControlEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isProhibitMode() {
|
||||
synchronized (mLock) {
|
||||
return mProhibitMode;
|
||||
@@ -3022,8 +3076,12 @@ public class HdmiControlService extends SystemService {
|
||||
|
||||
if (enabled) {
|
||||
enableHdmiControlService();
|
||||
setHdmiCecVolumeControlEnabled(
|
||||
readBooleanSetting(Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED, true));
|
||||
return;
|
||||
}
|
||||
|
||||
setHdmiCecVolumeControlEnabled(false);
|
||||
// Call the vendor handler before the service is disabled.
|
||||
invokeVendorCommandListenersOnControlStateChanged(false,
|
||||
HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING);
|
||||
|
||||
@@ -24,6 +24,7 @@ import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
|
||||
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2;
|
||||
import static com.android.server.hdmi.Constants.ADDR_TUNER_1;
|
||||
import static com.android.server.hdmi.Constants.ADDR_TV;
|
||||
import static com.android.server.hdmi.Constants.MESSAGE_GIVE_AUDIO_STATUS;
|
||||
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
|
||||
import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF;
|
||||
|
||||
@@ -47,6 +48,7 @@ import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(JUnit4.class)
|
||||
/** Tests for {@link HdmiCecLocalDeviceAudioSystem} class. */
|
||||
@@ -167,6 +169,8 @@ public class HdmiCecLocalDeviceAudioSystemTest {
|
||||
}
|
||||
};
|
||||
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
|
||||
mMyLooper = mTestLooper.getLooper();
|
||||
mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService);
|
||||
mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
|
||||
@@ -717,4 +721,112 @@ public class HdmiCecLocalDeviceAudioSystemTest {
|
||||
mHdmiCecLocalDeviceAudioSystem.onHotplug(0, false);
|
||||
assertThat(mWokenUp).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giveAudioStatus_volumeEnabled() {
|
||||
mMusicVolume = 50;
|
||||
mMusicMaxVolume = 100;
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true);
|
||||
|
||||
int volume = mHdmiControlService.getAudioManager()
|
||||
.getStreamVolume(AudioManager.STREAM_MUSIC);
|
||||
boolean mute = mHdmiControlService.getAudioManager()
|
||||
.isStreamMute(AudioManager.STREAM_MUSIC);
|
||||
int maxVolume = mHdmiControlService.getAudioManager()
|
||||
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
|
||||
int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
|
||||
HdmiCecMessage expected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV, scaledVolume, mute);
|
||||
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
ADDR_AUDIO_SYSTEM, ADDR_TV, MESSAGE_GIVE_AUDIO_STATUS, Constants.ABORT_REFUSED);
|
||||
|
||||
HdmiCecMessage giveAudioStatus = HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
mNativeWrapper.clearResultMessages();
|
||||
boolean handled = mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(expected);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort);
|
||||
assertThat(handled).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giveAudioStatus_volumeDisabled() {
|
||||
mMusicVolume = 50;
|
||||
mMusicMaxVolume = 100;
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true);
|
||||
|
||||
int volume = mHdmiControlService.getAudioManager()
|
||||
.getStreamVolume(AudioManager.STREAM_MUSIC);
|
||||
boolean mute = mHdmiControlService.getAudioManager()
|
||||
.isStreamMute(AudioManager.STREAM_MUSIC);
|
||||
int maxVolume = mHdmiControlService.getAudioManager()
|
||||
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
|
||||
int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
|
||||
HdmiCecMessage unexpected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV, scaledVolume, mute);
|
||||
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
|
||||
ADDR_AUDIO_SYSTEM, ADDR_TV, MESSAGE_GIVE_AUDIO_STATUS, Constants.ABORT_REFUSED);
|
||||
|
||||
HdmiCecMessage giveAudioStatus = HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV,
|
||||
ADDR_AUDIO_SYSTEM);
|
||||
mNativeWrapper.clearResultMessages();
|
||||
boolean handled = mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(giveAudioStatus);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected);
|
||||
assertThat(handled).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reportAudioStatus_volumeEnabled() {
|
||||
mMusicVolume = 50;
|
||||
mMusicMaxVolume = 100;
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true);
|
||||
|
||||
int volume = mHdmiControlService.getAudioManager()
|
||||
.getStreamVolume(AudioManager.STREAM_MUSIC);
|
||||
boolean mute = mHdmiControlService.getAudioManager()
|
||||
.isStreamMute(AudioManager.STREAM_MUSIC);
|
||||
int maxVolume = mHdmiControlService.getAudioManager()
|
||||
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
|
||||
int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
|
||||
HdmiCecMessage expected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV, scaledVolume, mute);
|
||||
|
||||
mNativeWrapper.clearResultMessages();
|
||||
mHdmiCecLocalDeviceAudioSystem.reportAudioStatus(ADDR_TV);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reportAudioStatus_volumeDisabled() {
|
||||
mMusicVolume = 50;
|
||||
mMusicMaxVolume = 100;
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
mHdmiCecLocalDeviceAudioSystem.setSystemAudioControlFeatureEnabled(true);
|
||||
|
||||
int volume = mHdmiControlService.getAudioManager()
|
||||
.getStreamVolume(AudioManager.STREAM_MUSIC);
|
||||
boolean mute = mHdmiControlService.getAudioManager()
|
||||
.isStreamMute(AudioManager.STREAM_MUSIC);
|
||||
int maxVolume = mHdmiControlService.getAudioManager()
|
||||
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
|
||||
int scaledVolume = VolumeControlAction.scaleToCecVolume(volume, maxVolume);
|
||||
HdmiCecMessage unexpected = HdmiCecMessageBuilder.buildReportAudioStatus(ADDR_AUDIO_SYSTEM,
|
||||
ADDR_TV, scaledVolume, mute);
|
||||
|
||||
mNativeWrapper.clearResultMessages();
|
||||
mHdmiCecLocalDeviceAudioSystem.reportAudioStatus(ADDR_TV);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.os.test.TestLooper;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -153,4 +154,75 @@ public class HdmiCecLocalDevicePlaybackTest {
|
||||
mHdmiCecLocalDevicePlayback.onHotplug(0, false);
|
||||
assertThat(mWokenUp).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("b/151147315")
|
||||
public void sendVolumeKeyEvent_up_volumeEnabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
|
||||
|
||||
assertThat(hasSendKeyAction()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("b/151147315")
|
||||
public void sendVolumeKeyEvent_down_volumeEnabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, false);
|
||||
|
||||
assertThat(hasSendKeyAction()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("b/151147315")
|
||||
public void sendVolumeKeyEvent_mute_volumeEnabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, false);
|
||||
|
||||
assertThat(hasSendKeyAction()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("b/151147315")
|
||||
public void sendVolumeKeyEvent_up_volumeDisabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_UP, false);
|
||||
|
||||
assertThat(hasSendKeyAction()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("b/151147315")
|
||||
public void sendVolumeKeyEvent_down_volumeDisabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_DOWN, false);
|
||||
|
||||
assertThat(hasSendKeyAction()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("b/151147315")
|
||||
public void sendVolumeKeyEvent_mute_volumeDisabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, true);
|
||||
mHdmiCecLocalDevicePlayback.sendVolumeKeyEvent(KeyEvent.KEYCODE_VOLUME_MUTE, false);
|
||||
|
||||
assertThat(hasSendKeyAction()).isFalse();
|
||||
}
|
||||
|
||||
private boolean hasSendKeyAction() {
|
||||
boolean match = false;
|
||||
for (HdmiCecFeatureAction action : mHdmiCecLocalDevicePlayback.mActions) {
|
||||
if (action instanceof SendKeyAction) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
|
||||
|
||||
import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
|
||||
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
|
||||
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
|
||||
import static com.android.server.hdmi.Constants.ADDR_TV;
|
||||
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
|
||||
import static com.android.server.hdmi.Constants.MESSAGE_DEVICE_VENDOR_ID;
|
||||
@@ -185,4 +186,64 @@ public class HdmiCecLocalDeviceTest {
|
||||
HdmiCecMessageBuilder.buildStandby(ADDR_TV, ADDR_AUDIO_SYSTEM));
|
||||
assertTrue(mStandbyMessageReceived);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUserControlPressed_volumeUp() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
boolean result = mHdmiLocalDevice.handleUserControlPressed(
|
||||
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
|
||||
HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP));
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUserControlPressed_volumeDown() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
boolean result = mHdmiLocalDevice.handleUserControlPressed(
|
||||
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
|
||||
HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN));
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUserControlPressed_volumeMute() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
boolean result = mHdmiLocalDevice.handleUserControlPressed(
|
||||
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
|
||||
HdmiCecKeycode.CEC_KEYCODE_MUTE));
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUserControlPressed_volumeUp_disabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
boolean result = mHdmiLocalDevice.handleUserControlPressed(
|
||||
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
|
||||
HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP));
|
||||
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUserControlPressed_volumeDown_disabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
boolean result = mHdmiLocalDevice.handleUserControlPressed(
|
||||
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
|
||||
HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN));
|
||||
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUserControlPressed_volumeMute_disabled() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
boolean result = mHdmiLocalDevice.handleUserControlPressed(
|
||||
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_PLAYBACK_1, ADDR_TV,
|
||||
HdmiCecKeycode.CEC_KEYCODE_MUTE));
|
||||
|
||||
assertFalse(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,4 +252,13 @@ public class HdmiControlServiceTest {
|
||||
assertThat(mHdmiControlService.getPowerStatus()).isEqualTo(
|
||||
HdmiControlManager.POWER_STATUS_STANDBY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetCecVolumeControlEnabled_isApi() {
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(false);
|
||||
assertThat(mHdmiControlService.isHdmiCecVolumeControlEnabled()).isFalse();
|
||||
|
||||
mHdmiControlService.setHdmiCecVolumeControlEnabled(true);
|
||||
assertThat(mHdmiControlService.isHdmiCecVolumeControlEnabled()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user