Loading core/java/android/hardware/location/ContextHubManager.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -1267,6 +1267,9 @@ public final class ContextHubManager { * registration succeeds, the endpoint can receive notifications through the provided callback. * registration succeeds, the endpoint can receive notifications through the provided callback. * * * @param hubEndpoint {@link HubEndpoint} object created by {@link HubEndpoint.Builder} * @param hubEndpoint {@link HubEndpoint} object created by {@link HubEndpoint.Builder} * @throws IllegalStateException if the registration failed, for example if too many endpoints * are registered at the service * @throws UnsupportedOperationException if endpoint registration is not supported */ */ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) @FlaggedApi(Flags.FLAG_OFFLOAD_API) @FlaggedApi(Flags.FLAG_OFFLOAD_API) Loading services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java 0 → 100644 +108 −0 Original line number Original line Diff line number Diff line /* * 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.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.IContextHubEndpoint; import android.hardware.contexthub.IContextHubEndpointCallback; import android.hardware.location.IContextHubTransactionCallback; /** * A class that represents a broker for the endpoint registered by the client app. This class * manages direct IContextHubEndpoint/IContextHubEndpointCallback API/callback calls. * * @hide */ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub { private static final String TAG = "ContextHubEndpointBroker"; /** The context of the service. */ private final Context mContext; /** The proxy to talk to the Context Hub HAL. */ private final IContextHubWrapper mContextHubProxy; /** The manager that registered this endpoint. */ private final ContextHubEndpointManager mEndpointManager; /** Metadata about this endpoint (app-facing container). */ private final HubEndpointInfo mEndpointInfo; /** Metadata about this endpoint (HAL-facing container). */ private final EndpointInfo mHalEndpointInfo; /** The remote callback interface for this endpoint. */ private final IContextHubEndpointCallback mContextHubEndpointCallback; /* package */ ContextHubEndpointBroker( Context context, IContextHubWrapper contextHubProxy, ContextHubEndpointManager endpointManager, EndpointInfo halEndpointInfo, IContextHubEndpointCallback callback) { mContext = context; mContextHubProxy = contextHubProxy; mEndpointManager = endpointManager; mEndpointInfo = new HubEndpointInfo(halEndpointInfo); mHalEndpointInfo = halEndpointInfo; mContextHubEndpointCallback = callback; } @Override public HubEndpointInfo getAssignedHubEndpointInfo() { return mEndpointInfo; } @Override public int openSession(HubEndpointInfo destination, HubServiceInfo serviceInfo) { // TODO(b/378487799): Implement this return 0; } @Override public void closeSession(int sessionId, int reason) { // TODO(b/378487799): Implement this } @Override public void openSessionRequestComplete(int sessionId) { // TODO(b/378487799): Implement this } @Override public void unregister() { // TODO(b/378487799): Implement this } @Override public void sendMessage( int sessionId, HubMessage message, IContextHubTransactionCallback callback) { // TODO(b/381102453): Implement this } @Override public void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode) { // TODO(b/381102453): Implement this } } services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java 0 → 100644 +111 −0 Original line number Original line Diff line number Diff line /* * 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.content.Context; import android.hardware.contexthub.EndpointInfo; import android.hardware.contexthub.HubEndpointInfo; import android.hardware.contexthub.IContextHubEndpoint; import android.hardware.contexthub.IContextHubEndpointCallback; import android.os.RemoteException; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * A class that manages registration/unregistration of clients and manages messages to/from clients. * * @hide */ /* package */ class ContextHubEndpointManager { private static final String TAG = "ContextHubEndpointManager"; /** The hub ID of the Context Hub Service. */ private static final long SERVICE_HUB_ID = 0x416e64726f696400L; /** The context of the service. */ private final Context mContext; /** The proxy to talk to the Context Hub. */ private final IContextHubWrapper mContextHubProxy; /** A map of endpoint IDs to brokers currently registered. */ private final Map<Long, ContextHubEndpointBroker> mEndpointMap = new ConcurrentHashMap<>(); /** Variables for managing endpoint ID creation */ private final Object mEndpointLock = new Object(); @GuardedBy("mEndpointLock") private long mNextEndpointId = 0; /* package */ ContextHubEndpointManager(Context context, IContextHubWrapper contextHubProxy) { mContext = context; mContextHubProxy = contextHubProxy; } /** * Registers a new endpoint with the service. * * @param pendingEndpointInfo the object describing the endpoint being registered * @param callback the callback interface of the endpoint to register * @return the endpoint interface * @throws IllegalStateException if max number of endpoints have already registered */ /* package */ IContextHubEndpoint registerEndpoint( HubEndpointInfo pendingEndpointInfo, IContextHubEndpointCallback callback) throws RemoteException { ContextHubEndpointBroker broker; long endpointId = getNewEndpointId(); EndpointInfo halEndpointInfo = ContextHubServiceUtil.createHalEndpointInfo( pendingEndpointInfo, endpointId, SERVICE_HUB_ID); try { mContextHubProxy.registerEndpoint(halEndpointInfo); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling HAL registerEndpoint", e); throw e; } broker = new ContextHubEndpointBroker( mContext, mContextHubProxy, this /* endpointManager */, halEndpointInfo, callback); mEndpointMap.put(endpointId, broker); // TODO(b/378487799): Add death recipient Log.d(TAG, "Registered endpoint with ID = " + endpointId); return IContextHubEndpoint.Stub.asInterface(broker); } /** * @return an available endpoint ID */ private long getNewEndpointId() { synchronized (mEndpointLock) { if (mNextEndpointId == Long.MAX_VALUE) { throw new IllegalStateException("Too many endpoints connected"); } return mNextEndpointId++; } } } services/core/java/com/android/server/location/contexthub/ContextHubService.java +11 −2 Original line number Original line Diff line number Diff line Loading @@ -155,6 +155,9 @@ public class ContextHubService extends IContextHubService.Stub { // The manager for sending messages to/from clients // The manager for sending messages to/from clients private ContextHubClientManager mClientManager; private ContextHubClientManager mClientManager; // Manages endpoint and its sessions between apps and HAL private ContextHubEndpointManager mEndpointManager; // The default client for old API clients // The default client for old API clients private Map<Integer, IContextHubClient> mDefaultClientMap; private Map<Integer, IContextHubClient> mDefaultClientMap; Loading Loading @@ -330,14 +333,17 @@ 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); Log.i(TAG, "Enabling generic offload API"); Log.i(TAG, "Enabling generic offload API"); } catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) { mEndpointManager = null; registry = null; registry = null; Log.w(TAG, "Generic offload API not supported, disabling"); Log.w(TAG, "Generic offload API not supported, disabling"); } } mHubInfoRegistry = registry; mHubInfoRegistry = registry; } else { } else { mHubInfoRegistry = null; mHubInfoRegistry = null; mEndpointManager = null; Log.i(TAG, "Disabling generic offload API"); Log.i(TAG, "Disabling generic offload API"); } } Loading Loading @@ -790,8 +796,11 @@ public class ContextHubService extends IContextHubService.Stub { HubEndpointInfo pendingHubEndpointInfo, IContextHubEndpointCallback callback) HubEndpointInfo pendingHubEndpointInfo, IContextHubEndpointCallback callback) throws RemoteException { throws RemoteException { super.registerEndpoint_enforcePermission(); super.registerEndpoint_enforcePermission(); // TODO(b/375487784): Implement this if (mEndpointManager == null) { return null; Log.e(TAG, "ContextHubService.registerEndpoint: endpoint manager failed to initialize"); throw new UnsupportedOperationException("Endpoint registration is not supported"); } return mEndpointManager.registerEndpoint(pendingHubEndpointInfo, callback); } } @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) Loading services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java +50 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,9 @@ package com.android.server.location.contexthub; import android.Manifest; import android.Manifest; import android.content.Context; import android.content.Context; import android.hardware.contexthub.EndpointInfo; import android.hardware.contexthub.HubEndpointInfo; import android.hardware.contexthub.HubServiceInfo; import android.hardware.contexthub.V1_0.AsyncEventType; import android.hardware.contexthub.V1_0.AsyncEventType; import android.hardware.contexthub.V1_0.ContextHubMsg; import android.hardware.contexthub.V1_0.ContextHubMsg; import android.hardware.contexthub.V1_0.HostEndPoint; import android.hardware.contexthub.V1_0.HostEndPoint; Loading Loading @@ -415,4 +418,51 @@ import java.util.List; static String formatDateFromTimestamp(long timeStampInMs) { static String formatDateFromTimestamp(long timeStampInMs) { return DATE_FORMATTER.format(Instant.ofEpochMilli(timeStampInMs)); return DATE_FORMATTER.format(Instant.ofEpochMilli(timeStampInMs)); } } /** * Converts a context hub HAL EndpointInfo object based on the provided HubEndpointInfo. * * @param info the HubEndpointInfo object * @return the equivalent EndpointInfo object */ /* package */ static EndpointInfo convertHalEndpointInfo(HubEndpointInfo info) { return createHalEndpointInfo( info, info.getIdentifier().getEndpoint(), info.getIdentifier().getHub()); } /** * Creates a context hub HAL EndpointInfo object based on the provided HubEndpointInfo. As * opposed to convertHalEndpointInfo, this method can be used to overwrite/specify the endpoint * and hub ID. * * @param info the HubEndpointInfo object * @param endpointId the endpoint ID of this object * @param hubId the hub ID of this object * @return the equivalent EndpointInfo object */ /* package */ static EndpointInfo createHalEndpointInfo(HubEndpointInfo info, long endpointId, long hubId) { EndpointInfo outputInfo = new EndpointInfo(); outputInfo.id = new android.hardware.contexthub.EndpointId(); outputInfo.id.id = endpointId; outputInfo.id.hubId = hubId; outputInfo.name = info.getName(); outputInfo.version = info.getVersion(); outputInfo.tag = info.getTag(); Collection<String> permissions = info.getRequiredPermissions(); outputInfo.requiredPermissions = permissions.toArray(new String[permissions.size()]); Collection<HubServiceInfo> services = info.getServiceInfoCollection(); outputInfo.services = new android.hardware.contexthub.Service[services.size()]; int i = 0; for (HubServiceInfo service : services) { outputInfo.services[i] = new android.hardware.contexthub.Service(); outputInfo.services[i].format = service.getFormat(); outputInfo.services[i].serviceDescriptor = service.getServiceDescriptor(); outputInfo.services[i].majorVersion = service.getMajorVersion(); outputInfo.services[i].minorVersion = service.getMinorVersion(); i++; } return outputInfo; } } } Loading
core/java/android/hardware/location/ContextHubManager.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -1267,6 +1267,9 @@ public final class ContextHubManager { * registration succeeds, the endpoint can receive notifications through the provided callback. * registration succeeds, the endpoint can receive notifications through the provided callback. * * * @param hubEndpoint {@link HubEndpoint} object created by {@link HubEndpoint.Builder} * @param hubEndpoint {@link HubEndpoint} object created by {@link HubEndpoint.Builder} * @throws IllegalStateException if the registration failed, for example if too many endpoints * are registered at the service * @throws UnsupportedOperationException if endpoint registration is not supported */ */ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) @FlaggedApi(Flags.FLAG_OFFLOAD_API) @FlaggedApi(Flags.FLAG_OFFLOAD_API) Loading
services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java 0 → 100644 +108 −0 Original line number Original line Diff line number Diff line /* * 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.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.IContextHubEndpoint; import android.hardware.contexthub.IContextHubEndpointCallback; import android.hardware.location.IContextHubTransactionCallback; /** * A class that represents a broker for the endpoint registered by the client app. This class * manages direct IContextHubEndpoint/IContextHubEndpointCallback API/callback calls. * * @hide */ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub { private static final String TAG = "ContextHubEndpointBroker"; /** The context of the service. */ private final Context mContext; /** The proxy to talk to the Context Hub HAL. */ private final IContextHubWrapper mContextHubProxy; /** The manager that registered this endpoint. */ private final ContextHubEndpointManager mEndpointManager; /** Metadata about this endpoint (app-facing container). */ private final HubEndpointInfo mEndpointInfo; /** Metadata about this endpoint (HAL-facing container). */ private final EndpointInfo mHalEndpointInfo; /** The remote callback interface for this endpoint. */ private final IContextHubEndpointCallback mContextHubEndpointCallback; /* package */ ContextHubEndpointBroker( Context context, IContextHubWrapper contextHubProxy, ContextHubEndpointManager endpointManager, EndpointInfo halEndpointInfo, IContextHubEndpointCallback callback) { mContext = context; mContextHubProxy = contextHubProxy; mEndpointManager = endpointManager; mEndpointInfo = new HubEndpointInfo(halEndpointInfo); mHalEndpointInfo = halEndpointInfo; mContextHubEndpointCallback = callback; } @Override public HubEndpointInfo getAssignedHubEndpointInfo() { return mEndpointInfo; } @Override public int openSession(HubEndpointInfo destination, HubServiceInfo serviceInfo) { // TODO(b/378487799): Implement this return 0; } @Override public void closeSession(int sessionId, int reason) { // TODO(b/378487799): Implement this } @Override public void openSessionRequestComplete(int sessionId) { // TODO(b/378487799): Implement this } @Override public void unregister() { // TODO(b/378487799): Implement this } @Override public void sendMessage( int sessionId, HubMessage message, IContextHubTransactionCallback callback) { // TODO(b/381102453): Implement this } @Override public void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode) { // TODO(b/381102453): Implement this } }
services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java 0 → 100644 +111 −0 Original line number Original line Diff line number Diff line /* * 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.content.Context; import android.hardware.contexthub.EndpointInfo; import android.hardware.contexthub.HubEndpointInfo; import android.hardware.contexthub.IContextHubEndpoint; import android.hardware.contexthub.IContextHubEndpointCallback; import android.os.RemoteException; import android.util.Log; import com.android.internal.annotations.GuardedBy; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * A class that manages registration/unregistration of clients and manages messages to/from clients. * * @hide */ /* package */ class ContextHubEndpointManager { private static final String TAG = "ContextHubEndpointManager"; /** The hub ID of the Context Hub Service. */ private static final long SERVICE_HUB_ID = 0x416e64726f696400L; /** The context of the service. */ private final Context mContext; /** The proxy to talk to the Context Hub. */ private final IContextHubWrapper mContextHubProxy; /** A map of endpoint IDs to brokers currently registered. */ private final Map<Long, ContextHubEndpointBroker> mEndpointMap = new ConcurrentHashMap<>(); /** Variables for managing endpoint ID creation */ private final Object mEndpointLock = new Object(); @GuardedBy("mEndpointLock") private long mNextEndpointId = 0; /* package */ ContextHubEndpointManager(Context context, IContextHubWrapper contextHubProxy) { mContext = context; mContextHubProxy = contextHubProxy; } /** * Registers a new endpoint with the service. * * @param pendingEndpointInfo the object describing the endpoint being registered * @param callback the callback interface of the endpoint to register * @return the endpoint interface * @throws IllegalStateException if max number of endpoints have already registered */ /* package */ IContextHubEndpoint registerEndpoint( HubEndpointInfo pendingEndpointInfo, IContextHubEndpointCallback callback) throws RemoteException { ContextHubEndpointBroker broker; long endpointId = getNewEndpointId(); EndpointInfo halEndpointInfo = ContextHubServiceUtil.createHalEndpointInfo( pendingEndpointInfo, endpointId, SERVICE_HUB_ID); try { mContextHubProxy.registerEndpoint(halEndpointInfo); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling HAL registerEndpoint", e); throw e; } broker = new ContextHubEndpointBroker( mContext, mContextHubProxy, this /* endpointManager */, halEndpointInfo, callback); mEndpointMap.put(endpointId, broker); // TODO(b/378487799): Add death recipient Log.d(TAG, "Registered endpoint with ID = " + endpointId); return IContextHubEndpoint.Stub.asInterface(broker); } /** * @return an available endpoint ID */ private long getNewEndpointId() { synchronized (mEndpointLock) { if (mNextEndpointId == Long.MAX_VALUE) { throw new IllegalStateException("Too many endpoints connected"); } return mNextEndpointId++; } } }
services/core/java/com/android/server/location/contexthub/ContextHubService.java +11 −2 Original line number Original line Diff line number Diff line Loading @@ -155,6 +155,9 @@ public class ContextHubService extends IContextHubService.Stub { // The manager for sending messages to/from clients // The manager for sending messages to/from clients private ContextHubClientManager mClientManager; private ContextHubClientManager mClientManager; // Manages endpoint and its sessions between apps and HAL private ContextHubEndpointManager mEndpointManager; // The default client for old API clients // The default client for old API clients private Map<Integer, IContextHubClient> mDefaultClientMap; private Map<Integer, IContextHubClient> mDefaultClientMap; Loading Loading @@ -330,14 +333,17 @@ 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); Log.i(TAG, "Enabling generic offload API"); Log.i(TAG, "Enabling generic offload API"); } catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) { mEndpointManager = null; registry = null; registry = null; Log.w(TAG, "Generic offload API not supported, disabling"); Log.w(TAG, "Generic offload API not supported, disabling"); } } mHubInfoRegistry = registry; mHubInfoRegistry = registry; } else { } else { mHubInfoRegistry = null; mHubInfoRegistry = null; mEndpointManager = null; Log.i(TAG, "Disabling generic offload API"); Log.i(TAG, "Disabling generic offload API"); } } Loading Loading @@ -790,8 +796,11 @@ public class ContextHubService extends IContextHubService.Stub { HubEndpointInfo pendingHubEndpointInfo, IContextHubEndpointCallback callback) HubEndpointInfo pendingHubEndpointInfo, IContextHubEndpointCallback callback) throws RemoteException { throws RemoteException { super.registerEndpoint_enforcePermission(); super.registerEndpoint_enforcePermission(); // TODO(b/375487784): Implement this if (mEndpointManager == null) { return null; Log.e(TAG, "ContextHubService.registerEndpoint: endpoint manager failed to initialize"); throw new UnsupportedOperationException("Endpoint registration is not supported"); } return mEndpointManager.registerEndpoint(pendingHubEndpointInfo, callback); } } @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) Loading
services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java +50 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,9 @@ package com.android.server.location.contexthub; import android.Manifest; import android.Manifest; import android.content.Context; import android.content.Context; import android.hardware.contexthub.EndpointInfo; import android.hardware.contexthub.HubEndpointInfo; import android.hardware.contexthub.HubServiceInfo; import android.hardware.contexthub.V1_0.AsyncEventType; import android.hardware.contexthub.V1_0.AsyncEventType; import android.hardware.contexthub.V1_0.ContextHubMsg; import android.hardware.contexthub.V1_0.ContextHubMsg; import android.hardware.contexthub.V1_0.HostEndPoint; import android.hardware.contexthub.V1_0.HostEndPoint; Loading Loading @@ -415,4 +418,51 @@ import java.util.List; static String formatDateFromTimestamp(long timeStampInMs) { static String formatDateFromTimestamp(long timeStampInMs) { return DATE_FORMATTER.format(Instant.ofEpochMilli(timeStampInMs)); return DATE_FORMATTER.format(Instant.ofEpochMilli(timeStampInMs)); } } /** * Converts a context hub HAL EndpointInfo object based on the provided HubEndpointInfo. * * @param info the HubEndpointInfo object * @return the equivalent EndpointInfo object */ /* package */ static EndpointInfo convertHalEndpointInfo(HubEndpointInfo info) { return createHalEndpointInfo( info, info.getIdentifier().getEndpoint(), info.getIdentifier().getHub()); } /** * Creates a context hub HAL EndpointInfo object based on the provided HubEndpointInfo. As * opposed to convertHalEndpointInfo, this method can be used to overwrite/specify the endpoint * and hub ID. * * @param info the HubEndpointInfo object * @param endpointId the endpoint ID of this object * @param hubId the hub ID of this object * @return the equivalent EndpointInfo object */ /* package */ static EndpointInfo createHalEndpointInfo(HubEndpointInfo info, long endpointId, long hubId) { EndpointInfo outputInfo = new EndpointInfo(); outputInfo.id = new android.hardware.contexthub.EndpointId(); outputInfo.id.id = endpointId; outputInfo.id.hubId = hubId; outputInfo.name = info.getName(); outputInfo.version = info.getVersion(); outputInfo.tag = info.getTag(); Collection<String> permissions = info.getRequiredPermissions(); outputInfo.requiredPermissions = permissions.toArray(new String[permissions.size()]); Collection<HubServiceInfo> services = info.getServiceInfoCollection(); outputInfo.services = new android.hardware.contexthub.Service[services.size()]; int i = 0; for (HubServiceInfo service : services) { outputInfo.services[i] = new android.hardware.contexthub.Service(); outputInfo.services[i].format = service.getFormat(); outputInfo.services[i].serviceDescriptor = service.getServiceDescriptor(); outputInfo.services[i].majorVersion = service.getMajorVersion(); outputInfo.services[i].minorVersion = service.getMinorVersion(); i++; } return outputInfo; } } }