Return early if audio system doesn't support SAD feature

Signals that the audio system doesn't support the SAD feature:
- it sends a <Feature Abort>[Unrecognized Opcode]
- even after 2 tries, it still doesn't respond to the <Give SAD>
  messages

Test: atest and manually verified that the SAD feature returns early and the ARC connection is unblocked.
Bug: 232235947
Change-Id: I146fd24820537ea4957785b8eb0710ddb12b977b
This commit is contained in:
Nathalie Le Clair
2022-05-11 16:44:42 +02:00
parent 56e26a9e4d
commit 46887f8e68
2 changed files with 102 additions and 76 deletions

View File

@@ -181,13 +181,20 @@ final class RequestSadAction extends HdmiCecFeatureAction {
return true;
}
if (cmd.getOpcode() == Constants.MESSAGE_FEATURE_ABORT
&& (cmd.getParams()[0] & 0xFF) == Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR
&& (cmd.getParams()[1] & 0xFF) == Constants.ABORT_INVALID_OPERAND) {
// Queried SADs are not supported
mQueriedSadCount += MAX_SAD_PER_REQUEST;
mTimeoutRetry = 0;
querySad();
return true;
&& (cmd.getParams()[0] & 0xFF)
== Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR) {
if ((cmd.getParams()[1] & 0xFF) == Constants.ABORT_UNRECOGNIZED_OPCODE) {
// SAD feature is not supported
wrapUpAndFinish();
return true;
}
if ((cmd.getParams()[1] & 0xFF) == Constants.ABORT_INVALID_OPERAND) {
// Queried SADs are not supported
mQueriedSadCount += MAX_SAD_PER_REQUEST;
mTimeoutRetry = 0;
querySad();
return true;
}
}
return false;
}
@@ -211,9 +218,9 @@ final class RequestSadAction extends HdmiCecFeatureAction {
querySad();
return;
}
mQueriedSadCount += MAX_SAD_PER_REQUEST;
mTimeoutRetry = 0;
querySad();
// Don't query any other SADs if one of the SAD queries ran into the maximum amount of
// retries.
wrapUpAndFinish();
}
}

View File

@@ -139,11 +139,12 @@ public class RequestSadActionTest {
}
@Test
public void noResponse_queryAgain_emptyResult() {
public void noResponse_queryAgainOnce_emptyResult() {
RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM,
mCallback);
action.start();
mTestLooper.dispatchAll();
assertThat(mSupportedSads).isNull();
HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
@@ -153,45 +154,90 @@ public class RequestSadActionTest {
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expected1);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mSupportedSads).isNotNull();
assertThat(mSupportedSads.size()).isEqualTo(0);
HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray());
assertThat(mNativeWrapper.getResultMessages()).contains(expected2);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expected2);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray());
assertThat(mNativeWrapper.getResultMessages()).contains(expected3);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expected3);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray());
assertThat(mNativeWrapper.getResultMessages()).contains(expected4);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expected4);
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected2);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected3);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected4);
assertThat(mSupportedSads.size()).isEqualTo(0);
}
@Test
public void unrecognizedOpcode_dontQueryAgain_emptyResult() {
RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM,
mCallback);
action.start();
mTestLooper.dispatchAll();
assertThat(mSupportedSads).isNull();
HdmiCecMessage unrecognizedOpcode = HdmiCecMessageBuilder.buildFeatureAbortCommand(
Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress,
Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR,
Constants.ABORT_UNRECOGNIZED_OPCODE);
HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray());
assertThat(mNativeWrapper.getResultMessages()).contains(expected1);
action.processCommand(unrecognizedOpcode);
mTestLooper.dispatchAll();
assertThat(mSupportedSads).isNotNull();
assertThat(mSupportedSads.size()).isEqualTo(0);
HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray());
HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray());
HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray());
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected2);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected3);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected4);
assertThat(mSupportedSads.size()).isEqualTo(0);
}
@@ -455,11 +501,12 @@ public class RequestSadActionTest {
}
@Test
public void invalidMessageLength_queryAgain() {
public void invalidMessageLength_queryAgainOnce() {
RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM,
mCallback);
action.start();
mTestLooper.dispatchAll();
assertThat(mSupportedSads).isNull();
HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
@@ -482,63 +529,35 @@ public class RequestSadActionTest {
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mSupportedSads).isNotNull();
assertThat(mSupportedSads.size()).isEqualTo(0);
HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray());
byte[] sadsToRespond_2 = new byte[]{
0x05, 0x18, 0x4A,
0x06, 0x64, 0x5A,
0x07,
0x08, 0x20, 0x0A};
HdmiCecMessage response2 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor(
Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_2);
assertThat(mNativeWrapper.getResultMessages()).contains(expected2);
mNativeWrapper.clearResultMessages();
action.processCommand(response2);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expected2);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray());
byte[] sadsToRespond_3 = new byte[0];
HdmiCecMessage response3 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor(
Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_3);
assertThat(mNativeWrapper.getResultMessages()).contains(expected3);
mNativeWrapper.clearResultMessages();
action.processCommand(response3);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expected3);
mNativeWrapper.clearResultMessages();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM,
CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray());
byte[] sadsToRespond_4 = new byte[]{
0x0D, 0x18, 0x4A,
0x0E, 0x64, 0x5A,
0x0F, 0x4B};
HdmiCecMessage response4 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor(
Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_4);
assertThat(mNativeWrapper.getResultMessages()).contains(expected4);
mNativeWrapper.clearResultMessages();
action.processCommand(response4);
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expected4);
mTestLooper.moveTimeForward(TIMEOUT_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected2);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected3);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected4);
assertThat(mSupportedSads.size()).isEqualTo(0);
}