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

Commit 7fe2ba57 authored by Arthur Ishiguro's avatar Arthur Ishiguro
Browse files

Framework changes for Context Hub AIDL

Bug: 194285834
Test: Load on device
Change-Id: I3a0ffa7f3e8af0fa0d127f2e7176c3b0228ef989
parent 5c527096
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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",
+23 −0
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
@@ -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();
        }
+105 −3
Original line number Diff line number Diff line
@@ -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.
     *
@@ -160,6 +189,25 @@ import java.util.List;
        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;
    }

    /**
     * Creates a HIDL ContextHubMsg object to send to a nanoapp.
     *
@@ -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;
        }
    }
}
+158 −0
Original line number Diff line number Diff line
@@ -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.
     */