Framework changes for Context Hub AIDL
Bug: 194285834
Test: Load on device
Change-Id: I3a0ffa7f3e8af0fa0d127f2e7176c3b0228ef989
diff --git a/Android.bp b/Android.bp
index 9127966f..0ac41c0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -238,6 +238,7 @@
"android.hardware.contexthub-V1.0-java",
"android.hardware.contexthub-V1.1-java",
"android.hardware.contexthub-V1.2-java",
+ "android.hardware.contexthub-V1-java",
"android.hardware.gnss-V1.0-java",
"android.hardware.gnss-V2.1-java",
"android.hardware.health-V1.0-java-constants",
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index 6d56d2d..51045a4 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -79,6 +79,29 @@
mSupportedSensors = new int[0];
mMemoryRegions = new MemoryRegion[0];
}
+ /**
+ * @hide
+ */
+ public ContextHubInfo(android.hardware.contexthub.ContextHubInfo contextHub) {
+ mId = contextHub.id;
+ mName = contextHub.name;
+ mVendor = contextHub.vendor;
+ mToolchain = contextHub.toolchain;
+ mPlatformVersion = 0;
+ mToolchainVersion = 0;
+ mPeakMips = contextHub.peakMips;
+ mStoppedPowerDrawMw = 0;
+ mSleepPowerDrawMw = 0;
+ mPeakPowerDrawMw = 0;
+ mMaxPacketLengthBytes = contextHub.maxSupportedMessageLengthBytes;
+ mChrePlatformId = contextHub.chrePlatformId;
+ mChreApiMajorVersion = contextHub.chreApiMajorVersion;
+ mChreApiMinorVersion = contextHub.chreApiMinorVersion;
+ mChrePatchVersion = (short) contextHub.chrePatchVersion;
+
+ mSupportedSensors = new int[0];
+ mMemoryRegions = new MemoryRegion[0];
+ }
/**
* returns the maximum number of bytes that can be sent per message to the hub
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 27a78dd..a491eb7 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -359,7 +359,10 @@
* @return the IContextHubWrapper interface
*/
private IContextHubWrapper getContextHubWrapper() {
- IContextHubWrapper wrapper = IContextHubWrapper.maybeConnectTo1_2();
+ IContextHubWrapper wrapper = IContextHubWrapper.maybeConnectToAidl();
+ if (wrapper == null) {
+ wrapper = IContextHubWrapper.maybeConnectTo1_2();
+ }
if (wrapper == null) {
wrapper = IContextHubWrapper.maybeConnectTo1_1();
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java b/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
index df6cc05..1de749b 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
@@ -33,6 +33,7 @@
import android.util.Log;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -45,6 +46,11 @@
private static final String CONTEXT_HUB_PERMISSION = Manifest.permission.ACCESS_CONTEXT_HUB;
/**
+ * A host endpoint that is reserved to identify a broadcasted message.
+ */
+ private static final char HOST_ENDPOINT_BROADCAST = 0xFFFF;
+
+ /**
* Creates a ConcurrentHashMap of the Context Hub ID to the ContextHubInfo object given an
* ArrayList of HIDL ContextHub objects.
*
@@ -110,11 +116,11 @@
}
/**
- * Generates the Context Hub HAL's NanoAppBinary object from the client-facing
+ * Generates the Context Hub HAL's HIDL NanoAppBinary object from the client-facing
* android.hardware.location.NanoAppBinary object.
*
* @param nanoAppBinary the client-facing NanoAppBinary object
- * @return the Context Hub HAL's NanoAppBinary object
+ * @return the Context Hub HAL's HIDL NanoAppBinary object
*/
/* package */
static android.hardware.contexthub.V1_0.NanoAppBinary createHidlNanoAppBinary(
@@ -142,6 +148,29 @@
}
/**
+ * Generates the Context Hub HAL's AIDL NanoAppBinary object from the client-facing
+ * android.hardware.location.NanoAppBinary object.
+ *
+ * @param nanoAppBinary the client-facing NanoAppBinary object
+ * @return the Context Hub HAL's AIDL NanoAppBinary object
+ */
+ /* package */
+ static android.hardware.contexthub.NanoappBinary createAidlNanoAppBinary(
+ NanoAppBinary nanoAppBinary) {
+ android.hardware.contexthub.NanoappBinary aidlNanoAppBinary =
+ new android.hardware.contexthub.NanoappBinary();
+
+ aidlNanoAppBinary.nanoappId = nanoAppBinary.getNanoAppId();
+ aidlNanoAppBinary.nanoappVersion = nanoAppBinary.getNanoAppVersion();
+ aidlNanoAppBinary.flags = nanoAppBinary.getFlags();
+ aidlNanoAppBinary.targetChreApiMajorVersion = nanoAppBinary.getTargetChreApiMajorVersion();
+ aidlNanoAppBinary.targetChreApiMinorVersion = nanoAppBinary.getTargetChreApiMinorVersion();
+ aidlNanoAppBinary.customBinary = nanoAppBinary.getBinaryNoHeader();
+
+ return aidlNanoAppBinary;
+ }
+
+ /**
* Generates a client-facing NanoAppState array from a HAL HubAppInfo array.
*
* @param nanoAppInfoList the array of HubAppInfo objects
@@ -154,7 +183,26 @@
for (HubAppInfo appInfo : nanoAppInfoList) {
nanoAppStateList.add(
new NanoAppState(appInfo.info_1_0.appId, appInfo.info_1_0.version,
- appInfo.info_1_0.enabled, appInfo.permissions));
+ appInfo.info_1_0.enabled, appInfo.permissions));
+ }
+
+ return nanoAppStateList;
+ }
+
+ /**
+ * Generates a client-facing NanoAppState array from a AIDL NanoappInfo array.
+ *
+ * @param nanoAppInfoList the array of NanoappInfo objects
+ * @return the corresponding array of NanoAppState objects
+ */
+ /* package */
+ static List<NanoAppState> createNanoAppStateList(
+ android.hardware.contexthub.NanoappInfo[] nanoAppInfoList) {
+ ArrayList<NanoAppState> nanoAppStateList = new ArrayList<>();
+ for (android.hardware.contexthub.NanoappInfo appInfo : nanoAppInfoList) {
+ nanoAppStateList.add(
+ new NanoAppState(appInfo.nanoappId, appInfo.nanoappVersion,
+ appInfo.enabled, new ArrayList<>(Arrays.asList(appInfo.permissions))));
}
return nanoAppStateList;
@@ -180,6 +228,29 @@
}
/**
+ * Creates an AIDL ContextHubMessage object to send to a nanoapp.
+ *
+ * @param hostEndPoint the ID of the client sending the message
+ * @param message the client-facing NanoAppMessage object describing the message
+ * @return the AIDL ContextHubMessage object
+ */
+ /* package */
+ static android.hardware.contexthub.ContextHubMessage createAidlContextHubMessage(
+ short hostEndPoint, NanoAppMessage message) {
+ android.hardware.contexthub.ContextHubMessage aidlMessage =
+ new android.hardware.contexthub.ContextHubMessage();
+
+ aidlMessage.nanoappId = message.getNanoAppId();
+ aidlMessage.hostEndPoint = (char) hostEndPoint;
+ aidlMessage.messageType = message.getMessageType();
+ aidlMessage.messageBody = message.getMessageBody();
+ // This explicit definition is required to avoid erroneous behavior at the binder.
+ aidlMessage.permissions = new String[0];
+
+ return aidlMessage;
+ }
+
+ /**
* Creates a client-facing NanoAppMessage object to send to a client.
*
* @param message the HIDL ContextHubMsg object from a nanoapp
@@ -195,6 +266,20 @@
}
/**
+ * Creates a client-facing NanoAppMessage object to send to a client.
+ *
+ * @param message the AIDL ContextHubMessage object from a nanoapp
+ * @return the NanoAppMessage object
+ */
+ /* package */
+ static NanoAppMessage createNanoAppMessage(
+ android.hardware.contexthub.ContextHubMessage message) {
+ return NanoAppMessage.createMessageFromNanoApp(
+ message.nanoappId, message.messageType, message.messageBody,
+ message.hostEndPoint == HOST_ENDPOINT_BROADCAST);
+ }
+
+ /**
* Checks for location hardware permissions.
*
* @param context the context of the service
@@ -274,4 +359,21 @@
return ContextHubService.CONTEXT_HUB_EVENT_UNKNOWN;
}
}
+
+ /**
+ * Converts an AIDL AsyncEventType to the corresponding ContextHubService.CONTEXT_HUB_EVENT_*.
+ *
+ * @param aidlEventType The AsyncEventType value.
+ * @return The converted event type.
+ */
+ /* package */
+ static int toContextHubEventFromAidl(int aidlEventType) {
+ switch (aidlEventType) {
+ case android.hardware.contexthub.AsyncEventType.RESTARTED:
+ return ContextHubService.CONTEXT_HUB_EVENT_RESTARTED;
+ default:
+ Log.e(TAG, "toContextHubEventFromAidl: Unknown event type: " + aidlEventType);
+ return ContextHubService.CONTEXT_HUB_EVENT_UNKNOWN;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
index d733db0..6c70d9d 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -30,13 +30,17 @@
import android.hardware.location.NanoAppMessage;
import android.hardware.location.NanoAppState;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Log;
import android.util.Pair;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.Set;
/**
* @hide
@@ -141,6 +145,29 @@
}
/**
+ * Attempts to connect to the Contexthub HAL AIDL service, if it exists.
+ *
+ * @return A valid IContextHubWrapper if the connection was successful, null otherwise.
+ */
+ @Nullable
+ public static IContextHubWrapper maybeConnectToAidl() {
+ android.hardware.contexthub.IContextHub proxy = null;
+ final String aidlServiceName =
+ android.hardware.contexthub.IContextHub.class.getCanonicalName() + "/default";
+ if (ServiceManager.isDeclared(aidlServiceName)) {
+ proxy = android.hardware.contexthub.IContextHub.Stub.asInterface(
+ ServiceManager.waitForService(aidlServiceName));
+ if (proxy == null) {
+ Log.e(TAG, "Context Hub AIDL service was declared but was not found");
+ }
+ } else {
+ Log.d(TAG, "Context Hub AIDL service is not declared");
+ }
+
+ return (proxy == null) ? null : new ContextHubWrapperAidl(proxy);
+ }
+
+ /**
* Calls the appropriate getHubs function depending on the HAL version.
*/
public abstract Pair<List<ContextHubInfo>, List<String>> getHubs() throws RemoteException;
@@ -258,6 +285,137 @@
public abstract void registerCallback(int contextHubId, @NonNull ICallback callback)
throws RemoteException;
+ private static class ContextHubWrapperAidl extends IContextHubWrapper {
+ private android.hardware.contexthub.IContextHub mHub;
+
+ private ICallback mCallback = null;
+
+ private ContextHubAidlCallback mAidlCallback = new ContextHubAidlCallback();
+
+ private class ContextHubAidlCallback extends
+ android.hardware.contexthub.IContextHubCallback.Stub {
+ public void handleNanoappInfo(android.hardware.contexthub.NanoappInfo[] appInfo) {
+ List<NanoAppState> nanoAppStateList =
+ ContextHubServiceUtil.createNanoAppStateList(appInfo);
+ mCallback.handleNanoappInfo(nanoAppStateList);
+ }
+
+ public void handleContextHubMessage(android.hardware.contexthub.ContextHubMessage msg,
+ String[] msgContentPerms) {
+ mCallback.handleNanoappMessage(
+ (short) msg.hostEndPoint,
+ ContextHubServiceUtil.createNanoAppMessage(msg),
+ new ArrayList<>(Arrays.asList(msg.permissions)),
+ new ArrayList<>(Arrays.asList(msgContentPerms)));
+ }
+
+ public void handleContextHubAsyncEvent(int evt) {
+ mCallback.handleContextHubEvent(
+ ContextHubServiceUtil.toContextHubEventFromAidl(evt));
+ }
+
+ public void handleTransactionResult(int transactionId, boolean success) {
+ mCallback.handleTransactionResult(transactionId, success);
+ }
+ }
+
+ ContextHubWrapperAidl(android.hardware.contexthub.IContextHub hub) {
+ mHub = hub;
+ }
+
+ public Pair<List<ContextHubInfo>, List<String>> getHubs() throws RemoteException {
+ Set<String> supportedPermissions = new HashSet<>();
+ ArrayList<ContextHubInfo> hubInfoList = new ArrayList<>();
+ for (android.hardware.contexthub.ContextHubInfo hub : mHub.getContextHubs()) {
+ hubInfoList.add(new ContextHubInfo(hub));
+ for (String permission : hub.supportedPermissions) {
+ supportedPermissions.add(permission);
+ }
+ }
+ return new Pair(hubInfoList, new ArrayList<String>(supportedPermissions));
+ }
+
+ // TODO(b/194285834): Implement settings logic
+ public boolean supportsLocationSettingNotifications() {
+ return false;
+ }
+
+ public boolean supportsWifiSettingNotifications() {
+ return false;
+ }
+
+ public boolean supportsAirplaneModeSettingNotifications() {
+ return false;
+ }
+
+ public boolean supportsMicrophoneDisableSettingNotifications() {
+ return false;
+ }
+
+ public void onLocationSettingChanged(boolean enabled) {
+ }
+
+ public void onWifiSettingChanged(boolean enabled) {
+ }
+
+ public void onAirplaneModeSettingChanged(boolean enabled) {
+ }
+
+ public void onMicrophoneDisableSettingChanged(boolean enabled) {
+ }
+
+ @ContextHubTransaction.Result
+ public int sendMessageToContextHub(
+ short hostEndpointId, int contextHubId, NanoAppMessage message)
+ throws RemoteException {
+ return toTransactionResult(mHub.sendMessageToHub(contextHubId,
+ ContextHubServiceUtil.createAidlContextHubMessage(hostEndpointId, message)));
+ }
+
+ @ContextHubTransaction.Result
+ public int loadNanoapp(int contextHubId, NanoAppBinary binary,
+ int transactionId) throws RemoteException {
+ android.hardware.contexthub.NanoappBinary aidlNanoAppBinary =
+ ContextHubServiceUtil.createAidlNanoAppBinary(binary);
+ return toTransactionResult(
+ mHub.loadNanoapp(contextHubId, aidlNanoAppBinary, transactionId));
+ }
+
+ @ContextHubTransaction.Result
+ public int unloadNanoapp(int contextHubId, long nanoappId, int transactionId)
+ throws RemoteException {
+ return toTransactionResult(mHub.unloadNanoapp(contextHubId, nanoappId, transactionId));
+ }
+
+ @ContextHubTransaction.Result
+ public int enableNanoapp(int contextHubId, long nanoappId, int transactionId)
+ throws RemoteException {
+ return toTransactionResult(mHub.enableNanoapp(contextHubId, nanoappId, transactionId));
+ }
+
+ @ContextHubTransaction.Result
+ public int disableNanoapp(int contextHubId, long nanoappId, int transactionId)
+ throws RemoteException {
+ return toTransactionResult(mHub.disableNanoapp(contextHubId, nanoappId, transactionId));
+ }
+
+ @ContextHubTransaction.Result
+ public int queryNanoapps(int contextHubId) throws RemoteException {
+ return toTransactionResult(mHub.queryNanoapps(contextHubId));
+ }
+
+ public void registerCallback(int contextHubId, ICallback callback) throws RemoteException {
+ mCallback = callback;
+ mHub.registerCallback(contextHubId, mAidlCallback);
+ }
+
+ @ContextHubTransaction.Result
+ private int toTransactionResult(boolean success) {
+ return success ? ContextHubTransaction.RESULT_SUCCESS
+ : ContextHubTransaction.RESULT_FAILED_UNKNOWN;
+ }
+ }
+
/**
* An abstract call that defines methods common to all HIDL IContextHubWrappers.
*/