diff options
4 files changed, 87 insertions, 54 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 4b85217c2136..101596d9d7c1 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -1150,6 +1150,13 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { return Constants.ABORT_REFUSED; } + if (mArcEstablished) { + HdmiLogger.debug("ARC is already established."); + HdmiCecMessage command = HdmiCecMessageBuilder.buildReportArcInitiated( + getDeviceInfo().getLogicalAddress(), message.getSource()); + mService.sendCecCommand(command); + return Constants.HANDLED; + } // In case where <Initiate Arc> is started by <Request ARC Initiation>, this message is // handled in RequestArcInitiationAction as well. SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this, diff --git a/services/core/java/com/android/server/hdmi/RequestSadAction.java b/services/core/java/com/android/server/hdmi/RequestSadAction.java index 0188e963140e..25663006b4b1 100644 --- a/services/core/java/com/android/server/hdmi/RequestSadAction.java +++ b/services/core/java/com/android/server/hdmi/RequestSadAction.java @@ -19,6 +19,8 @@ package com.android.server.hdmi; import android.hardware.hdmi.HdmiControlManager; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; + import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -36,7 +38,8 @@ final class RequestSadAction extends HdmiCecFeatureAction { // State in which the action is waiting for <Report Short Audio Descriptor>. private static final int STATE_WAITING_FOR_REPORT_SAD = 1; private static final int MAX_SAD_PER_REQUEST = 4; - private static final int RETRY_COUNTER_MAX = 1; + @VisibleForTesting + public static final int RETRY_COUNTER_MAX = 3; private final int mTargetAddress; private final RequestSadCallback mCallback; private final List<Integer> mCecCodecsToQuery = new ArrayList<>(); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java index a5f1fcd01aa1..2d957401e6bd 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -30,6 +30,7 @@ import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF; import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON; import static com.android.server.hdmi.RequestActiveSourceAction.TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS; import static com.android.server.hdmi.RoutingControlAction.TIMEOUT_ROUTING_INFORMATION_MS; +import static com.android.server.hdmi.RequestSadAction.RETRY_COUNTER_MAX; import static com.google.common.truth.Truth.assertThat; @@ -273,13 +274,12 @@ public class HdmiCecLocalDeviceTvTest { 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(); + for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { + assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); + mNativeWrapper.clearResultMessages(); + mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); + mTestLooper.dispatchAll(); + } assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); mNativeWrapper.clearResultMessages(); @@ -685,15 +685,43 @@ public class HdmiCecLocalDeviceTvTest { assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); // Finish querying SADs - assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); - mNativeWrapper.clearResultMessages(); - mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); + for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { + assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); + mNativeWrapper.clearResultMessages(); + mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); + mTestLooper.dispatchAll(); + } + + assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); + } + + @Test + public void handleInitiateArc_arcAlreadyEstablished_noRequestSad() { + // 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(); - assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); - mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); + + assertThat(mHdmiCecLocalDeviceTv.isArcEstablished()).isFalse(); + + HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc( + ADDR_AUDIO_SYSTEM, + ADDR_TV); + mNativeWrapper.onCecMessage(requestArcInitiation); mTestLooper.dispatchAll(); - assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); + // Finish querying SADs + for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { + assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); + mNativeWrapper.clearResultMessages(); + mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); + mTestLooper.dispatchAll(); + } + + assertThat(mHdmiCecLocalDeviceTv.isArcEstablished()).isTrue(); } @Test @@ -970,13 +998,12 @@ public class HdmiCecLocalDeviceTvTest { // <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(); + for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { + assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); + mNativeWrapper.clearResultMessages(); + mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); + mTestLooper.dispatchAll(); + } assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); mNativeWrapper.clearResultMessages(); @@ -1171,13 +1198,12 @@ public class HdmiCecLocalDeviceTvTest { mTestLooper.dispatchAll(); // 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(); + for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { + assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); + mNativeWrapper.clearResultMessages(); + mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); + mTestLooper.dispatchAll(); + } // ARC should be established after RequestSadAction is finished assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); @@ -1327,13 +1353,12 @@ public class HdmiCecLocalDeviceTvTest { 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(); + for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { + assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); + mNativeWrapper.clearResultMessages(); + mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); + mTestLooper.dispatchAll(); + } assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java index f8e465c4c36f..4cf293758519 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java @@ -18,6 +18,7 @@ package com.android.server.hdmi; import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; +import static com.android.server.hdmi.RequestSadAction.RETRY_COUNTER_MAX; import static com.google.common.truth.Truth.assertThat; @@ -144,7 +145,7 @@ public class RequestSadActionTest { } @Test - public void noResponse_queryAgainOnce_emptyResult() { + public void noResponse_queryAgain_emptyResult() { RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, mCallback); action.start(); @@ -154,13 +155,13 @@ public class RequestSadActionTest { HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray()); - assertThat(mNativeWrapper.getResultMessages()).contains(expected1); - mNativeWrapper.clearResultMessages(); - mTestLooper.moveTimeForward(TIMEOUT_MS); - mTestLooper.dispatchAll(); - assertThat(mNativeWrapper.getResultMessages()).contains(expected1); - mTestLooper.moveTimeForward(TIMEOUT_MS); - mTestLooper.dispatchAll(); + + for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { + assertThat(mNativeWrapper.getResultMessages()).contains(expected1); + mNativeWrapper.clearResultMessages(); + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + } assertThat(mSupportedSads).isNotNull(); assertThat(mSupportedSads.size()).isEqualTo(0); @@ -507,7 +508,7 @@ public class RequestSadActionTest { } @Test - public void invalidMessageLength_queryAgainOnce() { + public void invalidMessageLength_queryAgain() { RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, mCallback); action.start(); @@ -524,16 +525,13 @@ public class RequestSadActionTest { 0x27, 0x20, 0x0A}; HdmiCecMessage response1 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_1); - assertThat(mNativeWrapper.getResultMessages()).contains(expected1); - mNativeWrapper.clearResultMessages(); - action.processCommand(response1); - mTestLooper.dispatchAll(); - mTestLooper.moveTimeForward(TIMEOUT_MS); - mTestLooper.dispatchAll(); - assertThat(mNativeWrapper.getResultMessages()).contains(expected1); - mNativeWrapper.clearResultMessages(); - mTestLooper.moveTimeForward(TIMEOUT_MS); - mTestLooper.dispatchAll(); + + for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) { + assertThat(mNativeWrapper.getResultMessages()).contains(expected1); + mNativeWrapper.clearResultMessages(); + mTestLooper.moveTimeForward(TIMEOUT_MS); + mTestLooper.dispatchAll(); + } assertThat(mSupportedSads).isNotNull(); assertThat(mSupportedSads.size()).isEqualTo(0); |