Block new ARC connections during eARC connection

If eARC is disabled or not supported, ARC gets connected normally.

Test: atest
Bug: 262573690
Change-Id: I5c3d172f313c9457e3debe4d35ba6308f221b740
This commit is contained in:
Nathalie Le Clair
2022-10-05 13:59:48 +02:00
parent 8658ee82b3
commit 5023f01270
5 changed files with 354 additions and 29 deletions

View File

@@ -912,6 +912,12 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
return;
}
if (enabled && mService.earcBlocksArcConnection()) {
Slog.i(TAG,
"ARC connection blocked because eARC connection is established or being "
+ "established.");
return;
}
// Terminate opposite action and start action if not exist.
if (enabled) {
@@ -1010,6 +1016,13 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
protected int handleInitiateArc(HdmiCecMessage message) {
assertRunOnServiceThread();
if (mService.earcBlocksArcConnection()) {
Slog.i(TAG,
"ARC connection blocked because eARC connection is established or being "
+ "established.");
return Constants.ABORT_NOT_IN_CORRECT_MODE;
}
if (!canStartArcUpdateAction(message.getSource(), true)) {
HdmiDeviceInfo avrDeviceInfo = getAvrDeviceInfo();
if (avrDeviceInfo == null) {

View File

@@ -26,6 +26,7 @@ import static android.hardware.hdmi.HdmiControlManager.SOUNDBAR_MODE_ENABLED;
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
import static com.android.server.hdmi.Constants.DISABLED;
import static com.android.server.hdmi.Constants.ENABLED;
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_ARC_PENDING;
import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE;
import static com.android.server.hdmi.Constants.OPTION_MHL_INPUT_SWITCHING;
import static com.android.server.hdmi.Constants.OPTION_MHL_POWER_CHARGE;
@@ -4540,4 +4541,13 @@ public class HdmiControlService extends SystemService {
mEarcLocalDevice.handleEarcCapabilitiesReported(rawCapabilities);
}
}
protected boolean earcBlocksArcConnection() {
if (mEarcLocalDevice == null) {
return false;
}
synchronized (mLock) {
return mEarcLocalDevice.mEarcStatus != HDMI_EARC_STATUS_ARC_PENDING;
}
}
}

View File

@@ -18,6 +18,7 @@ package com.android.server.hdmi;
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_ARC_PENDING;
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_CONNECTED;
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_PENDING;
import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_IDLE;
import android.hardware.hdmi.HdmiDeviceInfo;
@@ -69,6 +70,9 @@ public class HdmiEarcLocalDeviceTx extends HdmiEarcLocalDevice {
HdmiEarcLocalDeviceTx(HdmiControlService service) {
super(service, HdmiDeviceInfo.DEVICE_TV);
synchronized (mLock) {
mEarcStatus = HDMI_EARC_STATUS_EARC_PENDING;
}
mReportCapsHandler = new Handler(service.getServiceLooper());
mReportCapsRunnable = new ReportCapsRunnable();
}

View File

@@ -96,6 +96,7 @@ public class HdmiCecLocalDeviceTvTest {
private int mTvPhysicalAddress;
private int mTvLogicalAddress;
private boolean mWokenUp;
private boolean mEarcBlocksArc;
private List<DeviceEventListener> mDeviceEventListeners = new ArrayList<>();
private class DeviceEventListener {
@@ -155,6 +156,11 @@ public class HdmiCecLocalDeviceTvTest {
return false;
}
@Override
boolean isPowerStandbyOrTransient() {
return false;
}
@Override
AudioManager getAudioManager() {
return mAudioManager;
@@ -164,6 +170,11 @@ public class HdmiCecLocalDeviceTvTest {
void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) {
mDeviceEventListeners.add(new DeviceEventListener(device, status));
}
@Override
protected boolean earcBlocksArcConnection() {
return mEarcBlocksArc;
}
};
mHdmiControlService.setIoLooper(mMyLooper);
@@ -175,16 +186,18 @@ public class HdmiCecLocalDeviceTvTest {
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[2];
hdmiPortInfos[0] =
new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x1000, true, false, false);
new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x1000, true, false, false, false);
hdmiPortInfos[1] =
new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true);
new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true, true);
mNativeWrapper.setPortInfo(hdmiPortInfos);
mHdmiControlService.initService();
mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mPowerManager = new FakePowerManagerWrapper(context);
mHdmiControlService.setPowerManager(mPowerManager);
mTvPhysicalAddress = 0x0000;
mEarcBlocksArc = false;
mNativeWrapper.setPhysicalAddress(mTvPhysicalAddress);
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_DISABLED);
mTestLooper.dispatchAll();
mHdmiCecLocalDeviceTv = mHdmiControlService.tv();
mTvLogicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress();
@@ -426,9 +439,10 @@ public class HdmiCecLocalDeviceTvTest {
public void startArcAction_enable_portDoesNotSupportArc() {
// Emulate Audio device on port 0x1000 (does not support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mHdmiCecLocalDeviceTv.startArcAction(true);
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
@@ -445,9 +459,10 @@ public class HdmiCecLocalDeviceTvTest {
public void startArcAction_disable_portDoesNotSupportArc() {
// Emulate Audio device on port 0x1000 (does not support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mHdmiCecLocalDeviceTv.startArcAction(false);
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
@@ -464,9 +479,10 @@ public class HdmiCecLocalDeviceTvTest {
public void startArcAction_enable_portSupportsArc() {
// Emulate Audio device on port 0x2000 (supports ARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
mHdmiCecLocalDeviceTv.startArcAction(true);
@@ -485,9 +501,10 @@ public class HdmiCecLocalDeviceTvTest {
public void startArcAction_disable_portSupportsArc() {
// Emulate Audio device on port 0x2000 (supports ARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
mHdmiCecLocalDeviceTv.startArcAction(false);
@@ -522,9 +539,10 @@ public class HdmiCecLocalDeviceTvTest {
public void handleInitiateArc_portDoesNotSupportArc() {
// Emulate Audio device on port 0x1000 (does not support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
ADDR_AUDIO_SYSTEM,
@@ -544,9 +562,10 @@ public class HdmiCecLocalDeviceTvTest {
public void handleInitiateArc_portSupportsArc() {
// Emulate Audio device on port 0x2000 (supports ARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
@@ -574,6 +593,66 @@ public class HdmiCecLocalDeviceTvTest {
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
}
@Test
public void handleTerminateArc_noAudioDevice() {
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(terminateArc);
mTestLooper.dispatchAll();
HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
}
@Test
public void handleTerminateArc_portDoesNotSupportArc() {
// Emulate Audio device on port 0x1000 (does not support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(terminateArc);
mTestLooper.dispatchAll();
HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
}
@Test
public void handleTerminateArc_portSupportsArc() {
// Emulate Audio device on port 0x2000 (supports ARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(terminateArc);
mTestLooper.dispatchAll();
HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
}
@Test
public void supportsRecordTvScreen() {
HdmiCecMessage recordTvScreen = HdmiCecMessage.build(ADDR_RECORDER_1, mTvLogicalAddress,
@@ -595,9 +674,10 @@ public class HdmiCecLocalDeviceTvTest {
HdmiControlManager.SYSTEM_AUDIO_CONTROL_ENABLED);
// Emulate Audio device on port 0x1000 (does not support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
HdmiCecFeatureAction systemAudioAutoInitiationAction =
@@ -636,9 +716,9 @@ public class HdmiCecLocalDeviceTvTest {
public void hotplugDetectionAction_discoversDeviceAfterMessageReceived() {
// Playback 1 sends a message before ACKing a poll
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.NACK);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildActiveSource(
HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
ADDR_PLAYBACK_1, ADDR_TV);
mNativeWrapper.onCecMessage(hdmiCecMessage);
mNativeWrapper.onCecMessage(activeSource);
mTestLooper.dispatchAll();
// Playback 1 begins ACKing polls, allowing detection by HotplugDetectionAction
@@ -853,11 +933,11 @@ public class HdmiCecLocalDeviceTvTest {
@Test
public void tvSendRequestArcTerminationOnSleep() {
// Emulate Audio device on port 0x2000 (supports ARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage hdmiCecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(hdmiCecMessage);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
mHdmiCecLocalDeviceTv.startArcAction(true);
@@ -898,4 +978,182 @@ public class HdmiCecLocalDeviceTvTest {
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
}
@Test
public void startArcAction_enable_earcBlocksArc() {
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
mTestLooper.dispatchAll();
mEarcBlocksArc = true;
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
mHdmiCecLocalDeviceTv.startArcAction(true);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination);
}
@Test
public void startArcAction_enable_earcDoesNotBlockArc() {
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
mTestLooper.dispatchAll();
mEarcBlocksArc = false;
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
mHdmiCecLocalDeviceTv.startArcAction(true);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination);
}
@Test
public void startArcAction_disable_earcBlocksArc() {
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
mTestLooper.dispatchAll();
mEarcBlocksArc = true;
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
mHdmiCecLocalDeviceTv.startArcAction(false);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
}
@Test
public void handleInitiateArc_earcBlocksArc() {
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
mTestLooper.dispatchAll();
mEarcBlocksArc = true;
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(requestArcInitiation);
mTestLooper.dispatchAll();
HdmiCecMessage featureAbortMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
ADDR_TV,
ADDR_AUDIO_SYSTEM,
Constants.MESSAGE_INITIATE_ARC,
Constants.ABORT_NOT_IN_CORRECT_MODE);
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbortMessage);
}
@Test
public void handleInitiateArc_earcDoesNotBlockArc() {
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
mTestLooper.dispatchAll();
mEarcBlocksArc = false;
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(requestArcInitiation);
mTestLooper.dispatchAll();
HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
// <Report ARC Initiated> should only be sent after SAD querying is done
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated);
// Finish querying SADs
assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
}
@Test
public void handleTerminateArc_earcBlocksArc() {
mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
mTestLooper.dispatchAll();
mEarcBlocksArc = true;
// Emulate Audio device on port 0x2000 (supports ARC and eARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(terminateArc);
mTestLooper.dispatchAll();
HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
}
}

View File

@@ -1253,6 +1253,46 @@ public class HdmiControlServiceTest {
verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(true);
}
@Test
public void earcIdle_blocksArcConnection() {
mHdmiControlServiceSpy.mEarcSupported = true;
mHdmiControlServiceSpy.clearEarcLocalDevice();
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_IDLE);
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
assertThat(mHdmiControlServiceSpy.earcBlocksArcConnection()).isTrue();
}
@Test
public void earcPending_blocksArcConnection() {
mHdmiControlServiceSpy.mEarcSupported = true;
mHdmiControlServiceSpy.clearEarcLocalDevice();
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_PENDING);
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
assertThat(mHdmiControlServiceSpy.earcBlocksArcConnection()).isTrue();
}
@Test
public void earcEnabled_blocksArcConnection() {
mHdmiControlServiceSpy.mEarcSupported = true;
mHdmiControlServiceSpy.clearEarcLocalDevice();
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_CONNECTED);
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
assertThat(mHdmiControlServiceSpy.earcBlocksArcConnection()).isTrue();
}
@Test
public void arcPending_doesNotBlockArcConnection() {
mHdmiControlServiceSpy.mEarcSupported = true;
mHdmiControlServiceSpy.clearEarcLocalDevice();
HdmiEarcLocalDeviceTx localDeviceTx = new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy);
localDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_ARC_PENDING);
mHdmiControlServiceSpy.addEarcLocalDevice(localDeviceTx);
assertThat(mHdmiControlServiceSpy.earcBlocksArcConnection()).isFalse();
}
protected static class MockPlaybackDevice extends HdmiCecLocalDevicePlayback {
private boolean mCanGoToStandby;