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

Commit 5e21bb07 authored by Nathalie Le Clair's avatar Nathalie Le Clair
Browse files

Fix unit tests after binding to the eARC HAL

The binding between eARC HAL and eARC framework needs to be stubbed in
tests. Otherwise, unit tests will fail on devices that don´t have an
eARC HAL.

Test: atest com.android.server.hdmi
Bug: 240388105
Change-Id: Id94cad548762f48be74da8ac785c16ec28fae3e7
parent fc5189ff
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -895,6 +895,11 @@ public class HdmiControlService extends SystemService {
        mCecController = cecController;
    }

    @VisibleForTesting
    void setEarcController(HdmiEarcController earcController) {
        mEarcController = earcController;
    }

    @VisibleForTesting
    void setHdmiCecNetwork(HdmiCecNetwork hdmiCecNetwork) {
        mHdmiCecNetwork = hdmiCecNetwork;
+38 −15
Original line number Diff line number Diff line
@@ -35,11 +35,21 @@ final class HdmiEarcController {

    private final HdmiControlService mService;

    private EArcHalWrapper mEArcAidl;
    private EArcNativeWrapper mEArcNativeWrapperImpl;

    private final class EArcHalWrapper implements IBinder.DeathRecipient {
    protected interface EArcNativeWrapper {
        boolean nativeInit();
        void nativeSetEArcEnabled(boolean enabled);
        boolean nativeIsEArcEnabled();
        void nativeSetCallback(EarcAidlCallback callback);
        byte nativeGetState(int portId);
        byte[] nativeGetLastReportedAudioCapabilities(int portId);
    }

    private static final class EArcNativeWrapperImpl implements EArcNativeWrapper,
            IBinder.DeathRecipient {
        private IEArc mEArc;
        private IEArcCallback mEArcCallback;
        private EarcAidlCallback mEArcCallback;

        @Override
        public void binderDied() {
@@ -65,10 +75,12 @@ final class HdmiEarcController {
            return true;
        }

        @Override
        public boolean nativeInit() {
            return connectToHal();
        }

        @Override
        public void nativeSetEArcEnabled(boolean enabled) {
            try {
                mEArc.setEArcEnabled(enabled);
@@ -80,6 +92,7 @@ final class HdmiEarcController {
            }
        }

        @Override
        public boolean nativeIsEArcEnabled() {
            try {
                return mEArc.isEArcEnabled();
@@ -89,7 +102,8 @@ final class HdmiEarcController {
            }
        }

        public void nativeSetCallback(IEArcCallback callback) {
        @Override
        public void nativeSetCallback(EarcAidlCallback callback) {
            mEArcCallback = callback;
            try {
                mEArc.setCallback(callback);
@@ -98,6 +112,7 @@ final class HdmiEarcController {
            }
        }

        @Override
        public byte nativeGetState(int portId) {
            try {
                return mEArc.getState(portId);
@@ -107,6 +122,7 @@ final class HdmiEarcController {
            }
        }

        @Override
        public byte[] nativeGetLastReportedAudioCapabilities(int portId) {
            try {
                return mEArc.getLastReportedAudioCapabilities(portId);
@@ -119,8 +135,9 @@ final class HdmiEarcController {
    }

    // Private constructor. Use HdmiEarcController.create().
    private HdmiEarcController(HdmiControlService service) {
    private HdmiEarcController(HdmiControlService service, EArcNativeWrapper nativeWrapper) {
        mService = service;
        mEArcNativeWrapperImpl = nativeWrapper;
    }

    /**
@@ -134,20 +151,26 @@ final class HdmiEarcController {
     *         returns {@code null}.
     */
    static HdmiEarcController create(HdmiControlService service) {
        // TODO add the native wrapper and return null if eARC HAL is not present.
        HdmiEarcController controller = new HdmiEarcController(service);
        if (!controller.init()) {
        return createWithNativeWrapper(service, new EArcNativeWrapperImpl());
    }

    /**
     * A factory method with injection of native methods for testing.
     */
    static HdmiEarcController createWithNativeWrapper(HdmiControlService service,
            EArcNativeWrapper nativeWrapper) {
        HdmiEarcController controller = new HdmiEarcController(service, nativeWrapper);
        if (!controller.init(nativeWrapper)) {
            HdmiLogger.warning("Could not connect to eARC AIDL HAL.");
            return null;
        }
        return controller;
    }

    private boolean init() {
        mEArcAidl = new EArcHalWrapper();
        if (mEArcAidl.nativeInit()) {
    private boolean init(EArcNativeWrapper nativeWrapper) {
        if (nativeWrapper.nativeInit()) {
            mControlHandler = new Handler(mService.getServiceLooper());
            mEArcAidl.nativeSetCallback(new EarcAidlCallback());
            mEArcNativeWrapperImpl.nativeSetCallback(new EarcAidlCallback());
            return true;
        }
        return false;
@@ -171,7 +194,7 @@ final class HdmiEarcController {
    @HdmiAnnotations.ServiceThreadOnly
    void setEarcEnabled(boolean enabled) {
        assertRunOnServiceThread();
        mEArcAidl.nativeSetEArcEnabled(enabled);
        mEArcNativeWrapperImpl.nativeSetEArcEnabled(enabled);
    }

    /**
@@ -182,7 +205,7 @@ final class HdmiEarcController {
    @HdmiAnnotations.ServiceThreadOnly
    @Constants.EarcStatus
    int getState(int portId) {
        return mEArcAidl.nativeGetState(portId);
        return mEArcNativeWrapperImpl.nativeGetState(portId);
    }

    /**
@@ -192,7 +215,7 @@ final class HdmiEarcController {
     */
    @HdmiAnnotations.ServiceThreadOnly
    byte[] getLastReportedCaps(int portId) {
        return mEArcAidl.nativeGetLastReportedAudioCapabilities(portId);
        return mEArcNativeWrapperImpl.nativeGetLastReportedAudioCapabilities(portId);
    }

    final class EarcAidlCallback extends IEArcCallback.Stub {
+54 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.hdmi.earc.IEArcStatus;

final class FakeEArcNativeWrapper implements HdmiEarcController.EArcNativeWrapper {
    private static final String TAG = "FakeEArcNativeWrapper";

    private boolean mIsEArcEnabled = true;

    @Override
    public boolean nativeInit() {
        return true;
    }

    @Override
    public void nativeSetEArcEnabled(boolean enabled) {
        mIsEArcEnabled = enabled;
    }

    @Override
    public boolean nativeIsEArcEnabled() {
        return mIsEArcEnabled;
    }

    @Override
    public void nativeSetCallback(HdmiEarcController.EarcAidlCallback callback) {
    }

    @Override
    public byte nativeGetState(int portId) {
        return IEArcStatus.STATUS_IDLE;
    }

    @Override
    public byte[] nativeGetLastReportedAudioCapabilities(int portId) {
        return new byte[] {};
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** Fake {@link NativeWrapper} useful for testing. */
/** Fake {@link NativeWrapper} for the HDMI CEC HAL, useful for testing. */
final class FakeNativeWrapper implements NativeWrapper {
    private static final String TAG = "FakeNativeWrapper";

+6 −0
Original line number Diff line number Diff line
@@ -90,6 +90,8 @@ public class HdmiCecLocalDeviceTvTest {
    private HdmiCecController mHdmiCecController;
    private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv;
    private FakeNativeWrapper mNativeWrapper;
    private HdmiEarcController mHdmiEarcController;
    private FakeEArcNativeWrapper mEArcNativeWrapper;
    private FakePowerManagerWrapper mPowerManager;
    private Looper mMyLooper;
    private TestLooper mTestLooper = new TestLooper();
@@ -185,6 +187,10 @@ public class HdmiCecLocalDeviceTvTest {
        mHdmiCecController = HdmiCecController.createWithNativeWrapper(
                mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
        mHdmiControlService.setCecController(mHdmiCecController);
        mEArcNativeWrapper = new FakeEArcNativeWrapper();
        mHdmiEarcController = HdmiEarcController.createWithNativeWrapper(
                mHdmiControlService, mEArcNativeWrapper);
        mHdmiControlService.setEarcController(mHdmiEarcController);
        mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
        HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[2];
        hdmiPortInfos[0] =
Loading