summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java93
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubService.java20
-rw-r--r--services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java113
-rw-r--r--services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java49
4 files changed, 266 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
new file mode 100644
index 000000000000..c05f7a0c0e00
--- /dev/null
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.location.contexthub;
+
+import android.hardware.contexthub.EndpointId;
+import android.hardware.contexthub.HubEndpointInfo;
+import android.hardware.contexthub.IEndpointCallback;
+import android.hardware.contexthub.Message;
+import android.hardware.contexthub.MessageDeliveryStatus;
+import android.os.RemoteException;
+
+/** IEndpointCallback implementation. */
+public class ContextHubHalEndpointCallback
+ extends android.hardware.contexthub.IEndpointCallback.Stub {
+ private final IEndpointLifecycleCallback mEndpointLifecycleCallback;
+
+ /** Interface for listening for endpoint start and stop events. */
+ public interface IEndpointLifecycleCallback {
+ /** Called when a batch of endpoints started. */
+ void onEndpointStarted(HubEndpointInfo[] endpointInfos);
+
+ /** Called when a batch of endpoints stopped. */
+ void onEndpointStopped(HubEndpointInfo.HubEndpointIdentifier[] endpointIds, byte reason);
+ }
+
+ ContextHubHalEndpointCallback(IEndpointLifecycleCallback endpointLifecycleCallback) {
+ mEndpointLifecycleCallback = endpointLifecycleCallback;
+ }
+
+ @Override
+ public void onEndpointStarted(android.hardware.contexthub.EndpointInfo[] halEndpointInfos)
+ throws RemoteException {
+ if (halEndpointInfos.length == 0) {
+ return;
+ }
+ HubEndpointInfo[] endpointInfos = new HubEndpointInfo[halEndpointInfos.length];
+ for (int i = 0; i < halEndpointInfos.length; i++) {
+ endpointInfos[i++] = new HubEndpointInfo(halEndpointInfos[i]);
+ }
+ mEndpointLifecycleCallback.onEndpointStarted(endpointInfos);
+ }
+
+ @Override
+ public void onEndpointStopped(EndpointId[] halEndpointIds, byte reason) throws RemoteException {
+ HubEndpointInfo.HubEndpointIdentifier[] endpointIds =
+ new HubEndpointInfo.HubEndpointIdentifier[halEndpointIds.length];
+ for (int i = 0; i < halEndpointIds.length; i++) {
+ endpointIds[i] = new HubEndpointInfo.HubEndpointIdentifier(halEndpointIds[i]);
+ }
+ 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 endpointId, EndpointId endpointId1, String s)
+ throws RemoteException {}
+
+ @Override
+ public void onCloseEndpointSession(int i, byte b) throws RemoteException {}
+
+ @Override
+ public void onEndpointSessionOpenComplete(int i) throws RemoteException {}
+
+ @Override
+ public int getInterfaceVersion() throws RemoteException {
+ return IEndpointCallback.VERSION;
+ }
+
+ @Override
+ public String getInterfaceHash() throws RemoteException {
+ return IEndpointCallback.HASH;
+ }
+}
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 88a7d08415dc..dd7e4dd69a80 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -250,6 +250,7 @@ public class ContextHubService extends IContextHubService.Stub {
public void handleServiceRestart() {
Log.i(TAG, "Recovering from Context Hub HAL restart...");
initExistingCallbacks();
+ mHubInfoRegistry.onHalRestart();
resetSettings();
if (Flags.reconnectHostEndpointsAfterHalRestart()) {
mClientManager.forEachClientOfHub(mContextHubId,
@@ -331,6 +332,7 @@ public class ContextHubService extends IContextHubService.Stub {
}
initDefaultClientMap();
+ initEndpointCallback();
initLocationSettingNotifications();
initWifiSettingNotifications();
@@ -509,6 +511,18 @@ public class ContextHubService extends IContextHubService.Stub {
mDefaultClientMap = Collections.unmodifiableMap(defaultClientMap);
}
+ private void initEndpointCallback() {
+ if (mHubInfoRegistry == null) {
+ return;
+ }
+ try {
+ mContextHubWrapper.registerEndpointCallback(
+ new ContextHubHalEndpointCallback(mHubInfoRegistry));
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException while registering IEndpointCallback", e);
+ }
+ }
+
/**
* Initializes existing callbacks with the mContextHubWrapper for every context hub
*/
@@ -744,8 +758,10 @@ public class ContextHubService extends IContextHubService.Stub {
@Override
public List<HubEndpointInfo> findEndpoints(long endpointId) {
super.findEndpoints_enforcePermission();
- // TODO(b/375487784): connect this with mHubInfoRegistry
- return Collections.emptyList();
+ if (mHubInfoRegistry == null) {
+ return Collections.emptyList();
+ }
+ return mHubInfoRegistry.findEndpoints(endpointId);
}
/**
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 68de9dbda2e1..4d1000f3e0e5 100644
--- a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
+++ b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
@@ -16,45 +16,144 @@
package com.android.server.location.contexthub;
+import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.location.HubInfo;
import android.os.RemoteException;
+import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-class HubInfoRegistry {
+class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycleCallback {
private static final String TAG = "HubInfoRegistry";
+ private final Object mLock = new Object();
private final IContextHubWrapper mContextHubWrapper;
- private final List<HubInfo> mHubsInfo;
+ @GuardedBy("mLock")
+ private List<HubInfo> mHubsInfo;
+
+ @GuardedBy("mLock")
+ private final ArrayMap<HubEndpointInfo.HubEndpointIdentifier, HubEndpointInfo>
+ mHubEndpointInfos = new ArrayMap<>();
HubInfoRegistry(IContextHubWrapper contextHubWrapper) {
- List<HubInfo> hubInfos;
mContextHubWrapper = contextHubWrapper;
+ refreshCachedHubs();
+ refreshCachedEndpoints();
+ }
+
+ /** Retrieve the list of hubs available. */
+ List<HubInfo> getHubs() {
+ synchronized (mLock) {
+ return mHubsInfo;
+ }
+ }
+
+ private void refreshCachedHubs() {
+ List<HubInfo> hubInfos;
try {
hubInfos = mContextHubWrapper.getHubs();
} catch (RemoteException e) {
Log.e(TAG, "RemoteException while getting Hub info", e);
hubInfos = Collections.emptyList();
}
- mHubsInfo = hubInfos;
+
+ synchronized (mLock) {
+ mHubsInfo = hubInfos;
+ }
}
- /** Retrieve the list of hubs available. */
- List<HubInfo> getHubs() {
- return mHubsInfo;
+ private void refreshCachedEndpoints() {
+ List<HubEndpointInfo> endpointInfos;
+ try {
+ endpointInfos = mContextHubWrapper.getEndpoints();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException while getting Hub info", e);
+ endpointInfos = Collections.emptyList();
+ }
+
+ synchronized (mLock) {
+ mHubEndpointInfos.clear();
+ for (HubEndpointInfo endpointInfo : endpointInfos) {
+ mHubEndpointInfos.put(endpointInfo.getIdentifier(), endpointInfo);
+ }
+ }
+ }
+
+ /** Invoked when HAL restarts */
+ public void onHalRestart() {
+ synchronized (mLock) {
+ refreshCachedHubs();
+ refreshCachedEndpoints();
+ }
+ }
+
+ @Override
+ public void onEndpointStarted(HubEndpointInfo[] endpointInfos) {
+ synchronized (mLock) {
+ for (HubEndpointInfo endpointInfo : endpointInfos) {
+ mHubEndpointInfos.remove(endpointInfo.getIdentifier());
+ mHubEndpointInfos.put(endpointInfo.getIdentifier(), endpointInfo);
+ }
+ }
+ }
+
+ @Override
+ public void onEndpointStopped(
+ HubEndpointInfo.HubEndpointIdentifier[] endpointIds, byte reason) {
+ synchronized (mLock) {
+ for (HubEndpointInfo.HubEndpointIdentifier endpointId : endpointIds) {
+ mHubEndpointInfos.remove(endpointId);
+ }
+ }
+ }
+
+ /** Return a list of {@link HubEndpointInfo} that represents endpoints with the matching id. */
+ public List<HubEndpointInfo> findEndpoints(long endpointIdQuery) {
+ List<HubEndpointInfo> searchResult = new ArrayList<>();
+ synchronized (mLock) {
+ for (HubEndpointInfo.HubEndpointIdentifier endpointId : mHubEndpointInfos.keySet()) {
+ if (endpointId.getEndpoint() == endpointIdQuery) {
+ searchResult.add(mHubEndpointInfos.get(endpointId));
+ }
+ }
+ }
+ return searchResult;
}
void dump(IndentingPrintWriter ipw) {
+ synchronized (mLock) {
+ dumpLocked(ipw);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void dumpLocked(IndentingPrintWriter ipw) {
ipw.println(TAG);
ipw.increaseIndent();
+ ipw.println("Hubs");
for (HubInfo hubInfo : mHubsInfo) {
ipw.println(hubInfo);
}
ipw.decreaseIndent();
+
+ ipw.println();
+
+ ipw.increaseIndent();
+ ipw.println("Endpoints");
+ for (HubEndpointInfo endpointInfo : mHubEndpointInfos.values()) {
+ ipw.println(endpointInfo);
+ }
+ ipw.decreaseIndent();
+
+ ipw.println();
}
+
}
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 6656a6fe9eb4..9b729eb11eed 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -19,6 +19,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.chre.flags.Flags;
import android.hardware.contexthub.HostEndpointInfo;
+import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.MessageDeliveryStatus;
import android.hardware.contexthub.NanSessionRequest;
import android.hardware.contexthub.V1_0.ContextHub;
@@ -229,6 +230,15 @@ public abstract class IContextHubWrapper {
return Collections.emptyList();
}
+ /** Calls the appropriate getEndpoints function depending on the HAL version. */
+ public List<HubEndpointInfo> getEndpoints() throws RemoteException {
+ return Collections.emptyList();
+ }
+
+ /** Calls the appropriate registerEndpointCallback function depending on the HAL version. */
+ public void registerEndpointCallback(android.hardware.contexthub.IEndpointCallback cb)
+ throws RemoteException {}
+
/**
* @return True if this version of the Contexthub HAL supports Location setting notifications.
*/
@@ -622,6 +632,45 @@ public abstract class IContextHubWrapper {
return retVal;
}
+ @Override
+ public List<HubEndpointInfo> getEndpoints() throws RemoteException {
+ android.hardware.contexthub.IContextHub hub = getHub();
+ if (hub == null) {
+ return Collections.emptyList();
+ }
+
+ List<HubEndpointInfo> retVal = new ArrayList<>();
+ final List<android.hardware.contexthub.EndpointInfo> halEndpointInfos =
+ hub.getEndpoints();
+ for (android.hardware.contexthub.EndpointInfo halEndpointInfo : halEndpointInfos) {
+ /* HAL -> API Type conversion */
+ final HubEndpointInfo endpointInfo = new HubEndpointInfo(halEndpointInfo);
+ if (DEBUG) {
+ Log.i(TAG, "getEndpoints: endpointInfo=" + endpointInfo);
+ }
+ retVal.add(endpointInfo);
+ }
+
+ if (DEBUG) {
+ Log.i(TAG, "getEndpoints: total count=" + retVal.size());
+ }
+ return retVal;
+ }
+
+ @Override
+ public void registerEndpointCallback(android.hardware.contexthub.IEndpointCallback cb)
+ throws RemoteException {
+ android.hardware.contexthub.IContextHub hub = getHub();
+ if (hub == null) {
+ return;
+ }
+
+ if (DEBUG) {
+ Log.i(TAG, "registerEndpointCallback: cb=" + cb);
+ }
+ hub.registerEndpointCallback(cb);
+ }
+
public boolean supportsLocationSettingNotifications() {
return true;
}