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

Commit cb0a0c5e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add ArcTerminationActionFromAvr and test."

parents eda5f459 21674275
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.hdmi;

import android.hardware.tv.cec.V1_0.SendMessageResult;

/**
 * Feature action that handles Audio Return Channel terminated by AVR devices.
 */
public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction {

    // State in which waits for ARC response.
    private static final int STATE_WAITING_FOR_INITIATE_ARC_RESPONSE = 1;
    private static final int STATE_ARC_TERMINATED = 2;

    // the required maximum response time specified in CEC 9.2
    private static final int TIMEOUT_MS = 1000;

    ArcTerminationActionFromAvr(HdmiCecLocalDevice source) {
        super(source);
    }

    @Override
    boolean start() {
        mState = STATE_WAITING_FOR_INITIATE_ARC_RESPONSE;
        addTimer(mState, TIMEOUT_MS);
        sendTerminateArc();
        return true;
    }

    @Override
    boolean processCommand(HdmiCecMessage cmd) {
        if (mState != STATE_WAITING_FOR_INITIATE_ARC_RESPONSE) {
            return false;
        }
        switch (cmd.getOpcode()) {
            case Constants.MESSAGE_REPORT_ARC_TERMINATED:
                mState = STATE_ARC_TERMINATED;
                audioSystem().setArcStatus(false);
                finish();
                return true;
        }
        return false;
    }

    @Override
    void handleTimerEvent(int state) {
        if (mState != state) {
            return;
        }

        switch (mState) {
            case STATE_WAITING_FOR_INITIATE_ARC_RESPONSE:
                handleTerminateArcTimeout();
                break;
        }
    }

    protected void sendTerminateArc() {
        sendCommand(HdmiCecMessageBuilder.buildTerminateArc(getSourceAddress(), Constants.ADDR_TV),
            result -> {
                if (result != SendMessageResult.SUCCESS) {
                    HdmiLogger.debug("Terminate ARC was not successfully sent.");
                    finish();
                }
            });
    }

    private void handleTerminateArcTimeout() {
        HdmiLogger.debug("handleTerminateArcTimeout");
        finish();
    }
}
+148 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.hdmi;

import static com.google.common.truth.Truth.assertThat;

import android.annotation.Nullable;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.os.Looper;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link ArcTerminationActionFromAvr}
 */
@SmallTest
@RunWith(JUnit4.class)
public class ArcTerminationActionFromAvrTest {

    private HdmiDeviceInfo mDeviceInfoForTests;
    private HdmiCecLocalDeviceAudioSystem mHdmiCecLocalDeviceAudioSystem;
    private ArcTerminationActionFromAvr mAction;

    private TestLooper mTestLooper = new TestLooper();
    private boolean mSendCecCommandSuccess;
    private boolean mShouldDispatchReportArcTerminated;
    private boolean mArcEnabled;
    private boolean mSetArcStatusCalled;

    @Before
    public void setUp() {
        mDeviceInfoForTests = new HdmiDeviceInfo(1000, 1);

        HdmiControlService hdmiControlService = new HdmiControlService(null) {
            @Override
            void sendCecCommand(HdmiCecMessage command,
                @Nullable SendMessageCallback callback) {
                switch (command.getOpcode()) {
                    case Constants.MESSAGE_TERMINATE_ARC:
                        if (callback != null) {
                            callback.onSendCompleted(mSendCecCommandSuccess
                                ? SendMessageResult.SUCCESS : SendMessageResult.NACK);
                        }
                        if (mShouldDispatchReportArcTerminated) {
                            mHdmiCecLocalDeviceAudioSystem.dispatchMessage(
                                HdmiCecMessageBuilder.buildReportArcTerminated(
                                    Constants.ADDR_TV,
                                    mHdmiCecLocalDeviceAudioSystem.mAddress));
                        }
                        break;
                    default:
                        throw new IllegalArgumentException("Unexpected message");
                }
            }

            @Override
            boolean isPowerStandby() {
                return false;
            }

            @Override
            boolean isAddressAllocated() {
                return true;
            }

            @Override
            Looper getServiceLooper() {
                return mTestLooper.getLooper();
            }
        };

        mHdmiCecLocalDeviceAudioSystem =
            new HdmiCecLocalDeviceAudioSystem(hdmiControlService) {
                @Override
                HdmiDeviceInfo getDeviceInfo() {
                    return mDeviceInfoForTests;
                }

                @Override
                void setArcStatus(boolean enabled) {
                    mSetArcStatusCalled = true;
                    mArcEnabled = enabled;
                }
            };
        mHdmiCecLocalDeviceAudioSystem.init();
        Looper looper = mTestLooper.getLooper();
        hdmiControlService.setIoLooper(looper);

        mArcEnabled = true;
        mAction = new ArcTerminationActionFromAvr(mHdmiCecLocalDeviceAudioSystem);
    }

    @Test
    public void testSendMessage_NotSuccess() {
        mSendCecCommandSuccess = false;
        mShouldDispatchReportArcTerminated = false;
        mSetArcStatusCalled = false;
        mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);

        mTestLooper.dispatchAll();
        assertThat(mSetArcStatusCalled).isFalse();
        assertThat(mArcEnabled).isTrue();
    }

    @Test
    public void testReportArcTerminated_NotReceived() {
        mSendCecCommandSuccess = true;
        mShouldDispatchReportArcTerminated = false;
        mSetArcStatusCalled = false;
        mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);

        mTestLooper.moveTimeForward(1000);
        mTestLooper.dispatchAll();
        assertThat(mSetArcStatusCalled).isFalse();
        assertThat(mArcEnabled).isTrue();
    }

    @Test
    public void testReportArcTerminated_Received() {
        mSendCecCommandSuccess = true;
        mShouldDispatchReportArcTerminated = true;
        mSetArcStatusCalled = false;
        mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);

        mTestLooper.moveTimeForward(1000);
        mTestLooper.dispatchAll();
        assertThat(mSetArcStatusCalled).isTrue();
        assertThat(mArcEnabled).isFalse();
    }
}