Loading core/java/android/hardware/contexthub/HubEndpoint.java +22 −1 Original line number Original line Diff line number Diff line Loading @@ -137,6 +137,8 @@ public class HubEndpoint { serviceDescriptor, serviceDescriptor, mLifecycleCallback.onSessionOpenRequest( mLifecycleCallback.onSessionOpenRequest( initiator, serviceDescriptor))); initiator, serviceDescriptor))); } else { invokeCallbackFinished(); } } } } Loading @@ -163,6 +165,8 @@ public class HubEndpoint { + result.getReason()); + result.getReason()); rejectSession(sessionId); rejectSession(sessionId); } } invokeCallbackFinished(); } } private void acceptSession( private void acceptSession( Loading Loading @@ -249,7 +253,12 @@ public class HubEndpoint { activeSession.setOpened(); activeSession.setOpened(); if (mLifecycleCallback != null) { if (mLifecycleCallback != null) { mLifecycleCallbackExecutor.execute( mLifecycleCallbackExecutor.execute( () -> mLifecycleCallback.onSessionOpened(activeSession)); () -> { mLifecycleCallback.onSessionOpened(activeSession); invokeCallbackFinished(); }); } else { invokeCallbackFinished(); } } } } Loading Loading @@ -278,7 +287,10 @@ public class HubEndpoint { synchronized (mLock) { synchronized (mLock) { mActiveSessions.remove(sessionId); mActiveSessions.remove(sessionId); } } invokeCallbackFinished(); }); }); } else { invokeCallbackFinished(); } } } } Loading Loading @@ -323,8 +335,17 @@ public class HubEndpoint { e.rethrowFromSystemServer(); e.rethrowFromSystemServer(); } } } } invokeCallbackFinished(); }); }); } } private void invokeCallbackFinished() { try { mServiceToken.onCallbackFinished(); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } }; }; /** Binder returned from system service, non-null while registered. */ /** Binder returned from system service, non-null while registered. */ Loading core/java/android/hardware/contexthub/IContextHubEndpoint.aidl +6 −0 Original line number Original line Diff line number Diff line Loading @@ -94,4 +94,10 @@ interface IContextHubEndpoint { */ */ @EnforcePermission("ACCESS_CONTEXT_HUB") @EnforcePermission("ACCESS_CONTEXT_HUB") void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode); void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode); /** * Invoked when a callback from IContextHubEndpointCallback finishes. */ @EnforcePermission("ACCESS_CONTEXT_HUB") void onCallbackFinished(); } } services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java +89 −32 Original line number Original line Diff line number Diff line Loading @@ -32,7 +32,10 @@ import android.hardware.location.ContextHubTransaction; import android.hardware.location.IContextHubTransactionCallback; import android.hardware.location.IContextHubTransactionCallback; import android.os.Binder; import android.os.Binder; import android.os.IBinder; import android.os.IBinder; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.RemoteException; import android.os.RemoteException; import android.os.WorkSource; import android.util.Log; import android.util.Log; import android.util.SparseArray; import android.util.SparseArray; Loading @@ -54,6 +57,16 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /** Message used by noteOp when this client receives a message from an endpoint. */ /** Message used by noteOp when this client receives a message from an endpoint. */ private static final String RECEIVE_MSG_NOTE = "ContextHubEndpointMessageDelivery"; private static final String RECEIVE_MSG_NOTE = "ContextHubEndpointMessageDelivery"; /** The duration of wakelocks acquired during HAL callbacks */ private static final long WAKELOCK_TIMEOUT_MILLIS = 5 * 1000; /* * Internal interface used to invoke client callbacks. */ interface CallbackConsumer { void accept(IContextHubEndpointCallback callback) throws RemoteException; } /** The context of the service. */ /** The context of the service. */ private final Context mContext; private final Context mContext; Loading Loading @@ -134,6 +147,9 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub private final int mUid; private final int mUid; /** Wakelock held while nanoapp message are in flight to the client */ private final WakeLock mWakeLock; /* package */ ContextHubEndpointBroker( /* package */ ContextHubEndpointBroker( Context context, Context context, IEndpointCommunication hubInterface, IEndpointCommunication hubInterface, Loading @@ -158,6 +174,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub mAppOpsManager = context.getSystemService(AppOpsManager.class); mAppOpsManager = context.getSystemService(AppOpsManager.class); mAppOpsManager.startWatchingMode(AppOpsManager.OP_NONE, mPackageName, this); mAppOpsManager.startWatchingMode(AppOpsManager.OP_NONE, mPackageName, this); PowerManager powerManager = context.getSystemService(PowerManager.class); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.setWorkSource(new WorkSource(mUid, mPackageName)); mWakeLock.setReferenceCounted(true); } } @Override @Override Loading Loading @@ -302,6 +323,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub } } } } @Override @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void onCallbackFinished() { super.onCallbackFinished_enforcePermission(); releaseWakeLock(); } /** Invoked when the underlying binder of this broker has died at the client process. */ /** Invoked when the underlying binder of this broker has died at the client process. */ @Override @Override public void binderDied() { public void binderDied() { Loading Loading @@ -357,15 +385,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub mSessionInfoMap.put(sessionId, new SessionInfo(initiator, true)); mSessionInfoMap.put(sessionId, new SessionInfo(initiator, true)); } } if (mContextHubEndpointCallback != null) { boolean success = try { invokeCallback( mContextHubEndpointCallback.onSessionOpenRequest( (consumer) -> sessionId, initiator, serviceDescriptor); consumer.onSessionOpenRequest( } catch (RemoteException e) { sessionId, initiator, serviceDescriptor)); Log.e(TAG, "RemoteException while calling onSessionOpenRequest", e); if (!success) { cleanupSessionResources(sessionId); cleanupSessionResources(sessionId); return; } } } } } Loading @@ -374,14 +400,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub Log.w(TAG, "Unknown session ID in onCloseEndpointSession: id=" + sessionId); Log.w(TAG, "Unknown session ID in onCloseEndpointSession: id=" + sessionId); return; return; } } if (mContextHubEndpointCallback != null) { try { invokeCallback( mContextHubEndpointCallback.onSessionClosed( (consumer) -> sessionId, ContextHubServiceUtil.toAppHubEndpointReason(reason)); consumer.onSessionClosed( } catch (RemoteException e) { sessionId, ContextHubServiceUtil.toAppHubEndpointReason(reason))); Log.e(TAG, "RemoteException while calling onSessionClosed", e); } } } } /* package */ void onEndpointSessionOpenComplete(int sessionId) { /* package */ void onEndpointSessionOpenComplete(int sessionId) { Loading @@ -392,13 +415,8 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub } } mSessionInfoMap.get(sessionId).setSessionState(SessionInfo.SessionState.ACTIVE); mSessionInfoMap.get(sessionId).setSessionState(SessionInfo.SessionState.ACTIVE); } } if (mContextHubEndpointCallback != null) { try { invokeCallback((consumer) -> consumer.onSessionOpenComplete(sessionId)); mContextHubEndpointCallback.onSessionOpenComplete(sessionId); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling onSessionClosed", e); } } } } /* package */ void onMessageReceived(int sessionId, HubMessage message) { /* package */ void onMessageReceived(int sessionId, HubMessage message) { Loading Loading @@ -440,16 +458,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub return; return; } } if (mContextHubEndpointCallback != null) { boolean success = try { invokeCallback((consumer) -> consumer.onMessageReceived(sessionId, message)); mContextHubEndpointCallback.onMessageReceived(sessionId, message); if (!success) { } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling onMessageReceived", e); sendMessageDeliveryStatus( sendMessageDeliveryStatus( sessionId, message.getMessageSequenceNumber(), ErrorCode.TRANSIENT_ERROR); sessionId, message.getMessageSequenceNumber(), ErrorCode.TRANSIENT_ERROR); } } } } } /* package */ void onMessageDeliveryStatusReceived( /* package */ void onMessageDeliveryStatusReceived( int sessionId, int sequenceNumber, byte errorCode) { int sessionId, int sequenceNumber, byte errorCode) { Loading Loading @@ -520,4 +535,46 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub Collection<String> requiredPermissions = targetEndpointInfo.getRequiredPermissions(); Collection<String> requiredPermissions = targetEndpointInfo.getRequiredPermissions(); return ContextHubServiceUtil.hasPermissions(mContext, mPid, mUid, requiredPermissions); return ContextHubServiceUtil.hasPermissions(mContext, mPid, mUid, requiredPermissions); } } private void acquireWakeLock() { Binder.withCleanCallingIdentity( () -> { if (mIsRegistered.get()) { mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS); } }); } private void releaseWakeLock() { Binder.withCleanCallingIdentity( () -> { if (mWakeLock.isHeld()) { try { mWakeLock.release(); } catch (RuntimeException e) { Log.e(TAG, "Releasing the wakelock fails - ", e); } } }); } /** * Invokes a callback and acquires a wakelock. * * @param consumer The callback invoke * @return false if the callback threw a RemoteException */ private boolean invokeCallback(CallbackConsumer consumer) { if (mContextHubEndpointCallback != null) { acquireWakeLock(); try { consumer.accept(mContextHubEndpointCallback); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling endpoint callback", e); releaseWakeLock(); return false; } } return true; } } } Loading
core/java/android/hardware/contexthub/HubEndpoint.java +22 −1 Original line number Original line Diff line number Diff line Loading @@ -137,6 +137,8 @@ public class HubEndpoint { serviceDescriptor, serviceDescriptor, mLifecycleCallback.onSessionOpenRequest( mLifecycleCallback.onSessionOpenRequest( initiator, serviceDescriptor))); initiator, serviceDescriptor))); } else { invokeCallbackFinished(); } } } } Loading @@ -163,6 +165,8 @@ public class HubEndpoint { + result.getReason()); + result.getReason()); rejectSession(sessionId); rejectSession(sessionId); } } invokeCallbackFinished(); } } private void acceptSession( private void acceptSession( Loading Loading @@ -249,7 +253,12 @@ public class HubEndpoint { activeSession.setOpened(); activeSession.setOpened(); if (mLifecycleCallback != null) { if (mLifecycleCallback != null) { mLifecycleCallbackExecutor.execute( mLifecycleCallbackExecutor.execute( () -> mLifecycleCallback.onSessionOpened(activeSession)); () -> { mLifecycleCallback.onSessionOpened(activeSession); invokeCallbackFinished(); }); } else { invokeCallbackFinished(); } } } } Loading Loading @@ -278,7 +287,10 @@ public class HubEndpoint { synchronized (mLock) { synchronized (mLock) { mActiveSessions.remove(sessionId); mActiveSessions.remove(sessionId); } } invokeCallbackFinished(); }); }); } else { invokeCallbackFinished(); } } } } Loading Loading @@ -323,8 +335,17 @@ public class HubEndpoint { e.rethrowFromSystemServer(); e.rethrowFromSystemServer(); } } } } invokeCallbackFinished(); }); }); } } private void invokeCallbackFinished() { try { mServiceToken.onCallbackFinished(); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } }; }; /** Binder returned from system service, non-null while registered. */ /** Binder returned from system service, non-null while registered. */ Loading
core/java/android/hardware/contexthub/IContextHubEndpoint.aidl +6 −0 Original line number Original line Diff line number Diff line Loading @@ -94,4 +94,10 @@ interface IContextHubEndpoint { */ */ @EnforcePermission("ACCESS_CONTEXT_HUB") @EnforcePermission("ACCESS_CONTEXT_HUB") void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode); void sendMessageDeliveryStatus(int sessionId, int messageSeqNumber, byte errorCode); /** * Invoked when a callback from IContextHubEndpointCallback finishes. */ @EnforcePermission("ACCESS_CONTEXT_HUB") void onCallbackFinished(); } }
services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java +89 −32 Original line number Original line Diff line number Diff line Loading @@ -32,7 +32,10 @@ import android.hardware.location.ContextHubTransaction; import android.hardware.location.IContextHubTransactionCallback; import android.hardware.location.IContextHubTransactionCallback; import android.os.Binder; import android.os.Binder; import android.os.IBinder; import android.os.IBinder; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.RemoteException; import android.os.RemoteException; import android.os.WorkSource; import android.util.Log; import android.util.Log; import android.util.SparseArray; import android.util.SparseArray; Loading @@ -54,6 +57,16 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub /** Message used by noteOp when this client receives a message from an endpoint. */ /** Message used by noteOp when this client receives a message from an endpoint. */ private static final String RECEIVE_MSG_NOTE = "ContextHubEndpointMessageDelivery"; private static final String RECEIVE_MSG_NOTE = "ContextHubEndpointMessageDelivery"; /** The duration of wakelocks acquired during HAL callbacks */ private static final long WAKELOCK_TIMEOUT_MILLIS = 5 * 1000; /* * Internal interface used to invoke client callbacks. */ interface CallbackConsumer { void accept(IContextHubEndpointCallback callback) throws RemoteException; } /** The context of the service. */ /** The context of the service. */ private final Context mContext; private final Context mContext; Loading Loading @@ -134,6 +147,9 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub private final int mUid; private final int mUid; /** Wakelock held while nanoapp message are in flight to the client */ private final WakeLock mWakeLock; /* package */ ContextHubEndpointBroker( /* package */ ContextHubEndpointBroker( Context context, Context context, IEndpointCommunication hubInterface, IEndpointCommunication hubInterface, Loading @@ -158,6 +174,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub mAppOpsManager = context.getSystemService(AppOpsManager.class); mAppOpsManager = context.getSystemService(AppOpsManager.class); mAppOpsManager.startWatchingMode(AppOpsManager.OP_NONE, mPackageName, this); mAppOpsManager.startWatchingMode(AppOpsManager.OP_NONE, mPackageName, this); PowerManager powerManager = context.getSystemService(PowerManager.class); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.setWorkSource(new WorkSource(mUid, mPackageName)); mWakeLock.setReferenceCounted(true); } } @Override @Override Loading Loading @@ -302,6 +323,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub } } } } @Override @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void onCallbackFinished() { super.onCallbackFinished_enforcePermission(); releaseWakeLock(); } /** Invoked when the underlying binder of this broker has died at the client process. */ /** Invoked when the underlying binder of this broker has died at the client process. */ @Override @Override public void binderDied() { public void binderDied() { Loading Loading @@ -357,15 +385,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub mSessionInfoMap.put(sessionId, new SessionInfo(initiator, true)); mSessionInfoMap.put(sessionId, new SessionInfo(initiator, true)); } } if (mContextHubEndpointCallback != null) { boolean success = try { invokeCallback( mContextHubEndpointCallback.onSessionOpenRequest( (consumer) -> sessionId, initiator, serviceDescriptor); consumer.onSessionOpenRequest( } catch (RemoteException e) { sessionId, initiator, serviceDescriptor)); Log.e(TAG, "RemoteException while calling onSessionOpenRequest", e); if (!success) { cleanupSessionResources(sessionId); cleanupSessionResources(sessionId); return; } } } } } Loading @@ -374,14 +400,11 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub Log.w(TAG, "Unknown session ID in onCloseEndpointSession: id=" + sessionId); Log.w(TAG, "Unknown session ID in onCloseEndpointSession: id=" + sessionId); return; return; } } if (mContextHubEndpointCallback != null) { try { invokeCallback( mContextHubEndpointCallback.onSessionClosed( (consumer) -> sessionId, ContextHubServiceUtil.toAppHubEndpointReason(reason)); consumer.onSessionClosed( } catch (RemoteException e) { sessionId, ContextHubServiceUtil.toAppHubEndpointReason(reason))); Log.e(TAG, "RemoteException while calling onSessionClosed", e); } } } } /* package */ void onEndpointSessionOpenComplete(int sessionId) { /* package */ void onEndpointSessionOpenComplete(int sessionId) { Loading @@ -392,13 +415,8 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub } } mSessionInfoMap.get(sessionId).setSessionState(SessionInfo.SessionState.ACTIVE); mSessionInfoMap.get(sessionId).setSessionState(SessionInfo.SessionState.ACTIVE); } } if (mContextHubEndpointCallback != null) { try { invokeCallback((consumer) -> consumer.onSessionOpenComplete(sessionId)); mContextHubEndpointCallback.onSessionOpenComplete(sessionId); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling onSessionClosed", e); } } } } /* package */ void onMessageReceived(int sessionId, HubMessage message) { /* package */ void onMessageReceived(int sessionId, HubMessage message) { Loading Loading @@ -440,16 +458,13 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub return; return; } } if (mContextHubEndpointCallback != null) { boolean success = try { invokeCallback((consumer) -> consumer.onMessageReceived(sessionId, message)); mContextHubEndpointCallback.onMessageReceived(sessionId, message); if (!success) { } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling onMessageReceived", e); sendMessageDeliveryStatus( sendMessageDeliveryStatus( sessionId, message.getMessageSequenceNumber(), ErrorCode.TRANSIENT_ERROR); sessionId, message.getMessageSequenceNumber(), ErrorCode.TRANSIENT_ERROR); } } } } } /* package */ void onMessageDeliveryStatusReceived( /* package */ void onMessageDeliveryStatusReceived( int sessionId, int sequenceNumber, byte errorCode) { int sessionId, int sequenceNumber, byte errorCode) { Loading Loading @@ -520,4 +535,46 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub Collection<String> requiredPermissions = targetEndpointInfo.getRequiredPermissions(); Collection<String> requiredPermissions = targetEndpointInfo.getRequiredPermissions(); return ContextHubServiceUtil.hasPermissions(mContext, mPid, mUid, requiredPermissions); return ContextHubServiceUtil.hasPermissions(mContext, mPid, mUid, requiredPermissions); } } private void acquireWakeLock() { Binder.withCleanCallingIdentity( () -> { if (mIsRegistered.get()) { mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS); } }); } private void releaseWakeLock() { Binder.withCleanCallingIdentity( () -> { if (mWakeLock.isHeld()) { try { mWakeLock.release(); } catch (RuntimeException e) { Log.e(TAG, "Releasing the wakelock fails - ", e); } } }); } /** * Invokes a callback and acquires a wakelock. * * @param consumer The callback invoke * @return false if the callback threw a RemoteException */ private boolean invokeCallback(CallbackConsumer consumer) { if (mContextHubEndpointCallback != null) { acquireWakeLock(); try { consumer.accept(mContextHubEndpointCallback); } catch (RemoteException e) { Log.e(TAG, "RemoteException while calling endpoint callback", e); releaseWakeLock(); return false; } } return true; } } }