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

Commit ada37c46 authored by Marvin Ramin's avatar Marvin Ramin
Browse files

Fix missing invocation of HdmiControlStatusListener

HdmiControlStatusListener is invoked with incorrect values and not
updated when DevicePowerStatusAction returns a result.

This has an effect of listeners receiving incorrect values. In addition
this impacts volume control behaviors via CEC.

Bug: 191224732
Test: manual + atest
Change-Id: Ied18ea0c52988851f5caae824c448a0c932600cb
parent 5c7cdbb8
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -2580,7 +2580,8 @@ public class HdmiControlService extends SystemService {
        return null;
    }

    private void addHdmiControlStatusChangeListener(
    @VisibleForTesting
    void addHdmiControlStatusChangeListener(
            final IHdmiControlStatusChangeListener listener) {
        final HdmiControlStatusChangeListenerRecord record =
                new HdmiControlStatusChangeListenerRecord(listener);
@@ -2916,15 +2917,19 @@ public class HdmiControlService extends SystemService {
                    } else {
                        mIsCecAvailable = true;
                    }
                    if (!listeners.isEmpty()) {
                        invokeHdmiControlStatusChangeListenerLocked(listeners,
                                isEnabled, mIsCecAvailable);
                    }
                }
            });
        } else {
            mIsCecAvailable = false;
        }
            if (!listeners.isEmpty()) {
                invokeHdmiControlStatusChangeListenerLocked(listeners, isEnabled, mIsCecAvailable);
            }
        }
    }

    private void invokeHdmiControlStatusChangeListenerLocked(
            Collection<IHdmiControlStatusChangeListener> listeners,
+95 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.content.ContextWrapper;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener;
import android.hardware.hdmi.IHdmiControlStatusChangeListener;
import android.os.Binder;
import android.os.IPowerManager;
import android.os.IThermalService;
@@ -683,6 +684,100 @@ public class HdmiControlServiceTest {
                HdmiControlManager.HDMI_CEC_VERSION_2_0);
    }

    @Test
    public void initCec_statusListener_CecDisabled() {
        HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback();

        mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback);

        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
                HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
        mTestLooper.dispatchAll();

        assertThat(hdmiControlStatusCallback.mCecEnabled).isFalse();
        assertThat(hdmiControlStatusCallback.mCecAvailable).isFalse();
    }

    @Test
    public void initCec_statusListener_CecEnabled_NoCecResponse() {
        HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback();

        mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback);

        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
                HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
        mTestLooper.dispatchAll();
        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
                HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
        mTestLooper.dispatchAll();
        // Hit timeout twice due to retries
        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
        mTestLooper.dispatchAll();
        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
        mTestLooper.dispatchAll();

        assertThat(hdmiControlStatusCallback.mCecEnabled).isTrue();
        assertThat(hdmiControlStatusCallback.mCecAvailable).isFalse();
    }

    @Test
    public void initCec_statusListener_CecEnabled_CecAvailable_TvOn() {
        HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback();
        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
        mTestLooper.dispatchAll();

        mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback);
        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
        mTestLooper.dispatchAll();

        HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
                Constants.ADDR_TV,
                mHdmiControlServiceSpy.playback().mAddress, HdmiControlManager.POWER_STATUS_ON);
        mNativeWrapper.onCecMessage(reportPowerStatus);
        mTestLooper.dispatchAll();

        assertThat(hdmiControlStatusCallback.mCecEnabled).isTrue();
        assertThat(hdmiControlStatusCallback.mCecAvailable).isTrue();
    }

    @Test
    public void initCec_statusListener_CecEnabled_CecAvailable_TvStandby() {
        HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback();
        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
        mTestLooper.dispatchAll();

        mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback);
        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
        mTestLooper.dispatchAll();

        HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
                Constants.ADDR_TV,
                mHdmiControlServiceSpy.playback().mAddress,
                HdmiControlManager.POWER_STATUS_STANDBY);
        mNativeWrapper.onCecMessage(reportPowerStatus);
        mTestLooper.dispatchAll();

        assertThat(hdmiControlStatusCallback.mCecEnabled).isTrue();
        assertThat(hdmiControlStatusCallback.mCecAvailable).isTrue();
    }

    private static class HdmiControlStatusCallback extends IHdmiControlStatusChangeListener.Stub {
        boolean mCecEnabled = false;
        boolean mCecAvailable = false;

        @Override
        public void onStatusChange(int isCecEnabled, boolean isCecAvailable)
                throws RemoteException {
            mCecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED;
            mCecAvailable = isCecAvailable;
        }
    }

    private static class VolumeControlFeatureCallback extends
            IHdmiCecVolumeControlFeatureListener.Stub {
        boolean mCallbackReceived = false;