diff options
6 files changed, 121 insertions, 176 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 2c072d0ed8fe..594e16452f7e 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java @@ -23,6 +23,7 @@ import android.hardware.contexthub.HubEndpointInfo; import android.hardware.contexthub.HubMessage; import android.hardware.contexthub.IContextHubEndpoint; import android.hardware.contexthub.IContextHubEndpointCallback; +import android.hardware.contexthub.IEndpointCommunication; import android.hardware.contexthub.Message; import android.hardware.contexthub.MessageDeliveryStatus; import android.hardware.location.ContextHubTransaction; @@ -50,8 +51,8 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /** The context of the service. */ private final Context mContext; - /** The proxy to talk to the Context Hub HAL. */ - private final IContextHubWrapper mContextHubProxy; + /** The proxy to talk to the Context Hub HAL for endpoint communication. */ + private final IEndpointCommunication mHubInterface; /** The manager that registered this endpoint. */ private final ContextHubEndpointManager mEndpointManager; @@ -90,14 +91,14 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /* package */ ContextHubEndpointBroker( Context context, - IContextHubWrapper contextHubProxy, + IEndpointCommunication hubInterface, ContextHubEndpointManager endpointManager, EndpointInfo halEndpointInfo, IContextHubEndpointCallback callback, String packageName, ContextHubTransactionManager transactionManager) { mContext = context; - mContextHubProxy = contextHubProxy; + mHubInterface = hubInterface; mEndpointManager = endpointManager; mEndpointInfo = new HubEndpointInfo(halEndpointInfo); mHalEndpointInfo = halEndpointInfo; @@ -123,7 +124,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub synchronized (mOpenSessionLock) { try { mPendingSessionIds.add(sessionId); - mContextHubProxy.openEndpointSession( + mHubInterface.openEndpointSession( sessionId, halEndpointInfo.id, mHalEndpointInfo.id, @@ -145,7 +146,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub super.closeSession_enforcePermission(); if (!mIsRegistered.get()) throw new IllegalStateException("Endpoint is not registered"); try { - mContextHubProxy.closeEndpointSession( + mHubInterface.closeEndpointSession( sessionId, ContextHubServiceUtil.toHalReason(reason)); } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { Log.e(TAG, "Exception while calling HAL closeEndpointSession", e); @@ -159,7 +160,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub super.unregister_enforcePermission(); mIsRegistered.set(false); try { - mContextHubProxy.unregisterEndpoint(mHalEndpointInfo); + mHubInterface.unregisterEndpoint(mHalEndpointInfo); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling HAL unregisterEndpoint", e); } @@ -183,7 +184,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub super.openSessionRequestComplete_enforcePermission(); synchronized (mOpenSessionLock) { try { - mContextHubProxy.endpointSessionOpenComplete(sessionId); + mHubInterface.endpointSessionOpenComplete(sessionId); mActiveRemoteSessionIds.add(sessionId); } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { Log.e(TAG, "Exception while calling endpointSessionOpenComplete", e); @@ -208,14 +209,14 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub // TODO(b/381102453): Handle permissions if (callback == null) { try { - mContextHubProxy.sendMessageToEndpoint(sessionId, halMessage); + mHubInterface.sendMessageToEndpoint(sessionId, halMessage); } catch (RemoteException e) { Log.w(TAG, "Exception while sending message on session " + sessionId, e); } } else { ContextHubServiceTransaction transaction = mTransactionManager.createSessionMessageTransaction( - sessionId, halMessage, mPackageName, callback); + mHubInterface, sessionId, halMessage, mPackageName, callback); try { mTransactionManager.addTransaction(transaction); } catch (IllegalStateException e) { @@ -240,7 +241,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub status.messageSequenceNumber = messageSeqNumber; status.errorCode = errorCode; try { - mContextHubProxy.sendMessageDeliveryStatusToEndpoint(sessionId, status); + mHubInterface.sendMessageDeliveryStatusToEndpoint(sessionId, status); } catch (RemoteException e) { Log.w( TAG, 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 07df7f994b24..99624b610c33 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java @@ -17,11 +17,14 @@ package com.android.server.location.contexthub; import android.content.Context; +import android.hardware.contexthub.ContextHubInfo; import android.hardware.contexthub.EndpointInfo; import android.hardware.contexthub.HubEndpointInfo; +import android.hardware.contexthub.HubInfo; import android.hardware.contexthub.HubMessage; import android.hardware.contexthub.IContextHubEndpoint; import android.hardware.contexthub.IContextHubEndpointCallback; +import android.hardware.contexthub.IEndpointCommunication; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.util.Log; @@ -75,11 +78,11 @@ import java.util.concurrent.ConcurrentHashMap; @GuardedBy("mEndpointLock") private long mNextEndpointId = -2; - /** The minimum session ID reservable by endpoints (retrieved from HAL) */ - private final int mMinSessionId; + /** The minimum session ID reservable by endpoints (retrieved from HAL in init()) */ + private int mMinSessionId = -1; - /** The minimum session ID reservable by endpoints (retrieved from HAL) */ - private final int mMaxSessionId; + /** The minimum session ID reservable by endpoints (retrieved from HAL in init()) */ + private int mMaxSessionId = -1; /** Variables for managing session ID creation */ private final Object mSessionIdLock = new Object(); @@ -92,8 +95,11 @@ import java.util.concurrent.ConcurrentHashMap; @GuardedBy("mSessionIdLock") private int mNextSessionId = 0; - /** Initialized to true if all initialization in the constructor succeeds. */ - private final boolean mSessionIdsValid; + /** Set true if init() succeeds */ + private boolean mSessionIdsValid = false; + + /** The interface for endpoint communication (retrieved from HAL in init()) */ + private IEndpointCommunication mHubInterface = null; /* package */ ContextHubEndpointManager( Context context, @@ -104,34 +110,73 @@ import java.util.concurrent.ConcurrentHashMap; mContextHubProxy = contextHubProxy; mHubInfoRegistry = hubInfoRegistry; mTransactionManager = transactionManager; + } + + /** + * Initializes this class. + * + * This is separate from the constructor so that this may be passed into the callback registered + * with the HAL. + * + * @throws InstantiationException on any failure + */ + /* package */ void init() throws InstantiationException { + if (mSessionIdsValid) { + throw new IllegalStateException("Already initialized"); + } + try { + HubInfo info = new HubInfo(); + info.hubId = SERVICE_HUB_ID; + // TODO(b/387291125): Populate the ContextHubInfo with real values. + ContextHubInfo contextHubInfo = new ContextHubInfo(); + contextHubInfo.name = ""; + contextHubInfo.vendor = ""; + contextHubInfo.toolchain = ""; + contextHubInfo.supportedPermissions = new String[0]; + info.hubDetails = HubInfo.HubDetails.contextHubInfo(contextHubInfo); + mHubInterface = mContextHubProxy.registerEndpointHub( + new ContextHubHalEndpointCallback(mHubInfoRegistry, this), + info); + if (mHubInterface == null) { + throw new IllegalStateException("Received null IEndpointCommunication"); + } + } catch (RemoteException | IllegalStateException | ServiceSpecificException + | UnsupportedOperationException e) { + String error = "Failed to register ContextHubService as message hub"; + Log.e(TAG, error, e); + throw new InstantiationException(error); + } + int[] range = null; try { - range = mContextHubProxy.requestSessionIdRange(SERVICE_SESSION_RANGE); + range = mHubInterface.requestSessionIdRange(SERVICE_SESSION_RANGE); if (range != null && range.length < SERVICE_SESSION_RANGE_LENGTH) { - Log.e(TAG, "Invalid session ID range: range array size = " + range.length); - range = null; + String error = "Invalid session ID range: range array size = " + range.length; + Log.e(TAG, error); + unregisterHub(); + throw new InstantiationException(error); } } catch (RemoteException | IllegalArgumentException | ServiceSpecificException e) { - Log.e(TAG, "Exception while calling HAL requestSessionIdRange", e); + String error = "Exception while calling HAL requestSessionIdRange"; + Log.e(TAG, error, e); + unregisterHub(); + throw new InstantiationException(error); } - if (range == null) { - mMinSessionId = -1; - mMaxSessionId = -1; - mSessionIdsValid = false; - } else { - mMinSessionId = range[0]; - mMaxSessionId = range[1]; - if (!isSessionIdRangeValid(mMinSessionId, mMaxSessionId)) { - Log.e( - TAG, - "Invalid session ID range: max=" + mMaxSessionId + " min=" + mMinSessionId); - mSessionIdsValid = false; - } else { - mNextSessionId = mMinSessionId; - mSessionIdsValid = true; - } + mMinSessionId = range[0]; + mMaxSessionId = range[1]; + if (!isSessionIdRangeValid(mMinSessionId, mMaxSessionId)) { + String error = + "Invalid session ID range: max=" + mMaxSessionId + " min=" + mMinSessionId; + Log.e(TAG, error); + unregisterHub(); + throw new InstantiationException(error); + } + + synchronized (mSessionIdLock) { + mNextSessionId = mMinSessionId; } + mSessionIdsValid = true; } /** @@ -157,7 +202,7 @@ import java.util.concurrent.ConcurrentHashMap; ContextHubServiceUtil.createHalEndpointInfo( pendingEndpointInfo, endpointId, SERVICE_HUB_ID); try { - mContextHubProxy.registerEndpoint(halEndpointInfo); + mHubInterface.registerEndpoint(halEndpointInfo); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling HAL registerEndpoint", e); throw e; @@ -165,7 +210,7 @@ import java.util.concurrent.ConcurrentHashMap; broker = new ContextHubEndpointBroker( mContext, - mContextHubProxy, + mHubInterface, this /* endpointManager */, halEndpointInfo, callback, @@ -327,6 +372,15 @@ import java.util.concurrent.ConcurrentHashMap; } } + /** Unregister the hub (called during init() failure). Silence errors. */ + private void unregisterHub() { + try { + mHubInterface.unregister(); + } catch (RemoteException | IllegalStateException e) { + Log.e(TAG, "Failed to unregister from HAL on init failure", e); + } + } + /** @return an available endpoint ID */ private long getNewEndpointId() { synchronized (mEndpointLock) { 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 165f9d3340e3..c8a04616623b 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java @@ -336,8 +336,9 @@ public class ContextHubService extends IContextHubService.Stub { mEndpointManager = new ContextHubEndpointManager( mContext, mContextHubWrapper, registry, mTransactionManager); + mEndpointManager.init(); Log.i(TAG, "Enabling generic offload API"); - } catch (UnsupportedOperationException e) { + } catch (InstantiationException e) { mEndpointManager = null; registry = null; Log.w(TAG, "Generic offload API not supported, disabling"); @@ -350,7 +351,6 @@ public class ContextHubService extends IContextHubService.Stub { } initDefaultClientMap(); - initEndpointCallback(); initLocationSettingNotifications(); initWifiSettingNotifications(); @@ -529,18 +529,6 @@ public class ContextHubService extends IContextHubService.Stub { mDefaultClientMap = Collections.unmodifiableMap(defaultClientMap); } - private void initEndpointCallback() { - if (mHubInfoRegistry == null) { - return; - } - try { - mContextHubWrapper.registerEndpointCallback( - new ContextHubHalEndpointCallback(mHubInfoRegistry, mEndpointManager)); - } catch (RemoteException | UnsupportedOperationException e) { - Log.e(TAG, "Exception while registering IEndpointCallback", e); - } - } - /** * Initializes existing callbacks with the mContextHubWrapper for every context hub */ diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java index 5dd40ea97a64..a430a82fc13b 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java @@ -17,6 +17,7 @@ package com.android.server.location.contexthub; import android.chre.flags.Flags; +import android.hardware.contexthub.IEndpointCommunication; import android.hardware.contexthub.Message; import android.hardware.location.ContextHubTransaction; import android.hardware.location.IContextHubTransactionCallback; @@ -402,12 +403,14 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Creates a transaction to send a message through a session. * + * @param hubInterface Interface for interacting with other endpoint hubs. * @param sessionId The ID of the endpoint session the message should be sent through. * @param message The message to send. * @param transactionCallback The callback of the transactions. * @return The generated transaction. */ /* package */ ContextHubServiceTransaction createSessionMessageTransaction( + IEndpointCommunication hubInterface, int sessionId, Message message, String packageName, @@ -422,7 +425,7 @@ import java.util.concurrent.atomic.AtomicInteger; /* package */ int onTransact() { try { message.sequenceNumber = getMessageSequenceNumber(); - mContextHubProxy.sendMessageToEndpoint(sessionId, message); + hubInterface.sendMessageToEndpoint(sessionId, message); return ContextHubTransaction.RESULT_SUCCESS; } catch (RemoteException e) { Log.e(TAG, "RemoteException while trying to send a session message", 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 503f1aca64d9..6e650c207358 100644 --- a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java +++ b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java @@ -98,10 +98,16 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl private final Object mCallbackLock = new Object(); - HubInfoRegistry(IContextHubWrapper contextHubWrapper) { + HubInfoRegistry(IContextHubWrapper contextHubWrapper) throws InstantiationException { mContextHubWrapper = contextHubWrapper; - refreshCachedHubs(); - refreshCachedEndpoints(); + try { + refreshCachedHubs(); + refreshCachedEndpoints(); + } catch (UnsupportedOperationException e) { + String error = "Failed to update hub and endpoint cache"; + Log.e(TAG, error, e); + throw new InstantiationException(error); + } } /** Retrieve the list of hubs available. */ 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 e1df503eccdb..a9bd38f6daf9 100644 --- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java +++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java @@ -18,10 +18,8 @@ package com.android.server.location.contexthub; import android.annotation.NonNull; import android.annotation.Nullable; import android.chre.flags.Flags; -import android.hardware.contexthub.EndpointId; import android.hardware.contexthub.HostEndpointInfo; import android.hardware.contexthub.HubEndpointInfo; -import android.hardware.contexthub.Message; import android.hardware.contexthub.MessageDeliveryStatus; import android.hardware.contexthub.NanSessionRequest; import android.hardware.contexthub.V1_0.ContextHub; @@ -238,40 +236,13 @@ public abstract class IContextHubWrapper { } /** Calls the appropriate registerEndpointCallback function depending on the HAL version. */ - public void registerEndpointCallback(android.hardware.contexthub.IEndpointCallback cb) - throws RemoteException {} - - /** Registers the endpoint with the ContextHub HAL */ - public void registerEndpoint(android.hardware.contexthub.EndpointInfo info) - throws RemoteException {} - - /** Unregisters a previously registered endpoint */ - public int[] requestSessionIdRange(int size) throws RemoteException { - return null; + public android.hardware.contexthub.IEndpointCommunication registerEndpointHub( + android.hardware.contexthub.IEndpointCallback cb, + android.hardware.contexthub.HubInfo hubInfo) + throws RemoteException { + throw new UnsupportedOperationException(); } - /** Opens an endpoint session between two endpoints */ - public void openEndpointSession( - int sessionId, EndpointId destination, EndpointId initiator, String serviceDescriptor) - throws RemoteException {} - - /** Closes a previously opened endpoint */ - public void closeEndpointSession(int sessionId, byte reason) throws RemoteException {} - - /** Unregisters a previously registered endpoint */ - 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 {} - - /** Sends a message to a remote endpoint */ - public void sendMessageToEndpoint(int sessionId, Message msg) throws RemoteException {} - - /** Sends a message delivery status to a remote endpoint */ - public void sendMessageDeliveryStatusToEndpoint(int sessionId, MessageDeliveryStatus msgStatus) - throws RemoteException {} - /** * @return True if this version of the Contexthub HAL supports Location setting notifications. */ @@ -691,97 +662,19 @@ public abstract class IContextHubWrapper { } @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); - } - - @Override - public void registerEndpoint(android.hardware.contexthub.EndpointInfo info) - throws RemoteException { - android.hardware.contexthub.IContextHub hub = getHub(); - if (hub == null) { - return; - } - hub.registerEndpoint(info); - } - - @Override - public int[] requestSessionIdRange(int size) throws RemoteException { + public android.hardware.contexthub.IEndpointCommunication registerEndpointHub( + android.hardware.contexthub.IEndpointCallback cb, + android.hardware.contexthub.HubInfo hubInfo) + throws RemoteException { android.hardware.contexthub.IContextHub hub = getHub(); if (hub == null) { return null; } - return hub.requestSessionIdRange(size); - } - - @Override - public void openEndpointSession( - int sessionId, - EndpointId destination, - EndpointId initiator, - String serviceDescriptor) - throws RemoteException { - android.hardware.contexthub.IContextHub hub = getHub(); - if (hub == null) { - return; - } - hub.openEndpointSession(sessionId, destination, initiator, serviceDescriptor); - } - - @Override - public void closeEndpointSession(int sessionId, byte reason) throws RemoteException { - android.hardware.contexthub.IContextHub hub = getHub(); - if (hub == null) { - return; - } - hub.closeEndpointSession(sessionId, reason); - } - - @Override - public void unregisterEndpoint(android.hardware.contexthub.EndpointInfo info) - throws RemoteException { - android.hardware.contexthub.IContextHub hub = getHub(); - if (hub == null) { - return; - } - hub.unregisterEndpoint(info); - } - @Override - public void endpointSessionOpenComplete(int sessionId) throws RemoteException { - android.hardware.contexthub.IContextHub hub = getHub(); - if (hub == null) { - return; - } - hub.endpointSessionOpenComplete(sessionId); - } - - @Override - public void sendMessageToEndpoint(int sessionId, Message msg) throws RemoteException { - android.hardware.contexthub.IContextHub hub = getHub(); - if (hub == null) { - return; - } - hub.sendMessageToEndpoint(sessionId, msg); - } - - @Override - public void sendMessageDeliveryStatusToEndpoint( - int sessionId, MessageDeliveryStatus msgStatus) throws RemoteException { - android.hardware.contexthub.IContextHub hub = getHub(); - if (hub == null) { - return; + if (DEBUG) { + Log.i(TAG, "registerEndpointHub: cb=" + cb); } - hub.sendMessageDeliveryStatusToEndpoint(sessionId, msgStatus); + return hub.registerEndpointHub(cb, hubInfo); } public boolean supportsLocationSettingNotifications() { |