Add callback to startArcAction

Test: atest
Bug: 262573690
Change-Id: I29676ef75dd3a197129e2ad0b92487f329cb806c
This commit is contained in:
Nathalie Le Clair
2022-10-20 09:03:12 +02:00
parent 5023f01270
commit 55037ec56c
6 changed files with 466 additions and 47 deletions

View File

@@ -899,10 +899,16 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@ServiceThreadOnly
void startArcAction(boolean enabled) {
startArcAction(enabled, null);
}
@ServiceThreadOnly
void startArcAction(boolean enabled, IHdmiControlCallback callback) {
assertRunOnServiceThread();
HdmiDeviceInfo info = getAvrDeviceInfo();
if (info == null) {
Slog.w(TAG, "Failed to start arc action; No AVR device.");
invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
return;
}
if (!canStartArcUpdateAction(info.getLogicalAddress(), enabled)) {
@@ -910,25 +916,37 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
if (enabled && !isConnectedToArcPort(info.getPhysicalAddress())) {
displayOsd(OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT);
}
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
return;
}
if (enabled && mService.earcBlocksArcConnection()) {
Slog.i(TAG,
"ARC connection blocked because eARC connection is established or being "
+ "established.");
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
return;
}
// Terminate opposite action and start action if not exist.
// Terminate opposite action and create an action with callback.
if (enabled) {
removeAction(RequestArcTerminationAction.class);
if (!hasAction(RequestArcInitiationAction.class)) {
addAndStartAction(new RequestArcInitiationAction(this, info.getLogicalAddress()));
if (hasAction(RequestArcInitiationAction.class)) {
RequestArcInitiationAction existingInitiationAction =
getActions(RequestArcInitiationAction.class).get(0);
existingInitiationAction.addCallback(callback);
} else {
addAndStartAction(
new RequestArcInitiationAction(this, info.getLogicalAddress(), callback));
}
} else {
removeAction(RequestArcInitiationAction.class);
if (!hasAction(RequestArcTerminationAction.class)) {
addAndStartAction(new RequestArcTerminationAction(this, info.getLogicalAddress()));
if (hasAction(RequestArcTerminationAction.class)) {
RequestArcTerminationAction existingTerminationAction =
getActions(RequestArcTerminationAction.class).get(0);
existingTerminationAction.addCallback(callback);
} else {
addAndStartAction(
new RequestArcTerminationAction(this, info.getLogicalAddress(), callback));
}
}
}
@@ -1036,9 +1054,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
return Constants.ABORT_REFUSED;
}
// In case where <Initiate Arc> is started by <Request ARC Initiation>
// need to clean up RequestArcInitiationAction.
removeAction(RequestArcInitiationAction.class);
// In case where <Initiate Arc> is started by <Request ARC Initiation>, this message is
// handled in RequestArcInitiationAction as well.
SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this,
message.getSource(), true);
addAndStartAction(action);
@@ -1072,9 +1089,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
return Constants.HANDLED;
}
// Do not check ARC configuration since the AVR might have been already removed.
// Clean up RequestArcTerminationAction in case <Terminate Arc> was started by
// <Request ARC Termination>.
removeAction(RequestArcTerminationAction.class);
// In case where <Terminate Arc> is started by <Request ARC Termination>, this
// message is handled in RequestArcTerminationAction as well.
SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this,
message.getSource(), false);
addAndStartAction(action);

View File

@@ -3237,6 +3237,9 @@ public class HdmiControlService extends SystemService {
}
private void invokeCallback(IHdmiControlCallback callback, int result) {
if (callback == null) {
return;
}
try {
callback.onComplete(result);
} catch (RemoteException e) {

View File

@@ -16,7 +16,9 @@
package com.android.server.hdmi;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.IHdmiControlCallback;
/**
* Base feature action class for &lt;Request ARC Initiation&gt;/&lt;Request ARC Termination&gt;.
@@ -35,41 +37,19 @@ abstract class RequestArcAction extends HdmiCecFeatureAction {
*
* @param source {@link HdmiCecLocalDevice} instance
* @param avrAddress address of AV receiver. It should be AUDIO_SYSTEM type
* @param callback callback to inform about the status of the action
* @throws IllegalArgumentException if device type of sourceAddress and avrAddress
* is invalid
*/
RequestArcAction(HdmiCecLocalDevice source, int avrAddress) {
super(source);
RequestArcAction(HdmiCecLocalDevice source, int avrAddress, IHdmiControlCallback callback) {
super(source, callback);
HdmiUtils.verifyAddressType(getSourceAddress(), HdmiDeviceInfo.DEVICE_TV);
HdmiUtils.verifyAddressType(avrAddress, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mAvrAddress = avrAddress;
}
@Override
boolean processCommand(HdmiCecMessage cmd) {
if (mState != STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE
|| !HdmiUtils.checkCommandSource(cmd, mAvrAddress, TAG)) {
return false;
}
int opcode = cmd.getOpcode();
switch (opcode) {
// Handles only <Feature Abort> here and, both <Initiate ARC> and <Terminate ARC>
// are handled in HdmiControlService itself because both can be
// received without <Request ARC Initiation> or <Request ARC Termination>.
case Constants.MESSAGE_FEATURE_ABORT:
int originalOpcode = cmd.getParams()[0] & 0xFF;
if (originalOpcode == Constants.MESSAGE_REQUEST_ARC_TERMINATION) {
disableArcTransmission();
finish();
return true;
} else if (originalOpcode == Constants.MESSAGE_REQUEST_ARC_INITIATION) {
tv().disableArc();
finish();
return true;
}
return false;
}
return false;
RequestArcAction(HdmiCecLocalDevice source, int avrAddress) {
this(source, avrAddress, null);
}
protected final void disableArcTransmission() {
@@ -86,6 +66,6 @@ abstract class RequestArcAction extends HdmiCecFeatureAction {
}
HdmiLogger.debug("[T] RequestArcAction.");
disableArcTransmission();
finish();
finishWithCallback(HdmiControlManager.RESULT_TIMEOUT);
}
}

View File

@@ -16,6 +16,8 @@
package com.android.server.hdmi;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.tv.cec.V1_0.SendMessageResult;
/**
@@ -35,6 +37,16 @@ final class RequestArcInitiationAction extends RequestArcAction {
super(source, avrAddress);
}
/**
* @Constructor
*
* For more details look at {@link RequestArcAction#RequestArcAction}.
*/
RequestArcInitiationAction(HdmiCecLocalDevice source, int avrAddress,
IHdmiControlCallback callback) {
super(source, avrAddress, callback);
}
@Override
boolean start() {
// Seq #38
@@ -49,10 +61,34 @@ final class RequestArcInitiationAction extends RequestArcAction {
if (error != SendMessageResult.SUCCESS) {
// Turn off ARC status if <Request ARC Initiation> fails.
tv().disableArc();
finish();
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
}
}
});
return true;
}
@Override
boolean processCommand(HdmiCecMessage cmd) {
if (mState != STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE
|| !HdmiUtils.checkCommandSource(cmd, mAvrAddress, TAG)) {
return false;
}
int opcode = cmd.getOpcode();
switch (opcode) {
case Constants.MESSAGE_FEATURE_ABORT:
int originalOpcode = cmd.getParams()[0] & 0xFF;
if (originalOpcode == Constants.MESSAGE_REQUEST_ARC_INITIATION) {
tv().disableArc();
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
return true;
}
return false;
case Constants.MESSAGE_INITIATE_ARC:
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
// This message still needs to be handled in HdmiCecLocalDeviceTv as well.
return false;
}
return false;
}
}

View File

@@ -16,6 +16,8 @@
package com.android.server.hdmi;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.tv.cec.V1_0.SendMessageResult;
/**
@@ -35,6 +37,16 @@ final class RequestArcTerminationAction extends RequestArcAction {
super(source, avrAddress);
}
/**
* @Constructor
*
* @see RequestArcAction#RequestArcAction
*/
RequestArcTerminationAction(HdmiCecLocalDevice source, int avrAddress,
IHdmiControlCallback callback) {
super(source, avrAddress, callback);
}
@Override
boolean start() {
mState = STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE;
@@ -49,10 +61,34 @@ final class RequestArcTerminationAction extends RequestArcAction {
// If failed to send <Request ARC Termination>, start "Disabled" ARC
// transmission action.
disableArcTransmission();
finish();
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
}
}
});
return true;
}
@Override
boolean processCommand(HdmiCecMessage cmd) {
if (mState != STATE_WATING_FOR_REQUEST_ARC_REQUEST_RESPONSE
|| !HdmiUtils.checkCommandSource(cmd, mAvrAddress, TAG)) {
return false;
}
int opcode = cmd.getOpcode();
switch (opcode) {
case Constants.MESSAGE_FEATURE_ABORT:
int originalOpcode = cmd.getParams()[0] & 0xFF;
if (originalOpcode == Constants.MESSAGE_REQUEST_ARC_TERMINATION) {
disableArcTransmission();
finishWithCallback(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
return true;
}
return false;
case Constants.MESSAGE_TERMINATE_ARC:
finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
// This message still needs to be handled in HdmiCecLocalDeviceTv as well.
return false;
}
return false;
}
}

View File

@@ -39,6 +39,7 @@ import android.content.Context;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.media.AudioManager;
import android.os.Looper;
@@ -209,6 +210,20 @@ public class HdmiCecLocalDeviceTvTest {
mNativeWrapper.clearResultMessages();
}
private static class TestCallback extends IHdmiControlCallback.Stub {
private final ArrayList<Integer> mCallbackResult = new ArrayList<Integer>();
@Override
public void onComplete(int result) {
mCallbackResult.add(result);
}
private int getResult() {
assertThat(mCallbackResult.size()).isEqualTo(1);
return mCallbackResult.get(0);
}
}
@Test
public void initialPowerStateIsStandby() {
assertThat(mHdmiCecLocalDeviceTv.getPowerStatus()).isEqualTo(
@@ -892,12 +907,12 @@ public class HdmiCecLocalDeviceTvTest {
mTestLooper.dispatchAll();
// <Feature Abort>[Not in correct mode] not sent
HdmiCecMessage featureAbortMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
ADDR_TV,
ADDR_PLAYBACK_1,
Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL,
Constants.ABORT_NOT_IN_CORRECT_MODE);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbortMessage);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort);
// <Set Audio Volume Level> uses volume range [0, 100]; STREAM_MUSIC uses range [0, 25]
verify(mAudioManager).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(5), anyInt());
@@ -918,12 +933,12 @@ public class HdmiCecLocalDeviceTvTest {
mTestLooper.dispatchAll();
// <Feature Abort>[Not in correct mode] sent
HdmiCecMessage featureAbortMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
ADDR_TV,
ADDR_PLAYBACK_1,
Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL,
Constants.ABORT_NOT_IN_CORRECT_MODE);
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbortMessage);
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
// AudioManager not notified of volume change
verify(mAudioManager, never()).setStreamVolume(eq(AudioManager.STREAM_MUSIC), anyInt(),
@@ -1081,12 +1096,12 @@ public class HdmiCecLocalDeviceTvTest {
mNativeWrapper.onCecMessage(requestArcInitiation);
mTestLooper.dispatchAll();
HdmiCecMessage featureAbortMessage = HdmiCecMessageBuilder.buildFeatureAbortCommand(
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
ADDR_TV,
ADDR_AUDIO_SYSTEM,
Constants.MESSAGE_INITIATE_ARC,
Constants.ABORT_NOT_IN_CORRECT_MODE);
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbortMessage);
assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort);
}
@Test
@@ -1156,4 +1171,337 @@ public class HdmiCecLocalDeviceTvTest {
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated);
}
@Test
public void startArcAction_initiation_noAvr() {
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
}
@Test
public void startArcAction_initiation_portNotConnected() {
// Emulate Audio device on port 0x2000 (supports ARC)
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
// Emulate port disconnect
mNativeWrapper.setPortConnectionStatus(2, false);
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
}
@Test
public void startArcAction_initiation_portDoesNotSupportArc() {
// Emulate Audio device on port 0x1000 (Doesn´t support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
}
@Test
public void startArcAction_initiation_indirectPhysicalAddress() {
// Emulate Audio device on port 0x2000 (Supports ARC)
mNativeWrapper.setPortConnectionStatus(2, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x2320, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
}
@Test
public void startArcAction_initiation_earcBlocksArc() {
// 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();
mEarcBlocksArc = true;
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
}
@Test
public void startArcAction_initiation_messageNotAcked() {
// 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();
mNativeWrapper.setMessageSendResult(
Constants.MESSAGE_REQUEST_ARC_INITIATION, SendMessageResult.NACK);
mTestLooper.dispatchAll();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
}
@Test
public void startArcAction_initiation_timeout() {
// 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();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT);
}
@Test
public void startArcAction_initiation_featureAbort() {
// 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();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
ADDR_AUDIO_SYSTEM,
ADDR_TV,
Constants.MESSAGE_REQUEST_ARC_INITIATION,
Constants.ABORT_NOT_IN_CORRECT_MODE);
mNativeWrapper.onCecMessage(featureAbort);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
}
@Test
public void startArcAction_initiation_success() {
// 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();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(true, callback);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation);
HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(initiateArc);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
}
@Test
public void startArcAction_termination_noAvr() {
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
}
@Test
public void startArcAction_termination_portDoesNotSupportArc() {
// Emulate Audio device on port 0x1000 (Doesn´t support ARC)
mNativeWrapper.setPortConnectionStatus(1, true);
HdmiCecMessage reportPhysicalAddress =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mNativeWrapper.onCecMessage(reportPhysicalAddress);
mTestLooper.dispatchAll();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE);
}
@Test
public void startArcAction_termination_messageNotAcked() {
// 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();
mNativeWrapper.setMessageSendResult(
Constants.MESSAGE_REQUEST_ARC_TERMINATION, SendMessageResult.NACK);
mTestLooper.dispatchAll();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
}
@Test
public void startArcAction_termination_timeout() {
// 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();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT);
}
@Test
public void startArcAction_termination_featureAbort() {
// 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();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand(
ADDR_AUDIO_SYSTEM,
ADDR_TV,
Constants.MESSAGE_REQUEST_ARC_TERMINATION,
Constants.ABORT_NOT_IN_CORRECT_MODE);
mNativeWrapper.onCecMessage(featureAbort);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
}
@Test
public void startArcAction_termination_success() {
// 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();
TestCallback callback = new TestCallback();
mHdmiCecLocalDeviceTv.startArcAction(false, callback);
mTestLooper.dispatchAll();
HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
ADDR_TV,
ADDR_AUDIO_SYSTEM);
assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination);
HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc(
ADDR_AUDIO_SYSTEM,
ADDR_TV);
mNativeWrapper.onCecMessage(terminateArc);
mTestLooper.dispatchAll();
assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
}
}