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

Commit f85810e9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Implements endpoint session callbacks" into main

parents a68ddb3b 55e000f0
Loading
Loading
Loading
Loading
+108 −15
Original line number Diff line number Diff line
@@ -27,6 +27,10 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

/**
@@ -60,6 +64,20 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
    /** True if this endpoint is registered with the service. */
    private AtomicBoolean mIsRegistered = new AtomicBoolean(true);

    private final Object mOpenSessionLock = new Object();

    /** The set of session IDs that are pending remote acceptance */
    @GuardedBy("mOpenSessionLock")
    private final Set<Integer> mPendingSessionIds = new HashSet<>();

    /** The set of session IDs that are actively enabled by this endpoint */
    @GuardedBy("mOpenSessionLock")
    private final Set<Integer> mActiveSessionIds = new HashSet<>();

    /** The set of session IDs that are actively enabled by the remote endpoint */
    @GuardedBy("mOpenSessionLock")
    private final Set<Integer> mActiveRemoteSessionIds = new HashSet<>();

    /* package */ ContextHubEndpointBroker(
            Context context,
            IContextHubWrapper contextHubProxy,
@@ -86,17 +104,25 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        if (!mIsRegistered.get()) throw new IllegalStateException("Endpoint is not registered");
        int sessionId = mEndpointManager.reserveSessionId();
        EndpointInfo halEndpointInfo = ContextHubServiceUtil.convertHalEndpointInfo(destination);

        synchronized (mOpenSessionLock) {
            try {
                mPendingSessionIds.add(sessionId);
                mContextHubProxy.openEndpointSession(
                    sessionId, halEndpointInfo.id, mHalEndpointInfo.id, serviceDescriptor);
                        sessionId,
                        halEndpointInfo.id,
                        mHalEndpointInfo.id,
                        serviceDescriptor);
            } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
                Log.e(TAG, "Exception while calling HAL openEndpointSession", e);
                mPendingSessionIds.remove(sessionId);
                mEndpointManager.returnSessionId(sessionId);
                throw e;
            }

            return sessionId;
        }
    }

    @Override
    public void closeSession(int sessionId, int reason) throws RemoteException {
@@ -110,11 +136,6 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        }
    }

    @Override
    public void openSessionRequestComplete(int sessionId) {
        // TODO(b/378487799): Implement this
    }

    @Override
    public void unregister() {
        ContextHubServiceUtil.checkPermissions(mContext);
@@ -124,10 +145,33 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException while calling HAL unregisterEndpoint", e);
        }
        // TODO(b/378487799): Release reserved session IDs
        synchronized (mOpenSessionLock) {
            for (int id : mPendingSessionIds) {
                mEndpointManager.returnSessionId(id);
            }
            for (int id : mActiveSessionIds) {
                mEndpointManager.returnSessionId(id);
            }
            mPendingSessionIds.clear();
            mActiveSessionIds.clear();
            mActiveRemoteSessionIds.clear();
        }
        mEndpointManager.unregisterEndpoint(mEndpointInfo.getIdentifier().getEndpoint());
    }

    @Override
    public void openSessionRequestComplete(int sessionId) {
        ContextHubServiceUtil.checkPermissions(mContext);
        synchronized (mOpenSessionLock) {
            try {
                mContextHubProxy.endpointSessionOpenComplete(sessionId);
                mActiveRemoteSessionIds.add(sessionId);
            } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
                Log.e(TAG, "Exception while calling endpointSessionOpenComplete", e);
            }
        }
    }

    @Override
    public void sendMessage(
            int sessionId, HubMessage message, IContextHubTransactionCallback callback) {
@@ -150,4 +194,53 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
            mContextHubEndpointCallback.asBinder().linkToDeath(this, 0 /* flags */);
        }
    }

    /* package */ void onEndpointSessionOpenRequest(
            int sessionId, HubEndpointInfo initiator, String serviceDescriptor) {
        if (mContextHubEndpointCallback != null) {
            try {
                mContextHubEndpointCallback.onSessionOpenRequest(
                        sessionId, initiator, serviceDescriptor);
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException while calling onSessionOpenRequest", e);
            }
        }
    }

    /* package */ void onCloseEndpointSession(int sessionId, byte reason) {
        synchronized (mOpenSessionLock) {
            mPendingSessionIds.remove(sessionId);
            mActiveSessionIds.remove(sessionId);
            mActiveRemoteSessionIds.remove(sessionId);
        }
        if (mContextHubEndpointCallback != null) {
            try {
                mContextHubEndpointCallback.onSessionClosed(sessionId, reason);
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException while calling onSessionClosed", e);
            }
        }
    }

    /* package */ void onEndpointSessionOpenComplete(int sessionId) {
        synchronized (mOpenSessionLock) {
            mPendingSessionIds.remove(sessionId);
            mActiveSessionIds.add(sessionId);
        }
        if (mContextHubEndpointCallback != null) {
            try {
                mContextHubEndpointCallback.onSessionOpenComplete(sessionId);
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException while calling onSessionClosed", e);
            }
        }
    }

    /* package */ boolean hasSessionId(int sessionId) {
        synchronized (mOpenSessionLock) {
            return mPendingSessionIds.contains(sessionId)
                    || mActiveSessionIds.contains(sessionId)
                    || mActiveRemoteSessionIds.contains(sessionId);
        }
    }
}
+74 −2
Original line number Diff line number Diff line
@@ -38,7 +38,8 @@ import java.util.concurrent.ConcurrentHashMap;
 *
 * @hide
 */
/* package */ class ContextHubEndpointManager {
/* package */ class ContextHubEndpointManager
        implements ContextHubHalEndpointCallback.IEndpointSessionCallback {
    private static final String TAG = "ContextHubEndpointManager";

    /** The hub ID of the Context Hub Service. */
@@ -56,6 +57,8 @@ import java.util.concurrent.ConcurrentHashMap;
    /** The proxy to talk to the Context Hub. */
    private final IContextHubWrapper mContextHubProxy;

    private final HubInfoRegistry mHubInfoRegistry;

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

@@ -85,9 +88,11 @@ import java.util.concurrent.ConcurrentHashMap;
    /** Initialized to true if all initialization in the constructor succeeds. */
    private final boolean mSessionIdsValid;

    /* package */ ContextHubEndpointManager(Context context, IContextHubWrapper contextHubProxy) {
    /* package */ ContextHubEndpointManager(
            Context context, IContextHubWrapper contextHubProxy, HubInfoRegistry hubInfoRegistry) {
        mContext = context;
        mContextHubProxy = contextHubProxy;
        mHubInfoRegistry = hubInfoRegistry;
        int[] range = null;
        try {
            range = mContextHubProxy.requestSessionIdRange(SERVICE_SESSION_RANGE);
@@ -210,6 +215,70 @@ import java.util.concurrent.ConcurrentHashMap;
        mEndpointMap.remove(endpointId);
    }

    @Override
    public void onEndpointSessionOpenRequest(
            int sessionId,
            HubEndpointInfo.HubEndpointIdentifier destination,
            HubEndpointInfo.HubEndpointIdentifier initiator,
            String serviceDescriptor) {
        if (destination.getHub() != SERVICE_HUB_ID) {
            Log.e(
                    TAG,
                    "onEndpointSessionOpenRequest: invalid destination hub ID: "
                            + destination.getHub());
            return;
        }
        ContextHubEndpointBroker broker = mEndpointMap.get(destination.getEndpoint());
        if (broker == null) {
            Log.e(
                    TAG,
                    "onEndpointSessionOpenRequest: unknown destination endpoint ID: "
                            + destination.getEndpoint());
            return;
        }
        HubEndpointInfo initiatorInfo = mHubInfoRegistry.getEndpointInfo(initiator);
        if (initiatorInfo == null) {
            Log.e(
                    TAG,
                    "onEndpointSessionOpenRequest: unknown initiator endpoint ID: "
                            + initiator.getEndpoint());
            return;
        }
        broker.onEndpointSessionOpenRequest(sessionId, initiatorInfo, serviceDescriptor);
    }

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

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

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

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

    /** @return an available endpoint ID */
    private long getNewEndpointId() {
        synchronized (mEndpointLock) {
@@ -220,6 +289,9 @@ import java.util.concurrent.ConcurrentHashMap;
        }
    }

    /**
     * @return true if the provided session ID range is valid
     */
    private boolean isSessionIdRangeValid(int minId, int maxId) {
        return (minId <= maxId) && (minId >= 0) && (maxId >= 0);
    }
+34 −5
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.RemoteException;
public class ContextHubHalEndpointCallback
        extends android.hardware.contexthub.IEndpointCallback.Stub {
    private final IEndpointLifecycleCallback mEndpointLifecycleCallback;
    private final IEndpointSessionCallback mEndpointSessionCallback;

    /** Interface for listening for endpoint start and stop events. */
    public interface IEndpointLifecycleCallback {
@@ -36,8 +37,27 @@ public class ContextHubHalEndpointCallback
        void onEndpointStopped(HubEndpointInfo.HubEndpointIdentifier[] endpointIds, byte reason);
    }

    ContextHubHalEndpointCallback(IEndpointLifecycleCallback endpointLifecycleCallback) {
    /** Interface for listening for endpoint session events. */
    public interface IEndpointSessionCallback {
        /** Called when an endpoint session open is requested by the HAL. */
        void onEndpointSessionOpenRequest(
                int sessionId,
                HubEndpointInfo.HubEndpointIdentifier destinationId,
                HubEndpointInfo.HubEndpointIdentifier initiatorId,
                String serviceDescriptor);

        /** Called when a endpoint close session is completed. */
        void onCloseEndpointSession(int sessionId, byte reason);

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

    ContextHubHalEndpointCallback(
            IEndpointLifecycleCallback endpointLifecycleCallback,
            IEndpointSessionCallback endpointSessionCallback) {
        mEndpointLifecycleCallback = endpointLifecycleCallback;
        mEndpointSessionCallback = endpointSessionCallback;
    }

    @Override
@@ -72,14 +92,23 @@ public class ContextHubHalEndpointCallback

    @Override
    public void onEndpointSessionOpenRequest(
            int i, EndpointId endpointId, EndpointId endpointId1, String s)
            throws RemoteException {}
            int i, EndpointId destination, EndpointId initiator, String s) throws RemoteException {
        HubEndpointInfo.HubEndpointIdentifier destinationId =
                new HubEndpointInfo.HubEndpointIdentifier(destination.hubId, destination.id);
        HubEndpointInfo.HubEndpointIdentifier initiatorId =
                new HubEndpointInfo.HubEndpointIdentifier(initiator.hubId, initiator.id);
        mEndpointSessionCallback.onEndpointSessionOpenRequest(i, destinationId, initiatorId, s);
    }

    @Override
    public void onCloseEndpointSession(int i, byte b) throws RemoteException {}
    public void onCloseEndpointSession(int i, byte b) throws RemoteException {
        mEndpointSessionCallback.onCloseEndpointSession(i, b);
    }

    @Override
    public void onEndpointSessionOpenComplete(int i) throws RemoteException {}
    public void onEndpointSessionOpenComplete(int i) throws RemoteException {
        mEndpointSessionCallback.onEndpointSessionOpenComplete(i);
    }

    @Override
    public int getInterfaceVersion() throws RemoteException {
+3 −2
Original line number Diff line number Diff line
@@ -333,7 +333,8 @@ public class ContextHubService extends IContextHubService.Stub {
            HubInfoRegistry registry;
            try {
                registry = new HubInfoRegistry(mContextHubWrapper);
                mEndpointManager = new ContextHubEndpointManager(mContext, mContextHubWrapper);
                mEndpointManager =
                        new ContextHubEndpointManager(mContext, mContextHubWrapper, registry);
                Log.i(TAG, "Enabling generic offload API");
            } catch (UnsupportedOperationException e) {
                mEndpointManager = null;
@@ -533,7 +534,7 @@ public class ContextHubService extends IContextHubService.Stub {
        }
        try {
            mContextHubWrapper.registerEndpointCallback(
                    new ContextHubHalEndpointCallback(mHubInfoRegistry));
                    new ContextHubHalEndpointCallback(mHubInfoRegistry, mEndpointManager));
        } catch (RemoteException | UnsupportedOperationException e) {
            Log.e(TAG, "Exception while registering IEndpointCallback", e);
        }
+6 −0
Original line number Diff line number Diff line
@@ -87,6 +87,12 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl
        }
    }

    public HubEndpointInfo getEndpointInfo(HubEndpointInfo.HubEndpointIdentifier id) {
        synchronized (mLock) {
            return mHubEndpointInfos.get(id);
        }
    }

    /** Invoked when HAL restarts */
    public void onHalRestart() {
        synchronized (mLock) {
Loading