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

Commit fc5189ff authored by Venkatarama Avadhani's avatar Venkatarama Avadhani Committed by Nathalie Le Clair
Browse files

EArc AIDL Binding

Add the binding to EARC AIDL in android.hardware.hdmi.earc.

Bug: 240388105
Test: atest VtsHalTvHdmiEArcAidlTargetTest
      atest VtsHalTvHdmiConnectionAidlTargetTest
      atest VtsHalTvHdmiCecAidlTargetTest
Change-Id: I25f6b8ae60858cb51e5d7b3b162e453b04db9e27
parent fbd63fbe
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -101,6 +101,8 @@ java_library_static {
    defaults: ["platform_service_defaults"],
    srcs: [
        ":android.hardware.biometrics.face-V3-java-source",
        ":android.hardware.tv.hdmi.connection-V1-java-source",
        ":android.hardware.tv.hdmi.earc-V1-java-source",
        ":statslog-art-java-gen",
        ":statslog-contexthub-java-gen",
        ":services.core-sources",
@@ -160,6 +162,7 @@ java_library_static {
        "android.hardware.tv.cec-V1.1-java",
        "android.hardware.tv.hdmi.cec-V1-java",
        "android.hardware.tv.hdmi.connection-V1-java",
        "android.hardware.tv.hdmi.earc-V1-java",
        "android.hardware.weaver-V1.0-java",
        "android.hardware.weaver-V2-java",
        "android.hardware.biometrics.face-V1.0-java",
+14 −6
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.server.hdmi;
import android.annotation.IntDef;
import android.annotation.StringDef;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.tv.hdmi.connection.HpdSignal;
import android.hardware.tv.hdmi.earc.IEArcStatus;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -599,10 +601,13 @@ final class Constants {
    })
    @interface RcProfileSource {}

    static final int HDMI_EARC_STATUS_IDLE = 0;             // IDLE1
    static final int HDMI_EARC_STATUS_EARC_PENDING = 1;     // DISC1 and DISC2
    static final int HDMI_EARC_STATUS_ARC_PENDING = 2;      // IDLE2 for ARC
    static final int HDMI_EARC_STATUS_EARC_CONNECTED = 3;   // eARC connected
    static final int HDMI_EARC_STATUS_IDLE = IEArcStatus.STATUS_IDLE; // IDLE1
    static final int HDMI_EARC_STATUS_EARC_PENDING =
            IEArcStatus.STATUS_EARC_PENDING; // DISC1 and DISC2
    static final int HDMI_EARC_STATUS_ARC_PENDING = IEArcStatus.STATUS_ARC_PENDING; // IDLE2 for ARC
    static final int HDMI_EARC_STATUS_EARC_CONNECTED =
            IEArcStatus.STATUS_EARC_CONNECTED; // eARC connected

    @IntDef({
            HDMI_EARC_STATUS_IDLE,
            HDMI_EARC_STATUS_EARC_PENDING,
@@ -611,8 +616,11 @@ final class Constants {
            })
    @interface EarcStatus {}

    static final int HDMI_HPD_TYPE_PHYSICAL = 0;   // Default. Physical hotplug signal.
    static final int HDMI_HPD_TYPE_STATUS_BIT = 1; // HDMI_HPD status bit.
    static final int HDMI_HPD_TYPE_PHYSICAL =
            HpdSignal.HDMI_HPD_PHYSICAL; // Default. Physical hotplug signal.
    static final int HDMI_HPD_TYPE_STATUS_BIT =
            HpdSignal.HDMI_HPD_STATUS_BIT; // HDMI_HPD status bit.

    @IntDef({
            HDMI_HPD_TYPE_PHYSICAL,
            HDMI_HPD_TYPE_STATUS_BIT
+119 −17
Original line number Diff line number Diff line
@@ -16,8 +16,14 @@

package com.android.server.hdmi;

import android.hardware.tv.hdmi.earc.IEArc;
import android.hardware.tv.hdmi.earc.IEArcCallback;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;

import com.android.internal.annotations.VisibleForTesting;

@@ -29,6 +35,89 @@ final class HdmiEarcController {

    private final HdmiControlService mService;

    private EArcHalWrapper mEArcAidl;

    private final class EArcHalWrapper implements IBinder.DeathRecipient {
        private IEArc mEArc;
        private IEArcCallback mEArcCallback;

        @Override
        public void binderDied() {
            mEArc.asBinder().unlinkToDeath(this, 0);
            connectToHal();
            if (mEArcCallback != null) {
                nativeSetCallback(mEArcCallback);
            }
        }

        boolean connectToHal() {
            mEArc =
                    IEArc.Stub.asInterface(
                            ServiceManager.getService(IEArc.DESCRIPTOR + "/default"));
            if (mEArc == null) {
                return false;
            }
            try {
                mEArc.asBinder().linkToDeath(this, 0);
            } catch (RemoteException e) {
                HdmiLogger.error("Couldn't link callback object: ", e);
            }
            return true;
        }

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

        public void nativeSetEArcEnabled(boolean enabled) {
            try {
                mEArc.setEArcEnabled(enabled);
            } catch (ServiceSpecificException sse) {
                HdmiLogger.error(
                        "Could not set eARC enabled to " + enabled + ". Error: ", sse.errorCode);
            } catch (RemoteException re) {
                HdmiLogger.error("Could not set eARC enabled to " + enabled + ":. Exception: ", re);
            }
        }

        public boolean nativeIsEArcEnabled() {
            try {
                return mEArc.isEArcEnabled();
            } catch (RemoteException re) {
                HdmiLogger.error("Could not read if eARC is enabled. Exception: ", re);
                return false;
            }
        }

        public void nativeSetCallback(IEArcCallback callback) {
            mEArcCallback = callback;
            try {
                mEArc.setCallback(callback);
            } catch (RemoteException re) {
                HdmiLogger.error("Could not set callback. Exception: ", re);
            }
        }

        public byte nativeGetState(int portId) {
            try {
                return mEArc.getState(portId);
            } catch (RemoteException re) {
                HdmiLogger.error("Could not get eARC state. Exception: ", re);
                return -1;
            }
        }

        public byte[] nativeGetLastReportedAudioCapabilities(int portId) {
            try {
                return mEArc.getLastReportedAudioCapabilities(portId);
            } catch (RemoteException re) {
                HdmiLogger.error(
                        "Could not read last reported audio capabilities. Exception: ", re);
                return null;
            }
        }
    }

    // Private constructor. Use HdmiEarcController.create().
    private HdmiEarcController(HdmiControlService service) {
        mService = service;
@@ -47,12 +136,21 @@ final class HdmiEarcController {
    static HdmiEarcController create(HdmiControlService service) {
        // TODO add the native wrapper and return null if eARC HAL is not present.
        HdmiEarcController controller = new HdmiEarcController(service);
        controller.init();
        if (!controller.init()) {
            HdmiLogger.warning("Could not connect to eARC AIDL HAL.");
            return null;
        }
        return controller;
    }

    private void init() {
    private boolean init() {
        mEArcAidl = new EArcHalWrapper();
        if (mEArcAidl.nativeInit()) {
            mControlHandler = new Handler(mService.getServiceLooper());
            mEArcAidl.nativeSetCallback(new EarcAidlCallback());
            return true;
        }
        return false;
    }

    private void assertRunOnServiceThread() {
@@ -73,9 +171,7 @@ final class HdmiEarcController {
    @HdmiAnnotations.ServiceThreadOnly
    void setEarcEnabled(boolean enabled) {
        assertRunOnServiceThread();
        // Stub.
        // TODO: bind to native.
        // TODO: handle error return values here, with logging.
        mEArcAidl.nativeSetEArcEnabled(enabled);
    }

    /**
@@ -86,23 +182,21 @@ final class HdmiEarcController {
    @HdmiAnnotations.ServiceThreadOnly
    @Constants.EarcStatus
    int getState(int portId) {
        // Stub.
        // TODO: bind to native.
        return Constants.HDMI_EARC_STATUS_IDLE;
        return mEArcAidl.nativeGetState(portId);
    }

    /**
     * Ask the HAL to report the last eARC capabilities that the connected audio system reported.
     *
     * @return the raw eARC capabilities
     */
    @HdmiAnnotations.ServiceThreadOnly
    byte[] getLastReportedCaps() {
        // Stub. TODO: bind to native.
        return new byte[] {};
    byte[] getLastReportedCaps(int portId) {
        return mEArcAidl.nativeGetLastReportedAudioCapabilities(portId);
    }

    final class EarcCallback {
        public void onStateChange(@Constants.EarcStatus int status, int portId) {
    final class EarcAidlCallback extends IEArcCallback.Stub {
        public void onStateChange(@Constants.EarcStatus byte status, int portId) {
            runOnServiceThread(
                    () -> mService.handleEarcStateChange(status, portId));
        }
@@ -111,7 +205,15 @@ final class HdmiEarcController {
            runOnServiceThread(
                    () -> mService.handleEarcCapabilitiesReported(rawCapabilities, portId));
        }

        @Override
        public synchronized String getInterfaceHash() throws RemoteException {
            return IEArcCallback.Stub.HASH;
        }

    // TODO: bind to native.
        @Override
        public int getInterfaceVersion() throws RemoteException {
            return IEArcCallback.Stub.VERSION;
        }
    }
}