From ddc4753a8d9d76d1a27cc85103b709808d8feda3 Mon Sep 17 00:00:00 2001 From: "daren.liao" Date: Tue, 23 Aug 2022 10:04:25 +0800 Subject: [PATCH] Send when Standby MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Description] In aosp/1313995, we propose to disable ARC at first, in case that AVR doesn’t response to during standby and ARC pin is not disabled. However, the proposed CL made TV never send during standby process, which is not expected. We still need to disable ARC Pin without waiting for sent from AVR. However, this could be done by calling enableAudioReturnChannel() of HdmiControlService directly after RequestArcTerminationAction is started, making sure that could be sent correctly by TV when ARC was enabled Note that after this modification, TV could receive after AVR deviceInfo is cleared. In this case, a new AVR deviceInfo with physical address=0xFFFF is added by HdmiCecNetwork. As a result, we also add error handling in enableAudioReturnChannel for such case. [Test Report] 1. Connect Denon AVR-3500H - TV standby off/on, ARC is okay - TV CEC off/on, ARC is okay. 2. atset HdmiCecLocalDeviceTvTest PASS Bug: 243492848 Change-Id: Ib4b7d98a091c7cce37f5d4818b84807d67da016b --- .../server/hdmi/HdmiCecLocalDeviceTv.java | 16 +++++- .../server/hdmi/HdmiCecLocalDeviceTvTest.java | 49 +++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 9bce471fd0cb6..8a22ab968165a 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -837,7 +837,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { void enableAudioReturnChannel(boolean enabled) { assertRunOnServiceThread(); HdmiDeviceInfo avr = getAvrDeviceInfo(); - if (avr != null) { + if (avr != null && avr.getPortId() != Constants.INVALID_PORT_ID) { mService.enableAudioReturnChannel(avr.getPortId(), enabled); } } @@ -1335,6 +1335,16 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } } + @ServiceThreadOnly + private void forceDisableArcOnAllPins() { + List ports = mService.getPortInfo(); + for (HdmiPortInfo port : ports) { + if (isArcFeatureEnabled(port.getId())) { + mService.enableAudioReturnChannel(port.getId(), false); + } + } + } + @ServiceThreadOnly private void disableArcIfExist() { assertRunOnServiceThread(); @@ -1342,13 +1352,15 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { if (avr == null) { return; } - disableArc(); // Seq #44. removeAllRunningArcAction(); if (!hasAction(RequestArcTerminationAction.class) && isArcEstablished()) { addAndStartAction(new RequestArcTerminationAction(this, avr.getLogicalAddress())); } + + // Disable ARC Pin earlier, prevent the case where AVR doesn't send in time + forceDisableArcOnAllPins(); } @ServiceThreadOnly 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 8112ca8fbb142..aceae72371eb9 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -842,4 +842,53 @@ public class HdmiCecLocalDeviceTvTest { verify(mAudioManager, never()).setStreamVolume(eq(AudioManager.STREAM_MUSIC), anyInt(), anyInt()); } + + @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); + 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); + HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc( + ADDR_AUDIO_SYSTEM, + ADDR_TV); + HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( + ADDR_TV, + ADDR_AUDIO_SYSTEM); + + assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); + + mNativeWrapper.onCecMessage(initiateArc); + 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(); + + // ARC should be established after RequestSadAction is finished + assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); + + mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF); + mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); + } + }