Adds client info in ContextHubService dump
Example: ... =================== CLIENTS ==================== [ContextHubClient endpointID: 0, contextHub: 0, package: android.uid.system:1000] [ContextHubClient endpointID: 1, contextHub: 0, package: com.google.oslo] [ContextHubClient endpointID: 2, contextHub: 0, package: com.google.oslo] [ContextHubClient endpointID: 3, contextHub: 0, package: com.google.oslo] [ContextHubClient endpointID: 4, contextHub: 0, package: com.google.oslo] [ContextHubClient endpointID: 5, contextHub: 0, package: com.google.oslo] [ContextHubClient endpointID: 6, contextHub: 0, package: com.google.oslo] [ContextHubClient endpointID: 7, contextHub: 0, package: android.uid.systemui:10124] [ContextHubClient endpointID: 8, contextHub: 0, intentCreatorPackage: com.google.android.apps.scone, nanoAppId: 0x476f6f676c001016] Registration history: 12/03 14:58:17.410 - [ContextHubClient endpointID: 9, contextHub: 0, package: com.google.uid.shared:10113] 12/03 14:58:17.403 + [ContextHubClient endpointID: 9, contextHub: 0, package: com.google.uid.shared:10113] 12/03 14:58:10.295 + [ContextHubClient endpointID: 8, contextHub: 0, intentCreatorPackage: com.google.android.apps.scone, nanoAppId: 0x476f6f676c001016] 12/03 14:58:05.501 + [ContextHubClient endpointID: 7, contextHub: 0, package: android.uid.systemui:10124] 12/03 14:58:05.379 + [ContextHubClient endpointID: 6, contextHub: 0, package: com.google.oslo] 12/03 14:58:05.375 + [ContextHubClient endpointID: 5, contextHub: 0, package: com.google.oslo] 12/03 14:58:05.371 + [ContextHubClient endpointID: 4, contextHub: 0, package: com.google.oslo] 12/03 14:58:05.367 + [ContextHubClient endpointID: 3, contextHub: 0, package: com.google.oslo] 12/03 14:58:05.365 + [ContextHubClient endpointID: 2, contextHub: 0, package: com.google.oslo] 12/03 14:58:05.362 + [ContextHubClient endpointID: 1, contextHub: 0, package: com.google.oslo] 12/03 14:58:04.257 + [ContextHubClient endpointID: 0, contextHub: 0, package: android.uid.system:1000] Bug: 121033022 Test: adb shell dumpsys contexthub Change-Id: I33f49c1e8a144ea2818add0e0b4c52d1f5454b65
This commit is contained in:
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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() {
|
||||
@@ -132,6 +147,10 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
|
||||
public void clear() {
|
||||
mPendingIntent = null;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return mValid;
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ ContextHubClientBroker(
|
||||
@@ -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(
|
||||
@@ -157,6 +177,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
|
||||
mAttachedContextHubInfo = contextHubInfo;
|
||||
mHostEndPointId = hostEndPointId;
|
||||
mPendingIntentRequest = new PendingIntentRequest(pendingIntent, nanoAppId);
|
||||
mPackage = pendingIntent.getCreatorPackage();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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.
|
||||
*
|
||||
@@ -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 + ")");
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -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;
|
||||
@@ -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 {
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user