From 98328d084607498f8d376f90940dc2ebaac0de1b Mon Sep 17 00:00:00 2001 From: Nathalie Le Clair Date: Mon, 13 Feb 2023 16:44:44 +0100 Subject: [PATCH 1/2] Make naming in Java consistent. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Java naming convention prefers the 'Earc' notation, so we should use that notation consistently. On the HAL side, there is no preference for the notation, so we keep the current notation, 'EArc“. Bug: 265395723 Test: make, atest Change-Id: I312edbcafe8b734ad6a73abefffaa3ea2f732d62 --- .../server/hdmi/HdmiEarcController.java | 60 +++++++++---------- ...rapper.java => FakeEarcNativeWrapper.java} | 14 ++--- .../server/hdmi/HdmiCecLocalDeviceTvTest.java | 6 +- .../server/hdmi/HdmiControlServiceTest.java | 6 +- .../hdmi/HdmiEarcLocalDeviceTxTest.java | 6 +- 5 files changed, 46 insertions(+), 46 deletions(-) rename services/tests/servicestests/src/com/android/server/hdmi/{FakeEArcNativeWrapper.java => FakeEarcNativeWrapper.java} (76%) diff --git a/services/core/java/com/android/server/hdmi/HdmiEarcController.java b/services/core/java/com/android/server/hdmi/HdmiEarcController.java index 2bb9ffb61eed3..46a8f039584b8 100644 --- a/services/core/java/com/android/server/hdmi/HdmiEarcController.java +++ b/services/core/java/com/android/server/hdmi/HdmiEarcController.java @@ -35,40 +35,40 @@ final class HdmiEarcController { private final HdmiControlService mService; - private EArcNativeWrapper mEArcNativeWrapperImpl; + private EarcNativeWrapper mEarcNativeWrapperImpl; - protected interface EArcNativeWrapper { + protected interface EarcNativeWrapper { boolean nativeInit(); - void nativeSetEArcEnabled(boolean enabled); - boolean nativeIsEArcEnabled(); + void nativeSetEarcEnabled(boolean enabled); + boolean nativeIsEarcEnabled(); void nativeSetCallback(EarcAidlCallback callback); byte nativeGetState(int portId); byte[] nativeGetLastReportedAudioCapabilities(int portId); } - private static final class EArcNativeWrapperImpl implements EArcNativeWrapper, + private static final class EarcNativeWrapperImpl implements EarcNativeWrapper, IBinder.DeathRecipient { - private IEArc mEArc; - private EarcAidlCallback mEArcCallback; + private IEArc mEarc; + private EarcAidlCallback mEarcCallback; @Override public void binderDied() { - mEArc.asBinder().unlinkToDeath(this, 0); + mEarc.asBinder().unlinkToDeath(this, 0); connectToHal(); - if (mEArcCallback != null) { - nativeSetCallback(mEArcCallback); + if (mEarcCallback != null) { + nativeSetCallback(mEarcCallback); } } boolean connectToHal() { - mEArc = + mEarc = IEArc.Stub.asInterface( ServiceManager.getService(IEArc.DESCRIPTOR + "/default")); - if (mEArc == null) { + if (mEarc == null) { return false; } try { - mEArc.asBinder().linkToDeath(this, 0); + mEarc.asBinder().linkToDeath(this, 0); } catch (RemoteException e) { HdmiLogger.error("Couldn't link callback object: ", e); } @@ -81,9 +81,9 @@ final class HdmiEarcController { } @Override - public void nativeSetEArcEnabled(boolean enabled) { + public void nativeSetEarcEnabled(boolean enabled) { try { - mEArc.setEArcEnabled(enabled); + mEarc.setEArcEnabled(enabled); } catch (ServiceSpecificException sse) { HdmiLogger.error( "Could not set eARC enabled to " + enabled + ". Error: ", sse.errorCode); @@ -93,9 +93,9 @@ final class HdmiEarcController { } @Override - public boolean nativeIsEArcEnabled() { + public boolean nativeIsEarcEnabled() { try { - return mEArc.isEArcEnabled(); + return mEarc.isEArcEnabled(); } catch (RemoteException re) { HdmiLogger.error("Could not read if eARC is enabled. Exception: ", re); return false; @@ -104,9 +104,9 @@ final class HdmiEarcController { @Override public void nativeSetCallback(EarcAidlCallback callback) { - mEArcCallback = callback; + mEarcCallback = callback; try { - mEArc.setCallback(callback); + mEarc.setCallback(callback); } catch (RemoteException re) { HdmiLogger.error("Could not set callback. Exception: ", re); } @@ -115,7 +115,7 @@ final class HdmiEarcController { @Override public byte nativeGetState(int portId) { try { - return mEArc.getState(portId); + return mEarc.getState(portId); } catch (RemoteException re) { HdmiLogger.error("Could not get eARC state. Exception: ", re); return -1; @@ -125,7 +125,7 @@ final class HdmiEarcController { @Override public byte[] nativeGetLastReportedAudioCapabilities(int portId) { try { - return mEArc.getLastReportedAudioCapabilities(portId); + return mEarc.getLastReportedAudioCapabilities(portId); } catch (RemoteException re) { HdmiLogger.error( "Could not read last reported audio capabilities. Exception: ", re); @@ -135,9 +135,9 @@ final class HdmiEarcController { } // Private constructor. Use HdmiEarcController.create(). - private HdmiEarcController(HdmiControlService service, EArcNativeWrapper nativeWrapper) { + private HdmiEarcController(HdmiControlService service, EarcNativeWrapper nativeWrapper) { mService = service; - mEArcNativeWrapperImpl = nativeWrapper; + mEarcNativeWrapperImpl = nativeWrapper; } /** @@ -151,14 +151,14 @@ final class HdmiEarcController { * returns {@code null}. */ static HdmiEarcController create(HdmiControlService service) { - return createWithNativeWrapper(service, new EArcNativeWrapperImpl()); + return createWithNativeWrapper(service, new EarcNativeWrapperImpl()); } /** * A factory method with injection of native methods for testing. */ static HdmiEarcController createWithNativeWrapper(HdmiControlService service, - EArcNativeWrapper nativeWrapper) { + EarcNativeWrapper nativeWrapper) { HdmiEarcController controller = new HdmiEarcController(service, nativeWrapper); if (!controller.init(nativeWrapper)) { HdmiLogger.warning("Could not connect to eARC AIDL HAL."); @@ -167,10 +167,10 @@ final class HdmiEarcController { return controller; } - private boolean init(EArcNativeWrapper nativeWrapper) { + private boolean init(EarcNativeWrapper nativeWrapper) { if (nativeWrapper.nativeInit()) { mControlHandler = new Handler(mService.getServiceLooper()); - mEArcNativeWrapperImpl.nativeSetCallback(new EarcAidlCallback()); + mEarcNativeWrapperImpl.nativeSetCallback(new EarcAidlCallback()); return true; } return false; @@ -194,7 +194,7 @@ final class HdmiEarcController { @HdmiAnnotations.ServiceThreadOnly void setEarcEnabled(boolean enabled) { assertRunOnServiceThread(); - mEArcNativeWrapperImpl.nativeSetEArcEnabled(enabled); + mEarcNativeWrapperImpl.nativeSetEarcEnabled(enabled); } /** @@ -205,7 +205,7 @@ final class HdmiEarcController { @HdmiAnnotations.ServiceThreadOnly @Constants.EarcStatus int getState(int portId) { - return mEArcNativeWrapperImpl.nativeGetState(portId); + return mEarcNativeWrapperImpl.nativeGetState(portId); } /** @@ -215,7 +215,7 @@ final class HdmiEarcController { */ @HdmiAnnotations.ServiceThreadOnly byte[] getLastReportedCaps(int portId) { - return mEArcNativeWrapperImpl.nativeGetLastReportedAudioCapabilities(portId); + return mEarcNativeWrapperImpl.nativeGetLastReportedAudioCapabilities(portId); } final class EarcAidlCallback extends IEArcCallback.Stub { diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeEArcNativeWrapper.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeEarcNativeWrapper.java similarity index 76% rename from services/tests/servicestests/src/com/android/server/hdmi/FakeEArcNativeWrapper.java rename to services/tests/servicestests/src/com/android/server/hdmi/FakeEarcNativeWrapper.java index ac491f44bbbf2..e0c8e818782d6 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/FakeEArcNativeWrapper.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeEarcNativeWrapper.java @@ -18,10 +18,10 @@ package com.android.server.hdmi; import android.hardware.tv.hdmi.earc.IEArcStatus; -final class FakeEArcNativeWrapper implements HdmiEarcController.EArcNativeWrapper { - private static final String TAG = "FakeEArcNativeWrapper"; +final class FakeEarcNativeWrapper implements HdmiEarcController.EarcNativeWrapper { + private static final String TAG = "FakeEarcNativeWrapper"; - private boolean mIsEArcEnabled = true; + private boolean mIsEarcEnabled = true; @Override public boolean nativeInit() { @@ -29,13 +29,13 @@ final class FakeEArcNativeWrapper implements HdmiEarcController.EArcNativeWrappe } @Override - public void nativeSetEArcEnabled(boolean enabled) { - mIsEArcEnabled = enabled; + public void nativeSetEarcEnabled(boolean enabled) { + mIsEarcEnabled = enabled; } @Override - public boolean nativeIsEArcEnabled() { - return mIsEArcEnabled; + public boolean nativeIsEarcEnabled() { + return mIsEarcEnabled; } @Override 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 ccfc2b969745f..75a8ad7a56a7b 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -91,7 +91,7 @@ public class HdmiCecLocalDeviceTvTest { private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv; private FakeNativeWrapper mNativeWrapper; private HdmiEarcController mHdmiEarcController; - private FakeEArcNativeWrapper mEArcNativeWrapper; + private FakeEarcNativeWrapper mEarcNativeWrapper; private FakePowerManagerWrapper mPowerManager; private Looper mMyLooper; private TestLooper mTestLooper = new TestLooper(); @@ -187,9 +187,9 @@ public class HdmiCecLocalDeviceTvTest { mHdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(mHdmiCecController); - mEArcNativeWrapper = new FakeEArcNativeWrapper(); + mEarcNativeWrapper = new FakeEarcNativeWrapper(); mHdmiEarcController = HdmiEarcController.createWithNativeWrapper( - mHdmiControlService, mEArcNativeWrapper); + mHdmiControlService, mEarcNativeWrapper); mHdmiControlService.setEarcController(mHdmiEarcController); mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService)); HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[2]; diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java index 8baad61b40fb8..4dd5e94541e47 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java @@ -88,7 +88,7 @@ public class HdmiControlServiceTest { private MockPlaybackDevice mPlaybackDeviceSpy; private FakeNativeWrapper mNativeWrapper; private HdmiEarcController mHdmiEarcController; - private FakeEArcNativeWrapper mEArcNativeWrapper; + private FakeEarcNativeWrapper mEarcNativeWrapper; private FakePowerManagerWrapper mPowerManager; private Looper mMyLooper; private TestLooper mTestLooper = new TestLooper(); @@ -128,9 +128,9 @@ public class HdmiControlServiceTest { mHdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlServiceSpy, mNativeWrapper, mHdmiControlServiceSpy.getAtomWriter()); mHdmiControlServiceSpy.setCecController(mHdmiCecController); - mEArcNativeWrapper = new FakeEArcNativeWrapper(); + mEarcNativeWrapper = new FakeEarcNativeWrapper(); mHdmiEarcController = HdmiEarcController.createWithNativeWrapper( - mHdmiControlServiceSpy, mEArcNativeWrapper); + mHdmiControlServiceSpy, mEarcNativeWrapper); mHdmiControlServiceSpy.setEarcController(mHdmiEarcController); mHdmiControlServiceSpy.setHdmiMhlController(HdmiMhlControllerStub.create( mHdmiControlServiceSpy)); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java index 4ac23f80ac686..c3aec841ac3db 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java @@ -69,7 +69,7 @@ public class HdmiEarcLocalDeviceTxTest { private HdmiEarcLocalDevice mHdmiEarcLocalDeviceTx; private FakeNativeWrapper mNativeWrapper; private HdmiEarcController mHdmiEarcController; - private FakeEArcNativeWrapper mEArcNativeWrapper; + private FakeEarcNativeWrapper mEarcNativeWrapper; private FakePowerManagerWrapper mPowerManager; private byte[] mEarcCapabilities = new byte[]{ 0x01, 0x01, 0x1a, 0x35, 0x0f, 0x7f, 0x07, 0x15, 0x07, 0x50, 0x3d, 0x1f, (byte) 0xc0, @@ -128,9 +128,9 @@ public class HdmiEarcLocalDeviceTxTest { mHdmiCecController = HdmiCecController.createWithNativeWrapper( mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); mHdmiControlService.setCecController(mHdmiCecController); - mEArcNativeWrapper = new FakeEArcNativeWrapper(); + mEarcNativeWrapper = new FakeEarcNativeWrapper(); mHdmiEarcController = HdmiEarcController.createWithNativeWrapper( - mHdmiControlService, mEArcNativeWrapper); + mHdmiControlService, mEarcNativeWrapper); mHdmiControlService.setEarcController(mHdmiEarcController); mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService)); mHdmiControlService.initService(); From e67e9018918d7f5be617f33508a4f4dd01efb9a2 Mon Sep 17 00:00:00 2001 From: Nathalie Le Clair Date: Tue, 14 Feb 2023 17:03:17 +0100 Subject: [PATCH 2/2] Unit tests for SAM during transitions from and to eARC SAM should remain ON during these transitions. This matches with the current implementation and is now validated by these unit tests. Bug: 265906726 Test: atest Change-Id: I4f262f429657430f23c13652478e6c52177f8c75 --- .../server/hdmi/HdmiCecLocalDeviceTvTest.java | 137 +++++++++++++++--- 1 file changed, 113 insertions(+), 24 deletions(-) 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 75a8ad7a56a7b..d2b1bdd127d2c 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java @@ -29,9 +29,11 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -240,6 +242,61 @@ public class HdmiCecLocalDeviceTvTest { } } + + private void initiateArcAndValidate() { + HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc( + ADDR_AUDIO_SYSTEM, + ADDR_TV); + + mNativeWrapper.onCecMessage(initiateArc); + mTestLooper.dispatchAll(); + + HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( + ADDR_TV, + ADDR_AUDIO_SYSTEM); + // 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); + mNativeWrapper.clearResultMessages(); + } + + private void initateSamAndValidate() { + // Record that previous system audio mode is on. + mHdmiCecLocalDeviceTv.setSystemAudioControlFeatureEnabled(true); + + HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv, + ADDR_AUDIO_SYSTEM); + mHdmiCecLocalDeviceTv.addAndStartAction(action); + mTestLooper.dispatchAll(); + + HdmiCecMessage giveSystemAudioModeStatus = + HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus( + mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(), + ADDR_AUDIO_SYSTEM); + + assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus); + + HdmiCecMessage reportSystemAudioMode = + HdmiCecMessageBuilder.buildReportSystemAudioMode( + ADDR_AUDIO_SYSTEM, + mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(), + true); + mHdmiControlService.handleCecCommand(reportSystemAudioMode); + mTestLooper.dispatchAll(); + + assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); + } + @Test public void initialPowerStateIsStandby() { assertThat(mHdmiCecLocalDeviceTv.getPowerStatus()).isEqualTo( @@ -1531,30 +1588,7 @@ public class HdmiCecLocalDeviceTvTest { mNativeWrapper.onCecMessage(reportPhysicalAddress); mTestLooper.dispatchAll(); - HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc( - ADDR_AUDIO_SYSTEM, - ADDR_TV); - - mNativeWrapper.onCecMessage(initiateArc); - mTestLooper.dispatchAll(); - - HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( - ADDR_TV, - ADDR_AUDIO_SYSTEM); - // 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); - mNativeWrapper.clearResultMessages(); + initiateArcAndValidate(); mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); mTestLooper.dispatchAll(); @@ -1565,4 +1599,59 @@ public class HdmiCecLocalDeviceTvTest { assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); } + + @Test + public void fromArcToEarc_SamRemainsOn() { + initateSamAndValidate(); + + // 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(); + + initiateArcAndValidate(); + + assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); + + mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); + mTestLooper.dispatchAll(); + + HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( + ADDR_TV, + ADDR_AUDIO_SYSTEM); + + assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); + assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); + } + + @Test + public void disableEarc_SamRemainsOn() { + initateSamAndValidate(); + + // 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(); + + mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); + mTestLooper.dispatchAll(); + assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); + + mHdmiControlService.initializeEarcLocalDevice(HdmiControlService.INITIATED_BY_BOOT_UP); + HdmiEarcLocalDevice mHdmiEarcLocalDeviceTx = mHdmiControlService.getEarcLocalDevice(); + mHdmiEarcLocalDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_CONNECTED); + mTestLooper.moveTimeForward(HdmiEarcLocalDeviceTx.REPORT_CAPS_MAX_DELAY_MS + 1); + mTestLooper.dispatchAll(); + verify(mAudioManager, times(1)).setWiredDeviceConnectionState( + any(), eq(1)); + + assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); + + } }