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

Commit b44757c4 authored by Arthur Ishiguro's avatar Arthur Ishiguro
Browse files

Implements endpoint messaging

Bug: 381102453
Flag: android.chre.flags.offload_implementation
Test: make services

Change-Id: I1711739d5a90301cf81832c3d3b356f666cd94d8
parent b9d33554
Loading
Loading
Loading
Loading
+72 −3
Original line number Diff line number Diff line
@@ -18,10 +18,14 @@ package com.android.server.location.contexthub;

import android.content.Context;
import android.hardware.contexthub.EndpointInfo;
import android.hardware.contexthub.ErrorCode;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubMessage;
import android.hardware.contexthub.IContextHubEndpoint;
import android.hardware.contexthub.IContextHubEndpointCallback;
import android.hardware.contexthub.Message;
import android.hardware.contexthub.MessageDeliveryStatus;
import android.hardware.location.ContextHubTransaction;
import android.hardware.location.IContextHubTransactionCallback;
import android.os.IBinder;
import android.os.RemoteException;
@@ -81,13 +85,17 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
    /** The package name of the app that created the endpoint */
    private final String mPackageName;

    /* Transaction manager used for sending reliable messages */
    private final ContextHubTransactionManager mTransactionManager;

    /* package */ ContextHubEndpointBroker(
            Context context,
            IContextHubWrapper contextHubProxy,
            ContextHubEndpointManager endpointManager,
            EndpointInfo halEndpointInfo,
            IContextHubEndpointCallback callback,
            String packageName) {
            String packageName,
            ContextHubTransactionManager transactionManager) {
        mContext = context;
        mContextHubProxy = contextHubProxy;
        mEndpointManager = endpointManager;
@@ -95,6 +103,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        mHalEndpointInfo = halEndpointInfo;
        mContextHubEndpointCallback = callback;
        mPackageName = packageName;
        mTransactionManager = transactionManager;
    }

    @Override
@@ -180,12 +189,57 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
    @Override
    public void sendMessage(
            int sessionId, HubMessage message, IContextHubTransactionCallback callback) {
        // TODO(b/381102453): Implement this
        ContextHubServiceUtil.checkPermissions(mContext);
        Message halMessage = ContextHubServiceUtil.createHalMessage(message);
        synchronized (mOpenSessionLock) {
            if (!mActiveSessionIds.contains(sessionId)
                    && !mActiveRemoteSessionIds.contains(sessionId)) {
                throw new SecurityException(
                        "sendMessage called on inactive session (id= " + sessionId + ")");
            }
        }

        // TODO(b/381102453): Handle permissions
        if (callback == null) {
            try {
                mContextHubProxy.sendMessageToEndpoint(sessionId, halMessage);
            } catch (RemoteException e) {
                Log.w(TAG, "Exception while sending message on session " + sessionId, e);
            }
        } else {
            ContextHubServiceTransaction transaction =
                    mTransactionManager.createSessionMessageTransaction(
                            sessionId, halMessage, mPackageName, callback);
            try {
                mTransactionManager.addTransaction(transaction);
            } catch (IllegalStateException e) {
                Log.e(
                        TAG,
                        "Unable to add a transaction in sendMessageToEndpoint "
                                + "(session ID = "
                                + sessionId
                                + ")",
                        e);
                transaction.onTransactionComplete(
                        ContextHubTransaction.RESULT_FAILED_SERVICE_INTERNAL_FAILURE);
            }
        }
    }

    @Override
    public void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode) {
        // TODO(b/381102453): Implement this
        ContextHubServiceUtil.checkPermissions(mContext);
        MessageDeliveryStatus status = new MessageDeliveryStatus();
        status.messageSequenceNumber = messageSeqNumber;
        status.errorCode = errorCode;
        try {
            mContextHubProxy.sendMessageDeliveryStatusToEndpoint(sessionId, status);
        } catch (RemoteException e) {
            Log.w(
                    TAG,
                    "Exception while sending message delivery status on session " + sessionId,
                    e);
        }
    }

    /** Invoked when the underlying binder of this broker has died at the client process. */
@@ -243,6 +297,21 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        }
    }

    /* package */ void onMessageReceived(int sessionId, HubMessage message) {
        if (mContextHubEndpointCallback != null) {
            try {
                mContextHubEndpointCallback.onMessageReceived(sessionId, message);
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException while calling onMessageReceived", e);
            }
        }
    }

    /* package */ void onMessageDeliveryStatusReceived(
            int sessionId, int sequenceNumber, byte errorCode) {
        mTransactionManager.onMessageDeliveryResponse(sequenceNumber, errorCode == ErrorCode.OK);
    }

    /* package */ boolean hasSessionId(int sessionId) {
        synchronized (mOpenSessionLock) {
            return mPendingSessionIds.contains(sessionId)
+42 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.location.contexthub;
import android.content.Context;
import android.hardware.contexthub.EndpointInfo;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubMessage;
import android.hardware.contexthub.IContextHubEndpoint;
import android.hardware.contexthub.IContextHubEndpointCallback;
import android.os.RemoteException;
@@ -59,6 +60,8 @@ import java.util.concurrent.ConcurrentHashMap;

    private final HubInfoRegistry mHubInfoRegistry;

    private final ContextHubTransactionManager mTransactionManager;

    /** A map of endpoint IDs to brokers currently registered. */
    private final Map<Long, ContextHubEndpointBroker> mEndpointMap = new ConcurrentHashMap<>();

@@ -93,10 +96,14 @@ import java.util.concurrent.ConcurrentHashMap;
    private final boolean mSessionIdsValid;

    /* package */ ContextHubEndpointManager(
            Context context, IContextHubWrapper contextHubProxy, HubInfoRegistry hubInfoRegistry) {
            Context context,
            IContextHubWrapper contextHubProxy,
            HubInfoRegistry hubInfoRegistry,
            ContextHubTransactionManager transactionManager) {
        mContext = context;
        mContextHubProxy = contextHubProxy;
        mHubInfoRegistry = hubInfoRegistry;
        mTransactionManager = transactionManager;
        int[] range = null;
        try {
            range = mContextHubProxy.requestSessionIdRange(SERVICE_SESSION_RANGE);
@@ -162,7 +169,8 @@ import java.util.concurrent.ConcurrentHashMap;
                        this /* endpointManager */,
                        halEndpointInfo,
                        callback,
                        packageName);
                        packageName,
                        mTransactionManager);
        mEndpointMap.put(endpointId, broker);

        try {
@@ -287,6 +295,38 @@ import java.util.concurrent.ConcurrentHashMap;
        }
    }

    @Override
    public void onMessageReceived(int sessionId, HubMessage message) {
        boolean callbackInvoked = false;
        for (ContextHubEndpointBroker broker : mEndpointMap.values()) {
            if (broker.hasSessionId(sessionId)) {
                broker.onMessageReceived(sessionId, message);
                callbackInvoked = true;
                break;
            }
        }

        if (!callbackInvoked) {
            Log.w(TAG, "onMessageReceived: unknown session ID " + sessionId);
        }
    }

    @Override
    public void onMessageDeliveryStatusReceived(int sessionId, int sequenceNumber, byte errorCode) {
        boolean callbackInvoked = false;
        for (ContextHubEndpointBroker broker : mEndpointMap.values()) {
            if (broker.hasSessionId(sessionId)) {
                broker.onMessageDeliveryStatusReceived(sessionId, sequenceNumber, errorCode);
                callbackInvoked = true;
                break;
            }
        }

        if (!callbackInvoked) {
            Log.w(TAG, "onMessageDeliveryStatusReceived: unknown session ID " + sessionId);
        }
    }

    /** @return an available endpoint ID */
    private long getNewEndpointId() {
        synchronized (mEndpointLock) {
+20 −7
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.server.location.contexthub;

import android.hardware.contexthub.EndpointId;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubMessage;
import android.hardware.contexthub.IEndpointCallback;
import android.hardware.contexthub.Message;
import android.hardware.contexthub.MessageDeliveryStatus;
@@ -51,6 +52,12 @@ public class ContextHubHalEndpointCallback

        /** Called when a requested endpoint open session is completed */
        void onEndpointSessionOpenComplete(int sessionId);

        /** Called when a message is received for the session */
        void onMessageReceived(int sessionId, HubMessage message);

        /** Called when a message delivery status is received for the session */
        void onMessageDeliveryStatusReceived(int sessionId, int sequenceNumber, byte errorCode);
    }

    ContextHubHalEndpointCallback(
@@ -83,13 +90,6 @@ public class ContextHubHalEndpointCallback
        mEndpointLifecycleCallback.onEndpointStopped(endpointIds, reason);
    }

    @Override
    public void onMessageReceived(int i, Message message) throws RemoteException {}

    @Override
    public void onMessageDeliveryStatusReceived(int i, MessageDeliveryStatus messageDeliveryStatus)
            throws RemoteException {}

    @Override
    public void onEndpointSessionOpenRequest(
            int i, EndpointId destination, EndpointId initiator, String s) throws RemoteException {
@@ -110,6 +110,19 @@ public class ContextHubHalEndpointCallback
        mEndpointSessionCallback.onEndpointSessionOpenComplete(i);
    }

    @Override
    public void onMessageReceived(int i, Message message) throws RemoteException {
        HubMessage hubMessage = ContextHubServiceUtil.createHubMessage(message);
        mEndpointSessionCallback.onMessageReceived(i, hubMessage);
    }

    @Override
    public void onMessageDeliveryStatusReceived(int i, MessageDeliveryStatus messageDeliveryStatus)
            throws RemoteException {
        mEndpointSessionCallback.onMessageDeliveryStatusReceived(
                i, messageDeliveryStatus.messageSequenceNumber, messageDeliveryStatus.errorCode);
    }

    @Override
    public int getInterfaceVersion() throws RemoteException {
        return IEndpointCallback.VERSION;
+2 −1
Original line number Diff line number Diff line
@@ -334,7 +334,8 @@ public class ContextHubService extends IContextHubService.Stub {
            try {
                registry = new HubInfoRegistry(mContextHubWrapper);
                mEndpointManager =
                        new ContextHubEndpointManager(mContext, mContextHubWrapper, registry);
                        new ContextHubEndpointManager(
                                mContext, mContextHubWrapper, registry, mTransactionManager);
                Log.i(TAG, "Enabling generic offload API");
            } catch (UnsupportedOperationException e) {
                mEndpointManager = null;
+37 −0
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import android.Manifest;
import android.content.Context;
import android.hardware.contexthub.EndpointInfo;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubMessage;
import android.hardware.contexthub.HubServiceInfo;
import android.hardware.contexthub.Message;
import android.hardware.contexthub.V1_0.AsyncEventType;
import android.hardware.contexthub.V1_0.ContextHubMsg;
import android.hardware.contexthub.V1_0.HostEndPoint;
@@ -465,4 +467,39 @@ import java.util.List;
        }
        return outputInfo;
    }

    /**
     * Converts a HubMessage object to a AIDL HAL Message object.
     *
     * @param message the HubMessage message to convert
     * @return the AIDL HAL message
     */
    /* package */
    static Message createHalMessage(HubMessage message) {
        Message outMessage = new Message();
        outMessage.flags =
                message.getDeliveryParams().isResponseRequired()
                        ? Message.FLAG_REQUIRES_DELIVERY_STATUS
                        : 0;
        outMessage.permissions = new String[0];
        outMessage.sequenceNumber = message.getMessageSequenceNumber();
        outMessage.type = message.getMessageType();
        outMessage.content = message.getMessageBody();
        return outMessage;
    }

    /**
     * Converts a AIDL HAL Message object to a HubMessage object.
     *
     * @param message the AIDL HAL Message message to convert
     * @return the HubMessage
     */
    /* package */
    static HubMessage createHubMessage(Message message) {
        boolean isReliable = (message.flags & Message.FLAG_REQUIRES_DELIVERY_STATUS) != 0;
        return HubMessage.createMessage(
                message.type,
                message.content,
                HubMessage.DeliveryParams.makeBasic().setResponseRequired(isReliable));
    }
}
Loading