Merge changes I4f262f42,I312edbca

* changes:
  Unit tests for SAM during transitions from and to eARC
  Make naming in Java consistent.
This commit is contained in:
Nathalie Le Clair
2023-02-20 13:31:34 +00:00
committed by Android (Google) Code Review
5 changed files with 159 additions and 70 deletions

View File

@@ -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 {

View File

@@ -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

View File

@@ -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;
@@ -91,7 +93,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 +189,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];
@@ -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);
// <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();
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);
// <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();
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();
}
}

View File

@@ -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));

View File

@@ -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();