Framework changes for Context Hub AIDL

Bug: 194285834
Test: Load on device
Change-Id: I3a0ffa7f3e8af0fa0d127f2e7176c3b0228ef989
This commit is contained in:
Arthur Ishiguro 2021-08-26 09:30:02 -07:00
parent 5c52709662
commit 7fe2ba5702
5 changed files with 291 additions and 4 deletions

View File

@ -238,6 +238,7 @@ java_library {
"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",

View File

@ -79,6 +79,29 @@ public class ContextHubInfo implements Parcelable {
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

View File

@ -359,7 +359,10 @@ public class ContextHubService extends IContextHubService.Stub {
* @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();
}

View File

@ -33,6 +33,7 @@ import android.hardware.location.NanoAppState;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@ -44,6 +45,11 @@ import java.util.List;
private static final String TAG = "ContextHubServiceUtil";
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 @@ import java.util.List;
}
/**
* 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(
@ -141,6 +147,29 @@ import java.util.List;
return hidlNanoAppBinary;
}
/**
* 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.
*
@ -154,7 +183,26 @@ import java.util.List;
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;
@ -179,6 +227,29 @@ import java.util.List;
return hidlMessage;
}
/**
* 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.
*
@ -194,6 +265,20 @@ import java.util.List;
message.hostEndPoint == HostEndPoint.BROADCAST);
}
/**
* 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.
*
@ -274,4 +359,21 @@ import java.util.List;
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;
}
}
}

View File

@ -30,13 +30,17 @@ import android.hardware.location.NanoAppBinary;
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
@ -140,6 +144,29 @@ public abstract class IContextHubWrapper {
return (proxy == null) ? null : new ContextHubWrapperV1_2(proxy);
}
/**
* 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.
*/
@ -258,6 +285,137 @@ public abstract class IContextHubWrapper {
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.
*/