diff options
7 files changed, 283 insertions, 65 deletions
diff --git a/core/java/android/hardware/contexthub/HubEndpoint.java b/core/java/android/hardware/contexthub/HubEndpoint.java index 6c669a3d7032..71702d996883 100644 --- a/core/java/android/hardware/contexthub/HubEndpoint.java +++ b/core/java/android/hardware/contexthub/HubEndpoint.java @@ -358,6 +358,7 @@ public class HubEndpoint { service.registerEndpoint( mPendingHubEndpointInfo, mServiceCallback, + mPendingHubEndpointInfo.getName(), mPendingHubEndpointInfo.getTag()); mAssignedHubEndpointInfo = serviceToken.getAssignedHubEndpointInfo(); mServiceToken = serviceToken; @@ -514,6 +515,7 @@ public class HubEndpoint { /** Create a builder for {@link HubEndpoint} */ public Builder(@NonNull Context context) { mPackageName = context.getPackageName(); + mTag = context.getAttributionTag(); mVersion = (int) context.getApplicationInfo().longVersionCode; mMainExecutor = context.getMainExecutor(); } @@ -532,6 +534,7 @@ public class HubEndpoint { /** * Set a tag string. The tag can be used to further identify the creator of the endpoint. * Endpoints created by the same package share the same name but should have different tags. + * The default value of the tag is retrieved from {@link Context#getAttributionTag()}. */ @NonNull public Builder setTag(@NonNull String tag) { diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl index 2a472375a00f..d5b3fa251e82 100644 --- a/core/java/android/hardware/location/IContextHubService.aidl +++ b/core/java/android/hardware/location/IContextHubService.aidl @@ -137,7 +137,7 @@ interface IContextHubService { // Register an endpoint with the context hub @EnforcePermission("ACCESS_CONTEXT_HUB") - IContextHubEndpoint registerEndpoint(in HubEndpointInfo pendingEndpointInfo, in IContextHubEndpointCallback callback, String packageName); + IContextHubEndpoint registerEndpoint(in HubEndpointInfo pendingEndpointInfo, in IContextHubEndpointCallback callback, String packageName, String attributionTag); // Register an endpoint discovery callback (id) @EnforcePermission("ACCESS_CONTEXT_HUB") 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 594e16452f7e..87d809b5e850 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java @@ -16,6 +16,7 @@ package com.android.server.location.contexthub; +import android.app.AppOpsManager; import android.content.Context; import android.hardware.contexthub.EndpointInfo; import android.hardware.contexthub.ErrorCode; @@ -26,16 +27,18 @@ import android.hardware.contexthub.IContextHubEndpointCallback; import android.hardware.contexthub.IEndpointCommunication; import android.hardware.contexthub.Message; import android.hardware.contexthub.MessageDeliveryStatus; +import android.hardware.contexthub.Reason; import android.hardware.location.ContextHubTransaction; import android.hardware.location.IContextHubTransactionCallback; +import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; +import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; -import java.util.HashSet; -import java.util.Set; +import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -45,9 +48,12 @@ import java.util.concurrent.atomic.AtomicBoolean; * @hide */ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub - implements IBinder.DeathRecipient { + implements IBinder.DeathRecipient, AppOpsManager.OnOpChangedListener { private static final String TAG = "ContextHubEndpointBroker"; + /** Message used by noteOp when this client receives a message from an endpoint. */ + private static final String RECEIVE_MSG_NOTE = "ContextHubEndpointMessageDelivery"; + /** The context of the service. */ private final Context mContext; @@ -57,6 +63,9 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /** The manager that registered this endpoint. */ private final ContextHubEndpointManager mEndpointManager; + /** Manager used for noting permissions usage of this broker. */ + private final AppOpsManager mAppOpsManager; + /** Metadata about this endpoint (app-facing container). */ private final HubEndpointInfo mEndpointInfo; @@ -71,24 +80,60 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub 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<>(); + static class SessionInfo { + enum SessionState { + /* The session is pending acceptance from the remote endpoint. */ + PENDING, + /* The session is active and can transport messages. */ + ACTIVE, + }; - /** The set of session IDs that are actively enabled by this endpoint */ - @GuardedBy("mOpenSessionLock") - private final Set<Integer> mActiveSessionIds = new HashSet<>(); + private final HubEndpointInfo mRemoteEndpointInfo; + + private SessionState mSessionState = SessionState.PENDING; + + private final boolean mRemoteInitiated; - /** The set of session IDs that are actively enabled by the remote endpoint */ + SessionInfo(HubEndpointInfo remoteEndpointInfo, boolean remoteInitiated) { + mRemoteEndpointInfo = remoteEndpointInfo; + mRemoteInitiated = remoteInitiated; + } + + public boolean isRemoteInitiated() { + return mRemoteInitiated; + } + + public HubEndpointInfo getRemoteEndpointInfo() { + return mRemoteEndpointInfo; + } + + public void setSessionState(SessionState state) { + mSessionState = state; + } + + public boolean isActive() { + return mSessionState == SessionState.ACTIVE; + } + } + + /** A map between a session ID which maps to its current state. */ @GuardedBy("mOpenSessionLock") - private final Set<Integer> mActiveRemoteSessionIds = new HashSet<>(); + private final SparseArray<SessionInfo> mSessionInfoMap = new SparseArray<>(); /** The package name of the app that created the endpoint */ private final String mPackageName; - /* Transaction manager used for sending reliable messages */ + /** The attribution tag of the module that created the endpoint */ + private final String mAttributionTag; + + /** Transaction manager used for sending reliable messages */ private final ContextHubTransactionManager mTransactionManager; + /** The PID/UID of the endpoint package providing IContextHubEndpointCallback */ + private final int mPid; + + private final int mUid; + /* package */ ContextHubEndpointBroker( Context context, IEndpointCommunication hubInterface, @@ -96,6 +141,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub EndpointInfo halEndpointInfo, IContextHubEndpointCallback callback, String packageName, + String attributionTag, ContextHubTransactionManager transactionManager) { mContext = context; mHubInterface = hubInterface; @@ -104,7 +150,14 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub mHalEndpointInfo = halEndpointInfo; mContextHubEndpointCallback = callback; mPackageName = packageName; + mAttributionTag = attributionTag; mTransactionManager = transactionManager; + + mPid = Binder.getCallingPid(); + mUid = Binder.getCallingUid(); + + mAppOpsManager = context.getSystemService(AppOpsManager.class); + mAppOpsManager.startWatchingMode(AppOpsManager.OP_NONE, mPackageName, this); } @Override @@ -118,12 +171,17 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub throws RemoteException { super.openSession_enforcePermission(); if (!mIsRegistered.get()) throw new IllegalStateException("Endpoint is not registered"); + if (!hasEndpointPermissions(destination)) { + throw new SecurityException( + "Insufficient permission to open a session with endpoint: " + destination); + } + int sessionId = mEndpointManager.reserveSessionId(); EndpointInfo halEndpointInfo = ContextHubServiceUtil.convertHalEndpointInfo(destination); synchronized (mOpenSessionLock) { try { - mPendingSessionIds.add(sessionId); + mSessionInfoMap.put(sessionId, new SessionInfo(destination, false)); mHubInterface.openEndpointSession( sessionId, halEndpointInfo.id, @@ -131,8 +189,7 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub serviceDescriptor); } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { Log.e(TAG, "Exception while calling HAL openEndpointSession", e); - mPendingSessionIds.remove(sessionId); - mEndpointManager.returnSessionId(sessionId); + cleanupSessionResources(sessionId); throw e; } @@ -145,13 +202,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub public void closeSession(int sessionId, int reason) throws RemoteException { super.closeSession_enforcePermission(); if (!mIsRegistered.get()) throw new IllegalStateException("Endpoint is not registered"); - try { - mHubInterface.closeEndpointSession( - sessionId, ContextHubServiceUtil.toHalReason(reason)); - } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { - Log.e(TAG, "Exception while calling HAL closeEndpointSession", e); - throw e; + if (!cleanupSessionResources(sessionId)) { + throw new IllegalArgumentException( + "Unknown session ID in closeSession: id=" + sessionId); } + halCloseEndpointSession(sessionId, ContextHubServiceUtil.toHalReason(reason)); } @Override @@ -165,15 +220,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub Log.e(TAG, "RemoteException while calling HAL unregisterEndpoint", e); } synchronized (mOpenSessionLock) { - for (int id : mPendingSessionIds) { - mEndpointManager.returnSessionId(id); + // Iterate in reverse since cleanupSessionResources will remove the entry + for (int i = mSessionInfoMap.size() - 1; i >= 0; i--) { + int id = mSessionInfoMap.keyAt(i); + cleanupSessionResources(id); } - for (int id : mActiveSessionIds) { - mEndpointManager.returnSessionId(id); - } - mPendingSessionIds.clear(); - mActiveSessionIds.clear(); - mActiveRemoteSessionIds.clear(); } mEndpointManager.unregisterEndpoint(mEndpointInfo.getIdentifier().getEndpoint()); } @@ -183,9 +234,14 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub public void openSessionRequestComplete(int sessionId) { super.openSessionRequestComplete_enforcePermission(); synchronized (mOpenSessionLock) { + SessionInfo info = mSessionInfoMap.get(sessionId); + if (info == null) { + throw new IllegalArgumentException( + "openSessionRequestComplete for invalid session id=" + sessionId); + } try { mHubInterface.endpointSessionOpenComplete(sessionId); - mActiveRemoteSessionIds.add(sessionId); + info.setSessionState(SessionInfo.SessionState.ACTIVE); } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { Log.e(TAG, "Exception while calling endpointSessionOpenComplete", e); } @@ -198,15 +254,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub int sessionId, HubMessage message, IContextHubTransactionCallback callback) { super.sendMessage_enforcePermission(); Message halMessage = ContextHubServiceUtil.createHalMessage(message); - synchronized (mOpenSessionLock) { - if (!mActiveSessionIds.contains(sessionId) - && !mActiveRemoteSessionIds.contains(sessionId)) { - throw new SecurityException( - "sendMessage called on inactive session (id= " + sessionId + ")"); - } + if (!isSessionActive(sessionId)) { + throw new SecurityException( + "sendMessage called on inactive session (id= " + sessionId + ")"); } - // TODO(b/381102453): Handle permissions if (callback == null) { try { mHubInterface.sendMessageToEndpoint(sessionId, halMessage); @@ -258,6 +310,31 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub } } + @Override + public void onOpChanged(String op, String packageName) { + if (!packageName.equals(mPackageName)) { + Log.w( + TAG, + "onOpChanged called with invalid package " + + packageName + + " expected " + + mPackageName); + } else { + synchronized (mOpenSessionLock) { + // Iterate in reverse since cleanupSessionResources will remove the entry + for (int i = mSessionInfoMap.size() - 1; i >= 0; i--) { + int id = mSessionInfoMap.keyAt(i); + HubEndpointInfo target = mSessionInfoMap.get(id).getRemoteEndpointInfo(); + if (!hasEndpointPermissions(target)) { + halCloseEndpointSessionNoThrow(id, Reason.PERMISSION_DENIED); + onCloseEndpointSession(id, Reason.PERMISSION_DENIED); + // Resource cleanup is done in onCloseEndpointSession + } + } + } + } + } + /* package */ void attachDeathRecipient() throws RemoteException { if (mContextHubEndpointCallback != null) { mContextHubEndpointCallback.asBinder().linkToDeath(this, 0 /* flags */); @@ -266,21 +343,36 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /* package */ void onEndpointSessionOpenRequest( int sessionId, HubEndpointInfo initiator, String serviceDescriptor) { + if (!hasEndpointPermissions(initiator)) { + halCloseEndpointSessionNoThrow(sessionId, Reason.PERMISSION_DENIED); + return; + } + + synchronized (mOpenSessionLock) { + if (hasSessionId(sessionId)) { + Log.e(TAG, "Existing session in onEndpointSessionOpenRequest: id=" + sessionId); + halCloseEndpointSessionNoThrow(sessionId, Reason.UNSPECIFIED); + return; + } + mSessionInfoMap.put(sessionId, new SessionInfo(initiator, true)); + } + if (mContextHubEndpointCallback != null) { try { mContextHubEndpointCallback.onSessionOpenRequest( sessionId, initiator, serviceDescriptor); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling onSessionOpenRequest", e); + cleanupSessionResources(sessionId); + return; } } } /* package */ void onCloseEndpointSession(int sessionId, byte reason) { - synchronized (mOpenSessionLock) { - mPendingSessionIds.remove(sessionId); - mActiveSessionIds.remove(sessionId); - mActiveRemoteSessionIds.remove(sessionId); + if (!cleanupSessionResources(sessionId)) { + Log.w(TAG, "Unknown session ID in onCloseEndpointSession: id=" + sessionId); + return; } if (mContextHubEndpointCallback != null) { try { @@ -294,8 +386,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /* package */ void onEndpointSessionOpenComplete(int sessionId) { synchronized (mOpenSessionLock) { - mPendingSessionIds.remove(sessionId); - mActiveSessionIds.add(sessionId); + if (!hasSessionId(sessionId)) { + Log.w(TAG, "Unknown session ID in onEndpointSessionOpenComplete: id=" + sessionId); + return; + } + mSessionInfoMap.get(sessionId).setSessionState(SessionInfo.SessionState.ACTIVE); } if (mContextHubEndpointCallback != null) { try { @@ -307,11 +402,51 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub } /* package */ void onMessageReceived(int sessionId, HubMessage message) { + HubEndpointInfo remote; + synchronized (mOpenSessionLock) { + if (!isSessionActive(sessionId)) { + Log.e( + TAG, + "Dropping message for inactive session (id=" + + sessionId + + ") with message: " + + message); + sendMessageDeliveryStatus( + sessionId, message.getMessageSequenceNumber(), ErrorCode.PERMANENT_ERROR); + return; + } + remote = mSessionInfoMap.get(sessionId).getRemoteEndpointInfo(); + } + if (!ContextHubServiceUtil.notePermissions( + mAppOpsManager, + mUid, + mPackageName, + mAttributionTag, + remote.getRequiredPermissions(), + RECEIVE_MSG_NOTE + + "-0x" + + Long.toHexString(remote.getIdentifier().getHub()) + + "-0x" + + Long.toHexString(remote.getIdentifier().getEndpoint()))) { + Log.e( + TAG, + "Dropping message from " + + remote + + ". " + + mPackageName + + " doesn't have permission"); + sendMessageDeliveryStatus( + sessionId, message.getMessageSequenceNumber(), ErrorCode.PERMISSION_DENIED); + return; + } + if (mContextHubEndpointCallback != null) { try { mContextHubEndpointCallback.onMessageReceived(sessionId, message); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling onMessageReceived", e); + sendMessageDeliveryStatus( + sessionId, message.getMessageSequenceNumber(), ErrorCode.TRANSIENT_ERROR); } } } @@ -323,9 +458,66 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /* package */ boolean hasSessionId(int sessionId) { synchronized (mOpenSessionLock) { - return mPendingSessionIds.contains(sessionId) - || mActiveSessionIds.contains(sessionId) - || mActiveRemoteSessionIds.contains(sessionId); + return mSessionInfoMap.contains(sessionId); } } + + /** + * Calls the HAL closeEndpointSession API. + * + * @param sessionId The session ID to close + * @param halReason The HAL reason + */ + private void halCloseEndpointSession(int sessionId, byte halReason) throws RemoteException { + try { + mHubInterface.closeEndpointSession(sessionId, halReason); + } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { + throw e; + } + } + + /** Same as halCloseEndpointSession but does not throw the exception */ + private void halCloseEndpointSessionNoThrow(int sessionId, byte halReason) { + try { + halCloseEndpointSession(sessionId, halReason); + } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) { + Log.e(TAG, "Exception while calling HAL closeEndpointSession", e); + } + } + + /** + * Cleans up resources related to a session with the provided ID. + * + * @param sessionId The session ID to clean up resources for + * @return false if the session ID was invalid + */ + private boolean cleanupSessionResources(int sessionId) { + synchronized (mOpenSessionLock) { + SessionInfo info = mSessionInfoMap.get(sessionId); + if (info != null && !info.isRemoteInitiated()) { + mEndpointManager.returnSessionId(sessionId); + mSessionInfoMap.remove(sessionId); + } + return info != null; + } + } + + /** + * @param sessionId The ID of the session to check + * @return true if the session with the given ID is currently active + */ + private boolean isSessionActive(int sessionId) { + synchronized (mOpenSessionLock) { + return hasSessionId(sessionId) && mSessionInfoMap.get(sessionId).isActive(); + } + } + + /** + * @param targetEndpointInfo The target endpoint to check permissions for + * @return true if this endpoint has sufficient permission to the provided target endpoint + */ + private boolean hasEndpointPermissions(HubEndpointInfo targetEndpointInfo) { + Collection<String> requiredPermissions = targetEndpointInfo.getRequiredPermissions(); + return ContextHubServiceUtil.hasPermissions(mContext, mPid, mUid, requiredPermissions); + } } 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 99624b610c33..7698a87f80c9 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java @@ -191,7 +191,8 @@ import java.util.concurrent.ConcurrentHashMap; /* package */ IContextHubEndpoint registerEndpoint( HubEndpointInfo pendingEndpointInfo, IContextHubEndpointCallback callback, - String packageName) + String packageName, + String attributionTag) throws RemoteException { if (!mSessionIdsValid) { throw new IllegalStateException("ContextHubEndpointManager failed to initialize"); @@ -215,6 +216,7 @@ import java.util.concurrent.ConcurrentHashMap; halEndpointInfo, callback, packageName, + attributionTag, mTransactionManager); mEndpointMap.put(endpointId, broker); 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 f1f2217fc3c4..88764b6601ff 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java @@ -21,6 +21,9 @@ import android.hardware.contexthub.HubMessage; import android.hardware.contexthub.IEndpointCallback; import android.hardware.contexthub.Message; import android.hardware.contexthub.MessageDeliveryStatus; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Process; import android.os.RemoteException; /** IEndpointCallback implementation. */ @@ -29,6 +32,11 @@ public class ContextHubHalEndpointCallback private final IEndpointLifecycleCallback mEndpointLifecycleCallback; private final IEndpointSessionCallback mEndpointSessionCallback; + // Use this thread in case where the execution requires to be on an async service thread. + private final HandlerThread mHandlerThread = + new HandlerThread("Context Hub endpoint callback", Process.THREAD_PRIORITY_BACKGROUND); + private Handler mHandler; + /** Interface for listening for endpoint start and stop events. */ public interface IEndpointLifecycleCallback { /** Called when a batch of endpoints started. */ @@ -65,6 +73,9 @@ public class ContextHubHalEndpointCallback IEndpointSessionCallback endpointSessionCallback) { mEndpointLifecycleCallback = endpointLifecycleCallback; mEndpointSessionCallback = endpointSessionCallback; + + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); } @Override @@ -77,7 +88,7 @@ public class ContextHubHalEndpointCallback for (int i = 0; i < halEndpointInfos.length; i++) { endpointInfos[i] = new HubEndpointInfo(halEndpointInfos[i]); } - mEndpointLifecycleCallback.onEndpointStarted(endpointInfos); + mHandler.post(() -> mEndpointLifecycleCallback.onEndpointStarted(endpointInfos)); } @Override @@ -87,40 +98,48 @@ public class ContextHubHalEndpointCallback for (int i = 0; i < halEndpointIds.length; i++) { endpointIds[i] = new HubEndpointInfo.HubEndpointIdentifier(halEndpointIds[i]); } - mEndpointLifecycleCallback.onEndpointStopped(endpointIds, reason); + mHandler.post(() -> mEndpointLifecycleCallback.onEndpointStopped(endpointIds, reason)); } @Override public void onEndpointSessionOpenRequest( - int i, EndpointId destination, EndpointId initiator, String s) throws RemoteException { + int sessionId, EndpointId destination, EndpointId initiator, String serviceDescriptor) + 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); + mHandler.post( + () -> + mEndpointSessionCallback.onEndpointSessionOpenRequest( + sessionId, destinationId, initiatorId, serviceDescriptor)); } @Override - public void onCloseEndpointSession(int i, byte b) throws RemoteException { - mEndpointSessionCallback.onCloseEndpointSession(i, b); + public void onCloseEndpointSession(int sessionId, byte reason) throws RemoteException { + mHandler.post(() -> mEndpointSessionCallback.onCloseEndpointSession(sessionId, reason)); } @Override - public void onEndpointSessionOpenComplete(int i) throws RemoteException { - mEndpointSessionCallback.onEndpointSessionOpenComplete(i); + public void onEndpointSessionOpenComplete(int sessionId) throws RemoteException { + mHandler.post(() -> mEndpointSessionCallback.onEndpointSessionOpenComplete(sessionId)); } @Override - public void onMessageReceived(int i, Message message) throws RemoteException { + public void onMessageReceived(int sessionId, Message message) throws RemoteException { HubMessage hubMessage = ContextHubServiceUtil.createHubMessage(message); - mEndpointSessionCallback.onMessageReceived(i, hubMessage); + mHandler.post(() -> mEndpointSessionCallback.onMessageReceived(sessionId, hubMessage)); } @Override - public void onMessageDeliveryStatusReceived(int i, MessageDeliveryStatus messageDeliveryStatus) - throws RemoteException { - mEndpointSessionCallback.onMessageDeliveryStatusReceived( - i, messageDeliveryStatus.messageSequenceNumber, messageDeliveryStatus.errorCode); + public void onMessageDeliveryStatusReceived( + int sessionId, MessageDeliveryStatus messageDeliveryStatus) throws RemoteException { + mHandler.post( + () -> + mEndpointSessionCallback.onMessageDeliveryStatusReceived( + sessionId, + messageDeliveryStatus.messageSequenceNumber, + messageDeliveryStatus.errorCode)); } @Override 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 f00328c1e88c..54ed5a9711b3 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java @@ -787,14 +787,16 @@ public class ContextHubService extends IContextHubService.Stub { public IContextHubEndpoint registerEndpoint( HubEndpointInfo pendingHubEndpointInfo, IContextHubEndpointCallback callback, - String packageName) + String packageName, + String attributionTag) throws RemoteException { super.registerEndpoint_enforcePermission(); if (mEndpointManager == null) { Log.e(TAG, "Endpoint manager failed to initialize"); throw new UnsupportedOperationException("Endpoint registration is not supported"); } - return mEndpointManager.registerEndpoint(pendingHubEndpointInfo, callback, packageName); + return mEndpointManager.registerEndpoint( + pendingHubEndpointInfo, callback, packageName, attributionTag); } @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java b/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java index 7b59d6f1301e..a41194b898ac 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java @@ -601,7 +601,7 @@ import java.util.List; int uid, String packageName, String attributionTag, - List<String> permissions, + Collection<String> permissions, String noteMessage) { for (String permission : permissions) { int opCode = AppOpsManager.permissionToOpCode(permission); |