Loading services/core/java/com/android/server/location/ContextHubClientBroker.java +45 −0 Original line number Diff line number Diff line Loading @@ -29,10 +29,12 @@ import android.hardware.location.ContextHubTransaction; import android.hardware.location.IContextHubClient; import android.hardware.location.IContextHubClientCallback; import android.hardware.location.NanoAppMessage; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; /** Loading Loading @@ -96,6 +98,16 @@ public class ContextHubClientBroker extends IContextHubClient.Stub */ private final PendingIntentRequest mPendingIntentRequest; /* * The host package associated with this client. */ private final String mPackage; /* * True if a PendingIntent has been cancelled. */ private AtomicBoolean mIsPendingIntentCancelled = new AtomicBoolean(false); /* * Helper class to manage registered PendingIntent requests from the client. */ Loading @@ -110,11 +122,14 @@ public class ContextHubClientBroker extends IContextHubClient.Stub */ private long mNanoAppId; private boolean mValid = false; PendingIntentRequest() {} PendingIntentRequest(PendingIntent pendingIntent, long nanoAppId) { mPendingIntent = pendingIntent; mNanoAppId = nanoAppId; mValid = true; } public long getNanoAppId() { Loading @@ -132,6 +147,10 @@ public class ContextHubClientBroker extends IContextHubClient.Stub public void clear() { mPendingIntent = null; } public boolean isValid() { return mValid; } } /* package */ ContextHubClientBroker( Loading @@ -145,6 +164,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub mHostEndPointId = hostEndPointId; mCallbackInterface = callback; mPendingIntentRequest = new PendingIntentRequest(); mPackage = mContext.getPackageManager().getNameForUid(Binder.getCallingUid()); } /* package */ ContextHubClientBroker( Loading @@ -157,6 +177,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub mAttachedContextHubInfo = contextHubInfo; mHostEndPointId = hostEndPointId; mPendingIntentRequest = new PendingIntentRequest(pendingIntent, nanoAppId); mPackage = pendingIntent.getCreatorPackage(); } /** Loading Loading @@ -312,6 +333,13 @@ public class ContextHubClientBroker extends IContextHubClient.Stub } } /** * @return true if the client is a PendingIntent client that has been cancelled. */ /* package */ boolean isPendingIntentCancelled() { return mIsPendingIntentCancelled.get(); } /** * Helper function to invoke a specified client callback, if the connection is open. * Loading Loading @@ -392,6 +420,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub Manifest.permission.LOCATION_HARDWARE /* requiredPermission */, null /* options */); } catch (PendingIntent.CanceledException e) { mIsPendingIntentCancelled.set(true); // The PendingIntent is no longer valid Log.w(TAG, "PendingIntent has been canceled, unregistering from client" + " (host endpoint ID " + mHostEndPointId + ")"); Loading Loading @@ -419,4 +448,20 @@ public class ContextHubClientBroker extends IContextHubClient.Stub mRegistered = false; } } @Override public String toString() { String out = "[ContextHubClient "; out += "endpointID: " + getHostEndPointId() + ", "; out += "contextHub: " + getAttachedContextHubId() + ", "; if (mPendingIntentRequest.isValid()) { out += "intentCreatorPackage: " + mPackage + ", "; out += "nanoAppId: 0x" + Long.toHexString(mPendingIntentRequest.getNanoAppId()); } else { out += "package: " + mPackage; } out += "]"; return out; } } services/core/java/com/android/server/location/ContextHubClientManager.java +106 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.location; import android.annotation.IntDef; import android.app.PendingIntent; import android.content.Context; import android.hardware.contexthub.V1_0.ContextHubMsg; Loading @@ -27,7 +28,12 @@ import android.hardware.location.NanoAppMessage; import android.os.RemoteException; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Calendar; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.function.Consumer; /** Loading Loading @@ -71,6 +77,79 @@ import java.util.function.Consumer; */ private int mNextHostEndPointId = 0; /* * The list of previous registration records. */ private static final int NUM_CLIENT_RECORDS = 20; private final ConcurrentLinkedEvictingDeque<RegistrationRecord> mRegistrationRecordDeque = new ConcurrentLinkedEvictingDeque<>(NUM_CLIENT_RECORDS); @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "ACTION_" }, value = { ACTION_REGISTERED, ACTION_UNREGISTERED, ACTION_CANCELLED, }) public @interface Action {} public static final int ACTION_REGISTERED = 0; public static final int ACTION_UNREGISTERED = 1; public static final int ACTION_CANCELLED = 2; /** * Helper class to make a ConcurrentLinkedDeque fixed-size, evicting old entries when full. */ private class ConcurrentLinkedEvictingDeque<E> extends ConcurrentLinkedDeque<E> { private int mSize; ConcurrentLinkedEvictingDeque(int size) { mSize = size; } @Override public boolean add(E elem) { synchronized (this) { if (size() == mSize) { poll(); } return super.add(elem); } } } /** * A container class to store a record of ContextHubClient registration. */ private class RegistrationRecord { private final String mBroker; private final int mAction; private final String mDate; RegistrationRecord(String broker, @Action int action) { mBroker = broker; mAction = action; Calendar instance = Calendar.getInstance(); mDate = String.format("%02d", instance.get(Calendar.MONTH) + 1) // Jan == 0 + "/" + String.format("%02d", instance.get(Calendar.DAY_OF_MONTH)) + " " + String.format("%02d", instance.get(Calendar.HOUR_OF_DAY)) + ":" + String.format("%02d", instance.get(Calendar.MINUTE)) + ":" + String.format("%02d", instance.get(Calendar.SECOND)) + "." + String.format("%03d", instance.get(Calendar.MILLISECOND)); } @Override public String toString() { String out = ""; out += mDate + " "; out += mAction == ACTION_REGISTERED ? "+ " : "- "; out += mBroker; if (mAction == ACTION_CANCELLED) { out += " (cancelled)"; } return out; } } /* package */ ContextHubClientManager( Context context, IContexthub contextHubProxy) { mContext = context; Loading @@ -96,6 +175,8 @@ import java.util.function.Consumer; mContext, mContextHubProxy, this /* clientManager */, contextHubInfo, hostEndPointId, clientCallback); mHostEndPointIdToClientMap.put(hostEndPointId, broker); mRegistrationRecordDeque.add( new RegistrationRecord(broker.toString(), ACTION_REGISTERED)); } try { Loading Loading @@ -136,6 +217,8 @@ import java.util.function.Consumer; hostEndPointId, pendingIntent, nanoAppId); mHostEndPointIdToClientMap.put(hostEndPointId, broker); registerString = "Registered"; mRegistrationRecordDeque.add( new RegistrationRecord(broker.toString(), ACTION_REGISTERED)); } } Loading Loading @@ -178,6 +261,13 @@ import java.util.function.Consumer; * @param hostEndPointId the host endpoint ID of the client that has died */ /* package */ void unregisterClient(short hostEndPointId) { ContextHubClientBroker broker = mHostEndPointIdToClientMap.get(hostEndPointId); if (broker != null) { @Action int action = broker.isPendingIntentCancelled() ? ACTION_CANCELLED : ACTION_UNREGISTERED; mRegistrationRecordDeque.add(new RegistrationRecord(broker.toString(), action)); } if (mHostEndPointIdToClientMap.remove(hostEndPointId) != null) { Log.d(TAG, "Unregistered client with host endpoint ID " + hostEndPointId); } else { Loading Loading @@ -285,4 +375,20 @@ import java.util.function.Consumer; return null; } @Override public String toString() { String out = ""; for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) { out += broker + "\n"; } out += "\nRegistration history:\n"; Iterator<RegistrationRecord> it = mRegistrationRecordDeque.descendingIterator(); while (it.hasNext()) { out += it.next() + "\n"; } return out; } } services/core/java/com/android/server/location/ContextHubService.java +4 −0 Original line number Diff line number Diff line Loading @@ -795,6 +795,10 @@ public class ContextHubService extends IContextHubService.Stub { // Dump nanoAppHash mNanoAppStateManager.foreachNanoAppInstanceInfo((info) -> pw.println(info)); pw.println(""); pw.println("=================== CLIENTS ===================="); pw.println(mClientManager); // dump eventLog } Loading Loading
services/core/java/com/android/server/location/ContextHubClientBroker.java +45 −0 Original line number Diff line number Diff line Loading @@ -29,10 +29,12 @@ import android.hardware.location.ContextHubTransaction; import android.hardware.location.IContextHubClient; import android.hardware.location.IContextHubClientCallback; import android.hardware.location.NanoAppMessage; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; /** Loading Loading @@ -96,6 +98,16 @@ public class ContextHubClientBroker extends IContextHubClient.Stub */ private final PendingIntentRequest mPendingIntentRequest; /* * The host package associated with this client. */ private final String mPackage; /* * True if a PendingIntent has been cancelled. */ private AtomicBoolean mIsPendingIntentCancelled = new AtomicBoolean(false); /* * Helper class to manage registered PendingIntent requests from the client. */ Loading @@ -110,11 +122,14 @@ public class ContextHubClientBroker extends IContextHubClient.Stub */ private long mNanoAppId; private boolean mValid = false; PendingIntentRequest() {} PendingIntentRequest(PendingIntent pendingIntent, long nanoAppId) { mPendingIntent = pendingIntent; mNanoAppId = nanoAppId; mValid = true; } public long getNanoAppId() { Loading @@ -132,6 +147,10 @@ public class ContextHubClientBroker extends IContextHubClient.Stub public void clear() { mPendingIntent = null; } public boolean isValid() { return mValid; } } /* package */ ContextHubClientBroker( Loading @@ -145,6 +164,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub mHostEndPointId = hostEndPointId; mCallbackInterface = callback; mPendingIntentRequest = new PendingIntentRequest(); mPackage = mContext.getPackageManager().getNameForUid(Binder.getCallingUid()); } /* package */ ContextHubClientBroker( Loading @@ -157,6 +177,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub mAttachedContextHubInfo = contextHubInfo; mHostEndPointId = hostEndPointId; mPendingIntentRequest = new PendingIntentRequest(pendingIntent, nanoAppId); mPackage = pendingIntent.getCreatorPackage(); } /** Loading Loading @@ -312,6 +333,13 @@ public class ContextHubClientBroker extends IContextHubClient.Stub } } /** * @return true if the client is a PendingIntent client that has been cancelled. */ /* package */ boolean isPendingIntentCancelled() { return mIsPendingIntentCancelled.get(); } /** * Helper function to invoke a specified client callback, if the connection is open. * Loading Loading @@ -392,6 +420,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub Manifest.permission.LOCATION_HARDWARE /* requiredPermission */, null /* options */); } catch (PendingIntent.CanceledException e) { mIsPendingIntentCancelled.set(true); // The PendingIntent is no longer valid Log.w(TAG, "PendingIntent has been canceled, unregistering from client" + " (host endpoint ID " + mHostEndPointId + ")"); Loading Loading @@ -419,4 +448,20 @@ public class ContextHubClientBroker extends IContextHubClient.Stub mRegistered = false; } } @Override public String toString() { String out = "[ContextHubClient "; out += "endpointID: " + getHostEndPointId() + ", "; out += "contextHub: " + getAttachedContextHubId() + ", "; if (mPendingIntentRequest.isValid()) { out += "intentCreatorPackage: " + mPackage + ", "; out += "nanoAppId: 0x" + Long.toHexString(mPendingIntentRequest.getNanoAppId()); } else { out += "package: " + mPackage; } out += "]"; return out; } }
services/core/java/com/android/server/location/ContextHubClientManager.java +106 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.location; import android.annotation.IntDef; import android.app.PendingIntent; import android.content.Context; import android.hardware.contexthub.V1_0.ContextHubMsg; Loading @@ -27,7 +28,12 @@ import android.hardware.location.NanoAppMessage; import android.os.RemoteException; import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Calendar; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.function.Consumer; /** Loading Loading @@ -71,6 +77,79 @@ import java.util.function.Consumer; */ private int mNextHostEndPointId = 0; /* * The list of previous registration records. */ private static final int NUM_CLIENT_RECORDS = 20; private final ConcurrentLinkedEvictingDeque<RegistrationRecord> mRegistrationRecordDeque = new ConcurrentLinkedEvictingDeque<>(NUM_CLIENT_RECORDS); @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "ACTION_" }, value = { ACTION_REGISTERED, ACTION_UNREGISTERED, ACTION_CANCELLED, }) public @interface Action {} public static final int ACTION_REGISTERED = 0; public static final int ACTION_UNREGISTERED = 1; public static final int ACTION_CANCELLED = 2; /** * Helper class to make a ConcurrentLinkedDeque fixed-size, evicting old entries when full. */ private class ConcurrentLinkedEvictingDeque<E> extends ConcurrentLinkedDeque<E> { private int mSize; ConcurrentLinkedEvictingDeque(int size) { mSize = size; } @Override public boolean add(E elem) { synchronized (this) { if (size() == mSize) { poll(); } return super.add(elem); } } } /** * A container class to store a record of ContextHubClient registration. */ private class RegistrationRecord { private final String mBroker; private final int mAction; private final String mDate; RegistrationRecord(String broker, @Action int action) { mBroker = broker; mAction = action; Calendar instance = Calendar.getInstance(); mDate = String.format("%02d", instance.get(Calendar.MONTH) + 1) // Jan == 0 + "/" + String.format("%02d", instance.get(Calendar.DAY_OF_MONTH)) + " " + String.format("%02d", instance.get(Calendar.HOUR_OF_DAY)) + ":" + String.format("%02d", instance.get(Calendar.MINUTE)) + ":" + String.format("%02d", instance.get(Calendar.SECOND)) + "." + String.format("%03d", instance.get(Calendar.MILLISECOND)); } @Override public String toString() { String out = ""; out += mDate + " "; out += mAction == ACTION_REGISTERED ? "+ " : "- "; out += mBroker; if (mAction == ACTION_CANCELLED) { out += " (cancelled)"; } return out; } } /* package */ ContextHubClientManager( Context context, IContexthub contextHubProxy) { mContext = context; Loading @@ -96,6 +175,8 @@ import java.util.function.Consumer; mContext, mContextHubProxy, this /* clientManager */, contextHubInfo, hostEndPointId, clientCallback); mHostEndPointIdToClientMap.put(hostEndPointId, broker); mRegistrationRecordDeque.add( new RegistrationRecord(broker.toString(), ACTION_REGISTERED)); } try { Loading Loading @@ -136,6 +217,8 @@ import java.util.function.Consumer; hostEndPointId, pendingIntent, nanoAppId); mHostEndPointIdToClientMap.put(hostEndPointId, broker); registerString = "Registered"; mRegistrationRecordDeque.add( new RegistrationRecord(broker.toString(), ACTION_REGISTERED)); } } Loading Loading @@ -178,6 +261,13 @@ import java.util.function.Consumer; * @param hostEndPointId the host endpoint ID of the client that has died */ /* package */ void unregisterClient(short hostEndPointId) { ContextHubClientBroker broker = mHostEndPointIdToClientMap.get(hostEndPointId); if (broker != null) { @Action int action = broker.isPendingIntentCancelled() ? ACTION_CANCELLED : ACTION_UNREGISTERED; mRegistrationRecordDeque.add(new RegistrationRecord(broker.toString(), action)); } if (mHostEndPointIdToClientMap.remove(hostEndPointId) != null) { Log.d(TAG, "Unregistered client with host endpoint ID " + hostEndPointId); } else { Loading Loading @@ -285,4 +375,20 @@ import java.util.function.Consumer; return null; } @Override public String toString() { String out = ""; for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) { out += broker + "\n"; } out += "\nRegistration history:\n"; Iterator<RegistrationRecord> it = mRegistrationRecordDeque.descendingIterator(); while (it.hasNext()) { out += it.next() + "\n"; } return out; } }
services/core/java/com/android/server/location/ContextHubService.java +4 −0 Original line number Diff line number Diff line Loading @@ -795,6 +795,10 @@ public class ContextHubService extends IContextHubService.Stub { // Dump nanoAppHash mNanoAppStateManager.foreachNanoAppInstanceInfo((info) -> pw.println(info)); pw.println(""); pw.println("=================== CLIENTS ===================="); pw.println(mClientManager); // dump eventLog } Loading