/*
 * Copyright (C) 2022 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 android.hdmicec.cts;

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

import static org.junit.Assume.assumeTrue;

import org.junit.Before;
import org.junit.Test;

/**
 * Abstract base class for tests for Absolute Volume Control (AVC). Subclasses must call
 * this class's constructor to specify the device type of the DUT and the System Audio device.
 * The three valid pairs of (DUT type, System Audio device type) for AVC are as follows:
 * (Playback, TV); (Playback, Audio System); (TV, Audio System).
 *
 * Currently, it is only feasible to test the case where the DUT is a playback device and the
 * System Audio device is a TV. This is because the CEC adapter responds <Feature Abort> to
 * <Set Audio Volume Level> when it is started as an Audio System.
 */
public abstract class BaseHdmiCecAbsoluteVolumeControlTest extends BaseHdmiCecCtsTest {

    /**
     * Constructor. The test device type and client params (determining the client's device type)
     * passed in here determine the behavior of the tests.
     */
    public BaseHdmiCecAbsoluteVolumeControlTest(@HdmiCecConstants.CecDeviceType int testDeviceType,
            String... clientParams) {
        super(testDeviceType, clientParams);
    }

    /**
     * Returns the audio output device being used.
     */
    public int getAudioOutputDevice() {
        if (mTestDeviceType == HdmiCecConstants.CEC_DEVICE_TYPE_TV) {
            return HdmiCecConstants.DEVICE_OUT_HDMI_ARC;
        } else {
            return HdmiCecConstants.DEVICE_OUT_HDMI;
        }
    }

    @Before
    @Override
    public void setUp() throws Exception {
        super.setUp();

        // This setting must be enabled to use AVC. Start with it disabled to ensure that we can
        // control when the AVC initiation process starts.
        setSettingsValue(HdmiCecConstants.SETTING_VOLUME_CONTROL_ENABLED,
                HdmiCecConstants.VOLUME_CONTROL_DISABLED);

        // Disable and enable CEC on the DUT to clear its knowledge of device feature support.
        // If the DUT isn't a TV, simulate a connected sink as well.
        if (mTestDeviceType == HdmiCecConstants.CEC_DEVICE_TYPE_TV) {
            getDevice().executeShellCommand("cmd hdmi_control cec_setting set hdmi_cec_enabled 0");
            waitForCondition(() -> !isCecAvailable(getDevice()), "Could not disable CEC");
            getDevice().executeShellCommand("cmd hdmi_control cec_setting set hdmi_cec_enabled 1");
            waitForCondition(() -> isCecAvailable(getDevice()), "Could not enable CEC");
        } else {
            simulateCecSinkConnected(getDevice(), getTargetLogicalAddress());
        }

        // Full volume behavior is a prerequisite for AVC. However, we cannot control this
        // condition from CTS tests or shell due to missing permissions. Therefore, we run these
        // tests only if it is already true.
        assumeTrue(isFullVolumeDevice(getAudioOutputDevice()));
    }

    /**
     * Requires the device to be able to adopt CEC 2.0 so that it sends <Give Features>.
     *
     * Tests that the DUT enables and disables AVC in response to changes in the System Audio
     * device's support for <Set Audio Volume Level>. In this test, this support status is
     * communicated through <Report Features> messages.
     */
    @Test
    public void testEnableDisableAvc_cec20_triggeredByReportFeatures() throws Exception {
        // Enable CEC 2.0
        setCec20();

        // Enable CEC volume
        setSettingsValue(HdmiCecConstants.SETTING_VOLUME_CONTROL_ENABLED,
                HdmiCecConstants.VOLUME_CONTROL_ENABLED);

        // Enable System Audio Mode if the System Audio device is an Audio System
        enableSystemAudioModeIfApplicable();

        // Since CEC 2.0 is enabled, DUT should also use <Give Features> to query AVC support
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.GIVE_FEATURES);
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.SET_AUDIO_VOLUME_LEVEL);

        // System Audio device reports support for <Set Audio Volume Level> via <Report Features>
        sendReportFeatures(true);

        // DUT queries audio status
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.GIVE_AUDIO_STATUS);
        checkAbsoluteVolumeControlStatus(false);

        // DUT receives audio status
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_AUDIO_STATUS,
                CecMessage.formatParams(50));
        checkAbsoluteVolumeControlStatus(true);

        // System Audio device reports no support for <Set Audio Volume Level>
        sendReportFeatures(false);
        checkAbsoluteVolumeControlStatus(false);
    }

    /**
     * Tests that the DUT enables and disables AVC in response to changes in the System Audio
     * device's support for <Set Audio Volume Level>. In this test, this support status is
     * communicated through (the lack of) <Feature Abort> responses to <Set Audio Volume Level>.
     */
    @Test
    public void testEnableDisableAvc_triggeredByAvcSupportChanged() throws Exception {
        setSettingsValue(HdmiCecConstants.SETTING_VOLUME_CONTROL_ENABLED,
                HdmiCecConstants.VOLUME_CONTROL_ENABLED);

        enableSystemAudioModeIfApplicable();

        // DUT queries AVC support by sending <Set Audio Volume Level>
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.SET_AUDIO_VOLUME_LEVEL);

        // System Audio device does not respond with <Feature Abort>. DUT queries audio status
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.GIVE_AUDIO_STATUS);
        checkAbsoluteVolumeControlStatus(false);

        // DUT receives audio status
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_AUDIO_STATUS,
                CecMessage.formatParams(50));
        checkAbsoluteVolumeControlStatus(true);

        // System Audio device responds to <Set Audio Volume Level> with
        // <Feature Abort>[Unrecognized opcode]
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.FEATURE_ABORT,
                CecMessage.formatParams(CecOperand.SET_AUDIO_VOLUME_LEVEL + "00"));
        checkAbsoluteVolumeControlStatus(false);
    }

    /**
     * Tests that the DUT enables and disables AVC in response to CEC volume control being
     * enabled or disabled.
     */
    @Test
    public void testEnableAndDisableAVC_triggeredByVolumeControlSettingChange() throws Exception {
        enableSystemAudioModeIfApplicable();

        // System audio device reports support for <Set Audio Volume Level>
        sendReportFeatures(true);

        // Enable CEC volume
        setSettingsValue(HdmiCecConstants.SETTING_VOLUME_CONTROL_ENABLED,
                HdmiCecConstants.VOLUME_CONTROL_ENABLED);

        // DUT queries audio status
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.GIVE_AUDIO_STATUS);
        checkAbsoluteVolumeControlStatus(false);

        // DUT receives audio status
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_AUDIO_STATUS,
                CecMessage.formatParams(50));
        checkAbsoluteVolumeControlStatus(true);

        // CEC volume control is disabled on the DUT
        setSettingsValue(HdmiCecConstants.SETTING_VOLUME_CONTROL_ENABLED,
                HdmiCecConstants.VOLUME_CONTROL_DISABLED);
        checkAbsoluteVolumeControlStatus(false);
    }

    /**
     * Tests that the DUT enables and disables AVC in response to System Audio mode being
     * enabled or disabled.
     *
     * Only valid when the System Audio device is an Audio System.
     */
    @Test
    public void testEnableDisableAvc_triggeredBySystemAudioModeChange() throws Exception {
        assumeTrue("Skipping this test for this setup because the System Audio device "
                        + "is not an Audio System.",
                hdmiCecClient.getSelfDevice().getDeviceType()
                        == HdmiCecConstants.CEC_DEVICE_TYPE_AUDIO_SYSTEM);

        // System audio device reports support for <Set Audio Volume Level>
        sendReportFeatures(true);

        // CEC volume control is enabled on the DUT
        setSettingsValue(HdmiCecConstants.SETTING_VOLUME_CONTROL_ENABLED,
                HdmiCecConstants.VOLUME_CONTROL_ENABLED);

        // Enable System Audio Mode
        broadcastSystemAudioModeMessage(true);

        // DUT queries audio status
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.GIVE_AUDIO_STATUS);
        checkAbsoluteVolumeControlStatus(false);

        // DUT receives audio status
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_AUDIO_STATUS,
                CecMessage.formatParams(50));
        checkAbsoluteVolumeControlStatus(true);

        // System Audio Mode is disabled
        broadcastSystemAudioModeMessage(false);
        checkAbsoluteVolumeControlStatus(false);
    }

    /**
     * Tests that the DUT sends the correct CEC messages when AVC is enabled and Android
     * initiates volume changes.
     */
    @Test
    public void testOutgoingVolumeUpdates() throws Exception {
        // Enable AVC
        setSettingsValue(HdmiCecConstants.SETTING_VOLUME_CONTROL_ENABLED,
                HdmiCecConstants.VOLUME_CONTROL_ENABLED);
        enableSystemAudioModeIfApplicable();
        sendReportFeatures(true);
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.GIVE_AUDIO_STATUS);
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_AUDIO_STATUS,
                CecMessage.formatParams(50));
        checkAbsoluteVolumeControlStatus(true);

        // Calling AudioManager#setStreamVolume should cause the DUT to send
        // <Set Audio Volume Level> with the new volume level as a parameter
        AudioManagerHelper.setDeviceVolume(getDevice(), 80);
        String setAudioVolumeLevelMessage = hdmiCecClient.checkExpectedOutput(
                hdmiCecClient.getSelfDevice(), CecOperand.SET_AUDIO_VOLUME_LEVEL);
        assertThat(CecMessage.getParams(setAudioVolumeLevelMessage)).isEqualTo(80);

        // Calling AudioManager#adjustStreamVolume should cause the DUT to send
        // <User Control Pressed>, <User Control Released>, and <Give Audio Status>
        AudioManagerHelper.raiseVolume(getDevice());
        String userControlPressedMessage = hdmiCecClient.checkExpectedOutput(
                hdmiCecClient.getSelfDevice(), CecOperand.USER_CONTROL_PRESSED);
        assertThat(CecMessage.getParams(userControlPressedMessage))
                .isEqualTo(HdmiCecConstants.CEC_KEYCODE_VOLUME_UP);
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.USER_CONTROL_RELEASED);
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.GIVE_AUDIO_STATUS);
    }

    /**
     * Tests that the DUT notifies AudioManager when it receives <Report Audio Status> from the
     * System Audio device.
     */
    @Test
    public void testIncomingVolumeUpdates() throws Exception {
        // Enable AVC
        setSettingsValue(HdmiCecConstants.SETTING_VOLUME_CONTROL_ENABLED,
                HdmiCecConstants.VOLUME_CONTROL_ENABLED);
        enableSystemAudioModeIfApplicable();
        sendReportFeatures(true);
        hdmiCecClient.checkExpectedOutput(hdmiCecClient.getSelfDevice(),
                CecOperand.GIVE_AUDIO_STATUS);
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_AUDIO_STATUS,
                CecMessage.formatParams(50)); // Volume 50, mute off
        checkAbsoluteVolumeControlStatus(true);

        // Volume and mute status should match the initial <Report Audio Status>
        assertApproximateDeviceVolumeAndMute(50, false);

        // Test an incoming <Report Audio Status> that does not mute the device
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_AUDIO_STATUS,
                CecMessage.formatParams(90)); // Volume 90, mute off
        assertApproximateDeviceVolumeAndMute(90, false);

        // Test an incoming <Report Audio Status> that mutes the device
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_AUDIO_STATUS,
                CecMessage.formatParams(70 + 0b1000_0000)); // Volume 70, mute on
        assertApproximateDeviceVolumeAndMute(0, true);
    }

    /**
     * Enables System Audio Mode if the System Audio device is an Audio System.
     */
    private void enableSystemAudioModeIfApplicable() throws Exception {
        if (hdmiCecClient.getSelfDevice() == LogicalAddress.AUDIO_SYSTEM) {
            broadcastSystemAudioModeMessage(true);
        }
    }

    /**
     * Has the CEC client broadcast a message enabling or disabling System Audio Mode.
     */
    private void broadcastSystemAudioModeMessage(boolean val) throws Exception {
        hdmiCecClient.sendCecMessage(
                hdmiCecClient.getSelfDevice(),
                LogicalAddress.BROADCAST,
                CecOperand.SET_SYSTEM_AUDIO_MODE,
                CecMessage.formatParams(val ? 1 : 0));
    }

    /**
     * Has the CEC client send a <Report Features> message expressing support or lack of support for
     * <Set Audio Volume Level>.
     */
    private void sendReportFeatures(boolean setAudioVolumeLevelSupport) throws Exception {
        String deviceTypeNibble = hdmiCecClient.getSelfDevice() == LogicalAddress.TV
                ? "80" : "08";
        String featureSupportNibble = setAudioVolumeLevelSupport ? "01" : "00";
        hdmiCecClient.sendCecMessage(hdmiCecClient.getSelfDevice(), CecOperand.REPORT_FEATURES,
                "06:" + deviceTypeNibble + ":00:" + featureSupportNibble);
    }

    /**
     * Checks that the status of Absolute Volume Control on the DUT to match the expected status.
     * Waits and rechecks a limited number of times if the status does not currently match.
     */
    private void checkAbsoluteVolumeControlStatus(boolean enabledStatus) throws Exception {
        String expectedStatus = enabledStatus ? "enabled" : "disabled";
        waitForCondition(() -> getAbsoluteVolumeControlStatus() == enabledStatus,
                "Absolute Volume Control was not " + expectedStatus + " when expected");
    }

    /**
     * Returns the state of Absolute Volume Control on the DUT. This is determined by the
     * volume behavior of the audio output device being used for HDMI audio.
     */
    private boolean getAbsoluteVolumeControlStatus() throws Exception {
        return getDevice()
                .executeShellCommand("dumpsys hdmi_control | grep mIsAbsoluteVolumeControlEnabled:")
                .replace("mIsAbsoluteVolumeControlEnabled:", "").trim()
                .equals("true");
    }

    /**
     * Asserts that the DUT's volume (scale: [0, 100]) is within 5 points of an expected volume.
     * This accounts for small differences due to rounding when converting between volume scales.
     * Also asserts that the DUT's mute status is equal to {@code expectedMute}.
     *
     * Asserting both volume and mute at the same time saves a shell command because both are
     * conveyed in a single log message.
     */
    private void assertApproximateDeviceVolumeAndMute(int expectedVolume, boolean expectedMute)
            throws Exception {
        // Raw output is equal to volume out of 100, plus 128 if muted
        // In practice, if the stream is muted, volume equals 0, so this will be at most 128
        int rawOutput = AudioManagerHelper.getDutAudioVolume(getDevice());

        int actualVolume = rawOutput % 128;
        assertWithMessage("Expected DUT to have volume " + expectedVolume
                + " but was actually " + actualVolume)
                .that(Math.abs(expectedVolume - actualVolume) <= 5)
                .isTrue();

        boolean actualMute = rawOutput >= 128;
        String expectedMuteString = expectedMute ? "muted" : "unmuted";
        String actualMuteString = actualMute ? "muted" : "unmuted";
        assertWithMessage("Expected DUT to be " + expectedMuteString
                + "but was actually " + actualMuteString)
                .that(expectedMute)
                .isEqualTo(actualMute);
    }
}
