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

Commit 3b3ec4a9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Decouple ARC and SAD" into main

parents 3f712f3a 7566a0b9
Loading
Loading
Loading
Loading
+41 −2
Original line number Original line Diff line number Diff line
@@ -79,6 +79,9 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
    // True by default for all the ARC-enabled ports.
    // True by default for all the ARC-enabled ports.
    private final SparseBooleanArray mArcFeatureEnabled = new SparseBooleanArray();
    private final SparseBooleanArray mArcFeatureEnabled = new SparseBooleanArray();


    @GuardedBy("mLock")
    private List<byte[]> mSupportedSads = new ArrayList<>();

    // Whether the System Audio Control feature is enabled or not. True by default.
    // Whether the System Audio Control feature is enabled or not. True by default.
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private boolean mSystemAudioControlFeatureEnabled;
    private boolean mSystemAudioControlFeatureEnabled;
@@ -858,6 +861,13 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
                new SystemAudioActionFromTv(this, avr.getLogicalAddress(), enabled, callback));
                new SystemAudioActionFromTv(this, avr.getLogicalAddress(), enabled, callback));
    }
    }


    void clearSads() {
        synchronized (mLock) {
            mSupportedSads.clear();
        }
    }


    // # Seq 25
    // # Seq 25
    void setSystemAudioMode(boolean on) {
    void setSystemAudioMode(boolean on) {
        if (!isSystemAudioControlFeatureEnabled() && on) {
        if (!isSystemAudioControlFeatureEnabled() && on) {
@@ -911,13 +921,41 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
    }
    }


    @ServiceThreadOnly
    @ServiceThreadOnly
    void enableArc(List<byte[]> supportedSads) {
    void enableArc() {
        assertRunOnServiceThread();
        assertRunOnServiceThread();
        HdmiLogger.debug("Set Arc Status[old:%b new:true]", mArcEstablished);
        HdmiLogger.debug("Set Arc Status[old:%b new:true]", mArcEstablished);


        enableAudioReturnChannel(true);
        enableAudioReturnChannel(true);
        notifyArcStatusToAudioService(true, supportedSads);
        //Ensure mSupportedSads is empty before fetching SADs
        synchronized (mLock) {
            mSupportedSads.clear();
        }
        notifyArcStatusToAudioService(true, mSupportedSads);
        mArcEstablished = true;
        mArcEstablished = true;

        // Avoid triggering duplicate RequestSadAction events.
        // This could lead to unexpected responses from the AVR and cause the TV to receive data
        // out of order. The SAD report does not provide information about the order of events.
        if (hasAction(RequestSadAction.class)) {
            return;
        }

        // Send Request SAD to get real SAD instead of default empty
        RequestSadAction action = new RequestSadAction(
                this, Constants.ADDR_AUDIO_SYSTEM,
                new RequestSadAction.RequestSadCallback() {
                    @Override
                    public void onRequestSadDone(List<byte[]> supportedSadsDone) {
                        synchronized (mLock) {
                            mSupportedSads = supportedSadsDone;
                        }
                        notifyArcStatusToAudioService(false, new ArrayList<>());
                        synchronized (mLock) {
                            notifyArcStatusToAudioService(true, mSupportedSads);
                        }
                    }
                });
        addAndStartAction(action);
    }
    }


    @ServiceThreadOnly
    @ServiceThreadOnly
@@ -928,6 +966,7 @@ public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        enableAudioReturnChannel(false);
        enableAudioReturnChannel(false);
        notifyArcStatusToAudioService(false, new ArrayList<>());
        notifyArcStatusToAudioService(false, new ArrayList<>());
        mArcEstablished = false;
        mArcEstablished = false;
        clearSads();
    }
    }


    /**
    /**
+14 −29
Original line number Original line Diff line number Diff line
@@ -60,18 +60,6 @@ final class SetArcTransmissionStateAction extends HdmiCecFeatureAction {
    boolean start() {
    boolean start() {
        // Seq #37.
        // Seq #37.
        if (mEnabled) {
        if (mEnabled) {
            // Avoid triggering duplicate RequestSadAction events.
            // This could lead to unexpected responses from the AVR and cause the TV to receive data
            // out of order. The SAD report does not provide information about the order of events.
            if ((tv().hasAction(RequestSadAction.class))) {
                return true;
            }
            // Request SADs before enabling ARC
            RequestSadAction action = new RequestSadAction(
                    localDevice(), Constants.ADDR_AUDIO_SYSTEM,
                    new RequestSadAction.RequestSadCallback() {
                        @Override
                        public void onRequestSadDone(List<byte[]> supportedSads) {
            // Enable ARC status immediately before sending <Report Arc Initiated>.
            // Enable ARC status immediately before sending <Report Arc Initiated>.
            // If AVR responds with <Feature Abort>, disable ARC status again.
            // If AVR responds with <Feature Abort>, disable ARC status again.
            // This is different from spec that says that turns ARC status to
            // This is different from spec that says that turns ARC status to
@@ -80,15 +68,12 @@ final class SetArcTransmissionStateAction extends HdmiCecFeatureAction {
            // But implemented this way to save the time having to wait for
            // But implemented this way to save the time having to wait for
            // <Feature Abort>.
            // <Feature Abort>.
            Slog.i(TAG, "Enabling ARC");
            Slog.i(TAG, "Enabling ARC");
                            tv().enableArc(supportedSads);
            tv().enableArc();
            // If succeeds to send <Report ARC Initiated>, wait general timeout to
            // If succeeds to send <Report ARC Initiated>, wait general timeout to
            // check whether there is no <Feature Abort> for <Report ARC Initiated>.
            // check whether there is no <Feature Abort> for <Report ARC Initiated>.
            mState = STATE_WAITING_TIMEOUT;
            mState = STATE_WAITING_TIMEOUT;
            addTimer(mState, HdmiConfig.TIMEOUT_MS);
            addTimer(mState, HdmiConfig.TIMEOUT_MS);
            sendReportArcInitiated();
            sendReportArcInitiated();
                        }
                    });
            addAndStartAction(action);
        } else {
        } else {
            disableArc();
            disableArc();
            finish();
            finish();
+2 −53
Original line number Original line Diff line number Diff line
@@ -341,18 +341,9 @@ public class HdmiCecLocalDeviceTvTest {
        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
                ADDR_TV,
                ADDR_TV,
                ADDR_AUDIO_SYSTEM);
                ADDR_AUDIO_SYSTEM);
        // <Report ARC Initiated> should only be sent after SAD querying is done
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(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(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        // But we need to check SADs started to be queried at this time
        assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
        mNativeWrapper.clearResultMessages();
        mNativeWrapper.clearResultMessages();
    }
    }


@@ -752,17 +743,6 @@ public class HdmiCecLocalDeviceTvTest {
        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
                ADDR_TV,
                ADDR_TV,
                ADDR_AUDIO_SYSTEM);
                ADDR_AUDIO_SYSTEM);
        // <Report ARC Initiated> should only be sent after SAD querying is done
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(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(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
    }
    }


@@ -1067,16 +1047,6 @@ public class HdmiCecLocalDeviceTvTest {
        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
            ADDR_TV,
            ADDR_TV,
            ADDR_AUDIO_SYSTEM);
            ADDR_AUDIO_SYSTEM);
        // <Report ARC Initiated> should only be sent after SAD querying is done
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(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(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        mNativeWrapper.clearResultMessages();
        mNativeWrapper.clearResultMessages();


@@ -1268,16 +1238,6 @@ public class HdmiCecLocalDeviceTvTest {


        mNativeWrapper.onCecMessage(initiateArc);
        mNativeWrapper.onCecMessage(initiateArc);
        mTestLooper.dispatchAll();
        mTestLooper.dispatchAll();

        // 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();
        }

        // ARC should be established after RequestSadAction is finished
        assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);


        mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
        mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
@@ -1421,17 +1381,6 @@ public class HdmiCecLocalDeviceTvTest {
        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
        HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
                ADDR_TV,
                ADDR_TV,
                ADDR_AUDIO_SYSTEM);
                ADDR_AUDIO_SYSTEM);
        // <Report ARC Initiated> should only be sent after SAD querying is done
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(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(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
        assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
    }
    }