summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java123
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java76
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java39
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubService.java5
-rw-r--r--services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java6
-rw-r--r--services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java12
6 files changed, 237 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
index 7155cd0fc719..4a533f42ffea 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
@@ -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,16 +104,24 @@ 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);
- try {
- mContextHubProxy.openEndpointSession(
- sessionId, halEndpointInfo.id, mHalEndpointInfo.id, serviceDescriptor);
- } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
- Log.e(TAG, "Exception while calling HAL openEndpointSession", e);
- mEndpointManager.returnSessionId(sessionId);
- throw e;
- }
- return sessionId;
+ synchronized (mOpenSessionLock) {
+ try {
+ mPendingSessionIds.add(sessionId);
+ mContextHubProxy.openEndpointSession(
+ 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
@@ -111,11 +137,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);
mIsRegistered.set(false);
@@ -124,11 +145,34 @@ 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) {
// TODO(b/381102453): Implement this
@@ -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);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
index fb64f99e5904..8c5095f35f0d 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
@@ -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);
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
index c05f7a0c0e00..8e72553a9c52 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
@@ -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 {
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 0d926b99217d..0b47a61341f7 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -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);
}
diff --git a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
index d2b2331d54f3..b91249204199 100644
--- a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
+++ b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
@@ -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) {
diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
index c79dc84ec2af..6cb942980403 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -261,6 +261,9 @@ public abstract class IContextHubWrapper {
public void unregisterEndpoint(android.hardware.contexthub.EndpointInfo info)
throws RemoteException {}
+ /** Notifies the completion of a session opened by the HAL */
+ public void endpointSessionOpenComplete(int sessionId) throws RemoteException {}
+
/**
* @return True if this version of the Contexthub HAL supports Location setting notifications.
*/
@@ -745,6 +748,15 @@ public abstract class IContextHubWrapper {
hub.unregisterEndpoint(info);
}
+ @Override
+ public void endpointSessionOpenComplete(int sessionId) throws RemoteException {
+ android.hardware.contexthub.IContextHub hub = getHub();
+ if (hub == null) {
+ return;
+ }
+ hub.endpointSessionOpenComplete(sessionId);
+ }
+
public boolean supportsLocationSettingNotifications() {
return true;
}