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 Original line Diff line number Diff line
@@ -27,6 +27,10 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.RemoteException;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.GuardedBy;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
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. */
    /** True if this endpoint is registered with the service. */
    private AtomicBoolean mIsRegistered = new AtomicBoolean(true);
    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(
    /* package */ ContextHubEndpointBroker(
            Context context,
            Context context,
            IContextHubWrapper contextHubProxy,
            IContextHubWrapper contextHubProxy,
@@ -86,17 +104,25 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        if (!mIsRegistered.get()) throw new IllegalStateException("Endpoint is not registered");
        if (!mIsRegistered.get()) throw new IllegalStateException("Endpoint is not registered");
        int sessionId = mEndpointManager.reserveSessionId();
        int sessionId = mEndpointManager.reserveSessionId();
        EndpointInfo halEndpointInfo = ContextHubServiceUtil.convertHalEndpointInfo(destination);
        EndpointInfo halEndpointInfo = ContextHubServiceUtil.convertHalEndpointInfo(destination);

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


            return sessionId;
            return sessionId;
        }
        }
    }


    @Override
    @Override
    public void closeSession(int sessionId, int reason) throws RemoteException {
    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
    @Override
    public void unregister() {
    public void unregister() {
        ContextHubServiceUtil.checkPermissions(mContext);
        ContextHubServiceUtil.checkPermissions(mContext);
@@ -124,10 +145,33 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException while calling HAL unregisterEndpoint", 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());
        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
    @Override
    public void sendMessage(
    public void sendMessage(
            int sessionId, HubMessage message, IContextHubTransactionCallback callback) {
            int sessionId, HubMessage message, IContextHubTransactionCallback callback) {
@@ -150,4 +194,53 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
            mContextHubEndpointCallback.asBinder().linkToDeath(this, 0 /* flags */);
            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 Original line Diff line number Diff line
@@ -38,7 +38,8 @@ import java.util.concurrent.ConcurrentHashMap;
 *
 *
 * @hide
 * @hide
 */
 */
/* package */ class ContextHubEndpointManager {
/* package */ class ContextHubEndpointManager
        implements ContextHubHalEndpointCallback.IEndpointSessionCallback {
    private static final String TAG = "ContextHubEndpointManager";
    private static final String TAG = "ContextHubEndpointManager";


    /** The hub ID of the Context Hub Service. */
    /** 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. */
    /** The proxy to talk to the Context Hub. */
    private final IContextHubWrapper mContextHubProxy;
    private final IContextHubWrapper mContextHubProxy;


    private final HubInfoRegistry mHubInfoRegistry;

    /** A map of endpoint IDs to brokers currently registered. */
    /** A map of endpoint IDs to brokers currently registered. */
    private final Map<Long, ContextHubEndpointBroker> mEndpointMap = new ConcurrentHashMap<>();
    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. */
    /** Initialized to true if all initialization in the constructor succeeds. */
    private final boolean mSessionIdsValid;
    private final boolean mSessionIdsValid;


    /* package */ ContextHubEndpointManager(Context context, IContextHubWrapper contextHubProxy) {
    /* package */ ContextHubEndpointManager(
            Context context, IContextHubWrapper contextHubProxy, HubInfoRegistry hubInfoRegistry) {
        mContext = context;
        mContext = context;
        mContextHubProxy = contextHubProxy;
        mContextHubProxy = contextHubProxy;
        mHubInfoRegistry = hubInfoRegistry;
        int[] range = null;
        int[] range = null;
        try {
        try {
            range = mContextHubProxy.requestSessionIdRange(SERVICE_SESSION_RANGE);
            range = mContextHubProxy.requestSessionIdRange(SERVICE_SESSION_RANGE);
@@ -210,6 +215,70 @@ import java.util.concurrent.ConcurrentHashMap;
        mEndpointMap.remove(endpointId);
        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 */
    /** @return an available endpoint ID */
    private long getNewEndpointId() {
    private long getNewEndpointId() {
        synchronized (mEndpointLock) {
        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) {
    private boolean isSessionIdRangeValid(int minId, int maxId) {
        return (minId <= maxId) && (minId >= 0) && (maxId >= 0);
        return (minId <= maxId) && (minId >= 0) && (maxId >= 0);
    }
    }
+34 −5
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.RemoteException;
public class ContextHubHalEndpointCallback
public class ContextHubHalEndpointCallback
        extends android.hardware.contexthub.IEndpointCallback.Stub {
        extends android.hardware.contexthub.IEndpointCallback.Stub {
    private final IEndpointLifecycleCallback mEndpointLifecycleCallback;
    private final IEndpointLifecycleCallback mEndpointLifecycleCallback;
    private final IEndpointSessionCallback mEndpointSessionCallback;


    /** Interface for listening for endpoint start and stop events. */
    /** Interface for listening for endpoint start and stop events. */
    public interface IEndpointLifecycleCallback {
    public interface IEndpointLifecycleCallback {
@@ -36,8 +37,27 @@ public class ContextHubHalEndpointCallback
        void onEndpointStopped(HubEndpointInfo.HubEndpointIdentifier[] endpointIds, byte reason);
        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;
        mEndpointLifecycleCallback = endpointLifecycleCallback;
        mEndpointSessionCallback = endpointSessionCallback;
    }
    }


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


    @Override
    @Override
    public void onEndpointSessionOpenRequest(
    public void onEndpointSessionOpenRequest(
            int i, EndpointId endpointId, EndpointId endpointId1, String s)
            int i, EndpointId destination, EndpointId initiator, String s) throws RemoteException {
            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
    @Override
    public void onCloseEndpointSession(int i, byte b) throws RemoteException {}
    public void onCloseEndpointSession(int i, byte b) throws RemoteException {
        mEndpointSessionCallback.onCloseEndpointSession(i, b);
    }


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


    @Override
    @Override
    public int getInterfaceVersion() throws RemoteException {
    public int getInterfaceVersion() throws RemoteException {
+3 −2
Original line number Original line Diff line number Diff line
@@ -333,7 +333,8 @@ public class ContextHubService extends IContextHubService.Stub {
            HubInfoRegistry registry;
            HubInfoRegistry registry;
            try {
            try {
                registry = new HubInfoRegistry(mContextHubWrapper);
                registry = new HubInfoRegistry(mContextHubWrapper);
                mEndpointManager = new ContextHubEndpointManager(mContext, mContextHubWrapper);
                mEndpointManager =
                        new ContextHubEndpointManager(mContext, mContextHubWrapper, registry);
                Log.i(TAG, "Enabling generic offload API");
                Log.i(TAG, "Enabling generic offload API");
            } catch (UnsupportedOperationException e) {
            } catch (UnsupportedOperationException e) {
                mEndpointManager = null;
                mEndpointManager = null;
@@ -533,7 +534,7 @@ public class ContextHubService extends IContextHubService.Stub {
        }
        }
        try {
        try {
            mContextHubWrapper.registerEndpointCallback(
            mContextHubWrapper.registerEndpointCallback(
                    new ContextHubHalEndpointCallback(mHubInfoRegistry));
                    new ContextHubHalEndpointCallback(mHubInfoRegistry, mEndpointManager));
        } catch (RemoteException | UnsupportedOperationException e) {
        } catch (RemoteException | UnsupportedOperationException e) {
            Log.e(TAG, "Exception while registering IEndpointCallback", e);
            Log.e(TAG, "Exception while registering IEndpointCallback", e);
        }
        }
+6 −0
Original line number Original line 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 */
    /** Invoked when HAL restarts */
    public void onHalRestart() {
    public void onHalRestart() {
        synchronized (mLock) {
        synchronized (mLock) {
Loading