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

Commit 40355178 authored by Nathalie Le Clair's avatar Nathalie Le Clair
Browse files

Enable and disable eARC in the HAL

Depending on the settings value, enable or disable on boot and wakeup.
Enable when the setting gets enabled.
Disable when the setting gets disabled.

Test: atest
Bug: 240388084

Change-Id: I74a90d26e8cde0f9acfd5eb1b33c845a6a995b18
parent ad77ca9f
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -54,7 +54,7 @@ import java.util.concurrent.ArrayBlockingQueue;
 * Class that models a logical CEC device hosted in this system. Handles initialization, CEC
 * Class that models a logical CEC device hosted in this system. Handles initialization, CEC
 * commands that call for actions customized per device type.
 * commands that call for actions customized per device type.
 */
 */
abstract class HdmiCecLocalDevice {
abstract class HdmiCecLocalDevice extends HdmiLocalDevice {
    private static final String TAG = "HdmiCecLocalDevice";
    private static final String TAG = "HdmiCecLocalDevice";


    private static final int MAX_HDMI_ACTIVE_SOURCE_HISTORY = 10;
    private static final int MAX_HDMI_ACTIVE_SOURCE_HISTORY = 10;
+48 −20
Original line number Original line Diff line number Diff line
@@ -713,8 +713,12 @@ public class HdmiControlService extends SystemService {


            mEarcSupported &= (mEarcController != null);
            mEarcSupported &= (mEarcController != null);
        }
        }
        if (isEarcSupportedAndEnabled()) {
        if (isEarcSupported()) {
            if (isEarcEnabled()) {
                initializeEarc(INITIATED_BY_BOOT_UP);
                initializeEarc(INITIATED_BY_BOOT_UP);
            } else {
                setEarcEnabledInHal(false);
            }
        }
        }


        mHdmiCecConfig.registerChangeListener(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
        mHdmiCecConfig.registerChangeListener(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
@@ -3386,9 +3390,15 @@ public class HdmiControlService extends SystemService {
        }
        }
    }
    }


    private boolean isEarcSupportedAndEnabled() {
    private boolean isEarcEnabled() {
        synchronized (mLock) {
        synchronized (mLock) {
            return mEarcSupported && mEarcEnabled;
            return mEarcEnabled;
        }
    }

    private boolean isEarcSupported() {
        synchronized (mLock) {
            return mEarcSupported;
        }
        }
    }
    }


@@ -3485,7 +3495,8 @@ public class HdmiControlService extends SystemService {
        } else {
        } else {
            Slog.i(TAG, "Device does not support HDMI-CEC.");
            Slog.i(TAG, "Device does not support HDMI-CEC.");
        }
        }
        if (isEarcSupportedAndEnabled()) {
        if (isEarcSupported()) {
            if (isEarcEnabled()) {
                int startReason = -1;
                int startReason = -1;
                switch (wakeUpAction) {
                switch (wakeUpAction) {
                    case WAKE_UP_SCREEN_ON:
                    case WAKE_UP_SCREEN_ON:
@@ -3497,9 +3508,11 @@ public class HdmiControlService extends SystemService {
                    default:
                    default:
                        Slog.e(TAG, "wakeUpAction " + wakeUpAction + " not defined.");
                        Slog.e(TAG, "wakeUpAction " + wakeUpAction + " not defined.");
                        return;
                        return;

                }
                }
                initializeEarc(startReason);
                initializeEarc(startReason);
            } else {
                setEarcEnabledInHal(false);
            }
        }
        }
        // TODO: Initialize MHL local devices.
        // TODO: Initialize MHL local devices.
    }
    }
@@ -4394,6 +4407,7 @@ public class HdmiControlService extends SystemService {


    private void initializeEarc(int initiatedBy) {
    private void initializeEarc(int initiatedBy) {
        Slog.i(TAG, "eARC initialized, reason = " + initiatedBy);
        Slog.i(TAG, "eARC initialized, reason = " + initiatedBy);
        setEarcEnabledInHal(true);
        initializeEarcLocalDevice(initiatedBy);
        initializeEarcLocalDevice(initiatedBy);
    }
    }


@@ -4415,7 +4429,7 @@ public class HdmiControlService extends SystemService {
        synchronized (mLock) {
        synchronized (mLock) {
            mEarcEnabled = (enabled == EARC_FEATURE_ENABLED);
            mEarcEnabled = (enabled == EARC_FEATURE_ENABLED);


            if (!mEarcSupported) {
            if (!isEarcSupported()) {
                Slog.i(TAG, "Enabled/disabled eARC setting, but the hardware doesn´t support eARC. "
                Slog.i(TAG, "Enabled/disabled eARC setting, but the hardware doesn´t support eARC. "
                        + "This settings change doesn´t have an effect.");
                        + "This settings change doesn´t have an effect.");
                return;
                return;
@@ -4448,6 +4462,8 @@ public class HdmiControlService extends SystemService {


    @ServiceThreadOnly
    @ServiceThreadOnly
    private void onDisableEarc() {
    private void onDisableEarc() {
        disableEarcLocalDevice();
        setEarcEnabledInHal(false);
        clearEarcLocalDevice();
        clearEarcLocalDevice();
    }
    }


@@ -4471,5 +4487,17 @@ public class HdmiControlService extends SystemService {
        assertRunOnServiceThread();
        assertRunOnServiceThread();
        return mEarcLocalDevice;
        return mEarcLocalDevice;
    }
    }
    private void disableEarcLocalDevice() {
        if (mEarcLocalDevice == null) {
            return;
        }
        mEarcLocalDevice.disableDevice();
    }


    @ServiceThreadOnly
    @VisibleForTesting
    protected void setEarcEnabledInHal(boolean enabled) {
        assertRunOnServiceThread();
        mEarcController.setEarcEnabled(enabled);
    }
}
}
+4 −1
Original line number Original line Diff line number Diff line
@@ -22,9 +22,12 @@ import android.util.IndentingPrintWriter;
 * Class that models a local eARC device hosted in this system.
 * Class that models a local eARC device hosted in this system.
 * The class contains methods that are common between eARC TX and eARC RX devices.
 * The class contains methods that are common between eARC TX and eARC RX devices.
 */
 */
public class HdmiEarcLocalDevice {
public class HdmiEarcLocalDevice extends HdmiLocalDevice {
    private static final String TAG = "HdmiEarcLocalDevice";
    private static final String TAG = "HdmiEarcLocalDevice";


    protected void disableDevice() {
    }

    /** Dump internal status of HdmiEarcLocalDevice object */
    /** Dump internal status of HdmiEarcLocalDevice object */
    protected void dump(final IndentingPrintWriter pw) {
    protected void dump(final IndentingPrintWriter pw) {
        // Should be overridden in the more specific classes
        // Should be overridden in the more specific classes
+26 −0
Original line number Original line Diff line number Diff line
/*
 * 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 com.android.server.hdmi;

/**
 * Class that models an HDMI device hosted in this system.
 * Can be used to share methods between CEC and eARC local devices.
 * Currently just a placeholder.
 */
abstract class HdmiLocalDevice {
    private static final String TAG = "HdmiLocalDevice";
}
+124 −4
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;


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


@@ -29,6 +30,7 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertEquals;


import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doNothing;
@@ -128,13 +130,13 @@ public class HdmiControlServiceTest {
        mLocalDevices.add(mPlaybackDeviceSpy);
        mLocalDevices.add(mPlaybackDeviceSpy);
        mHdmiPortInfo = new HdmiPortInfo[4];
        mHdmiPortInfo = new HdmiPortInfo[4];
        mHdmiPortInfo[0] =
        mHdmiPortInfo[0] =
                new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x2100, true, false, false);
                new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x2100, true, false, false, false);
        mHdmiPortInfo[1] =
        mHdmiPortInfo[1] =
                new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2200, true, false, false);
                new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2200, true, false, false, false);
        mHdmiPortInfo[2] =
        mHdmiPortInfo[2] =
                new HdmiPortInfo(3, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, false);
                new HdmiPortInfo(3, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true, true);
        mHdmiPortInfo[3] =
        mHdmiPortInfo[3] =
                new HdmiPortInfo(4, HdmiPortInfo.PORT_INPUT, 0x3000, true, false, false);
                new HdmiPortInfo(4, HdmiPortInfo.PORT_INPUT, 0x3000, true, false, false, false);
        mNativeWrapper.setPortInfo(mHdmiPortInfo);
        mNativeWrapper.setPortInfo(mHdmiPortInfo);
        mHdmiControlServiceSpy.initService();
        mHdmiControlServiceSpy.initService();
        mPowerManager = new FakePowerManagerWrapper(mContextSpy);
        mPowerManager = new FakePowerManagerWrapper(mContextSpy);
@@ -1131,6 +1133,124 @@ public class HdmiControlServiceTest {
        verify(mHdmiControlServiceSpy, times(1)).initializeEarcLocalDevice(anyInt());
        verify(mHdmiControlServiceSpy, times(1)).initializeEarcLocalDevice(anyInt());
    }
    }


    @Test
    public void disableCec_DoNotInformHalAboutEarc() {
        mHdmiControlServiceSpy.setEarcSupported(true);
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
                HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
        mTestLooper.dispatchAll();
        Mockito.clearInvocations(mHdmiControlServiceSpy);
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
                HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
        mTestLooper.dispatchAll();
        verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(anyBoolean());
    }

    @Test
    public void disableEarc_informHalAboutEarc() {
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.SETTING_NAME_EARC_ENABLED,
                HdmiControlManager.EARC_FEATURE_ENABLED);
        mHdmiControlServiceSpy.setEarcSupported(true);
        mTestLooper.dispatchAll();
        Mockito.clearInvocations(mHdmiControlServiceSpy);
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.SETTING_NAME_EARC_ENABLED,
                HdmiControlManager.EARC_FEATURE_DISABLED);
        mTestLooper.dispatchAll();
        verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false);
        verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(true);
    }

    @Test
    public void enableCec_DoNotInformHalAboutEarc() {
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
                HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
        mHdmiControlServiceSpy.setEarcSupported(true);
        mTestLooper.dispatchAll();
        Mockito.clearInvocations(mHdmiControlServiceSpy);
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
                HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
        mTestLooper.dispatchAll();
        verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(anyBoolean());
    }

    @Test
    public void enableEarc_informHalAboutEarc() {
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.SETTING_NAME_EARC_ENABLED,
                HdmiControlManager.EARC_FEATURE_DISABLED);
        mHdmiControlServiceSpy.setEarcSupported(true);
        mTestLooper.dispatchAll();
        Mockito.clearInvocations(mHdmiControlServiceSpy);
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.SETTING_NAME_EARC_ENABLED,
                HdmiControlManager.EARC_FEATURE_ENABLED);
        mTestLooper.dispatchAll();
        verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true);
        verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(false);
    }

    @Test
    public void bootWithEarcEnabled_informHalAboutEarc() {
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.SETTING_NAME_EARC_ENABLED,
                HdmiControlManager.EARC_FEATURE_ENABLED);
        mHdmiControlServiceSpy.setEarcSupported(true);
        mTestLooper.dispatchAll();
        Mockito.clearInvocations(mHdmiControlServiceSpy);
        mHdmiControlServiceSpy.initService();
        mTestLooper.dispatchAll();
        verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true);
        verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(false);
    }

    @Test
    public void bootWithEarcDisabled_informHalAboutEarc() {
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.SETTING_NAME_EARC_ENABLED,
                HdmiControlManager.EARC_FEATURE_DISABLED);
        mHdmiControlServiceSpy.setEarcSupported(true);
        mTestLooper.dispatchAll();
        Mockito.clearInvocations(mHdmiControlServiceSpy);
        mHdmiControlServiceSpy.initService();
        mTestLooper.dispatchAll();
        verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false);
        verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(true);
    }

    @Test
    public void wakeUpWithEarcEnabled_informHalAboutEarc() {
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.SETTING_NAME_EARC_ENABLED,
                HdmiControlManager.EARC_FEATURE_ENABLED);
        mHdmiControlServiceSpy.setEarcSupported(true);
        mTestLooper.dispatchAll();
        Mockito.clearInvocations(mHdmiControlServiceSpy);
        mHdmiControlServiceSpy.onWakeUp(WAKE_UP_SCREEN_ON);
        mTestLooper.dispatchAll();
        verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(true);
        verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(false);
    }

    @Test
    public void wakeUpWithEarcDisabled_informHalAboutEarc() {
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.SETTING_NAME_EARC_ENABLED,
                HdmiControlManager.EARC_FEATURE_DISABLED);
        mHdmiControlServiceSpy.setEarcSupported(true);
        mTestLooper.dispatchAll();
        Mockito.clearInvocations(mHdmiControlServiceSpy);
        mHdmiControlServiceSpy.onWakeUp(WAKE_UP_SCREEN_ON);
        mTestLooper.dispatchAll();
        verify(mHdmiControlServiceSpy, times(1)).setEarcEnabledInHal(false);
        verify(mHdmiControlServiceSpy, times(0)).setEarcEnabledInHal(true);
    }

    protected static class MockPlaybackDevice extends HdmiCecLocalDevicePlayback {
    protected static class MockPlaybackDevice extends HdmiCecLocalDevicePlayback {


        private boolean mCanGoToStandby;
        private boolean mCanGoToStandby;