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
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 17b6f5d..2e86eb7 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -101,6 +101,8 @@
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 @@
"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",
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 6b5af88..61417ef0 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -19,6 +19,8 @@
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 @@
})
@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 @@
})
@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
diff --git a/services/core/java/com/android/server/hdmi/HdmiEarcController.java b/services/core/java/com/android/server/hdmi/HdmiEarcController.java
index 8522509..2c1aa4f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiEarcController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiEarcController.java
@@ -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 @@
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 @@
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() {
- mControlHandler = new Handler(mService.getServiceLooper());
+ 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 @@
@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 @@
@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 @@
runOnServiceThread(
() -> mService.handleEarcCapabilitiesReported(rawCapabilities, portId));
}
- }
- // TODO: bind to native.
+ @Override
+ public synchronized String getInterfaceHash() throws RemoteException {
+ return IEArcCallback.Stub.HASH;
+ }
+
+ @Override
+ public int getInterfaceVersion() throws RemoteException {
+ return IEArcCallback.Stub.VERSION;
+ }
+ }
}