Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 210868b9 authored by Nathalie Le Clair's avatar Nathalie Le Clair Committed by Android (Google) Code Review
Browse files

Merge changes I4f262f42,I312edbca

* changes:
  Unit tests for SAM during transitions from and to eARC
  Make naming in Java consistent.
parents 20f0bdae e67e9018
Loading
Loading
Loading
Loading
+30 −30
Original line number Diff line number Diff line
@@ -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 {
+7 −7
Original line number Diff line number Diff line
@@ -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
+108 −19
Original line number Diff line number Diff line
@@ -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,33 @@ public class HdmiCecLocalDeviceTvTest {
        mNativeWrapper.onCecMessage(reportPhysicalAddress);
        mTestLooper.dispatchAll();

        HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc(
                ADDR_AUDIO_SYSTEM,
                ADDR_TV);
        initiateArcAndValidate();

        mNativeWrapper.onCecMessage(initiateArc);
        mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
        mTestLooper.dispatchAll();

        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
        HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination(
                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);
        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();

        assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        mNativeWrapper.clearResultMessages();
        initiateArcAndValidate();

        assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue();

        mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED);
        mTestLooper.dispatchAll();
@@ -1564,5 +1624,34 @@ public class HdmiCecLocalDeviceTvTest {
                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();

    }
}
+3 −3
Original line number Diff line number Diff line
@@ -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));
+3 −3
Original line number Diff line number Diff line
@@ -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();