Add current clients to servicediscovery dumpsys
In addition to logs, add the list of current clients and their requests
to the servicediscovery dumpsys.
This is useful to know what is being queried at a given time, and to
monitor listener leaks (sometimes by apps).
Sample output:
Active clients:
mUid 1000, mResolvedService null, mIsLegacy false, mUseJavaBackend \
true, mClientRequests:
2: Advertiser: serviceFullName=OpenThread BorderRouter \
#850C._meshcop._udp, net=null \
{2, startTime 18721, foundServices 0, lostServices \
0, fromCache false, sentQueries 0}
mUid 10108, mResolvedService null, mIsLegacy false, mUseJavaBackend \
true, mClientRequests:
16: Discovery/DiscoveryListener: \
serviceType=_nmt227941123._tcp.local, net=null \
{17, startTime 298263, foundServices 3, lostServices \
3, fromCache false, sentQueries 18}
24: Advertiser: \
serviceFullName=NsdTest223067831._nmt295637688._tcp, net=122 \
{25, startTime 301849, foundServices 0, lostServices 0, \
fromCache false, sentQueries 0}
25: Discovery/DiscoveryListener: \
serviceType=_nmt295637688._tcp.local, net=122 \
{26, startTime 302663, foundServices 0, lostServices \
0, fromCache false, sentQueries 1}
Test: dumpsys servicediscovery
Change-Id: I19051911a2f47582c75a564e1eeb1825796656bf
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index 46c435f..8552eec 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -275,7 +275,7 @@
}
@VisibleForTesting
- static class MdnsListener implements MdnsServiceBrowserListener {
+ abstract static class MdnsListener implements MdnsServiceBrowserListener {
protected final int mClientRequestId;
protected final int mTransactionId;
@NonNull
@@ -321,6 +321,10 @@
@Override
public void onFailedToParseMdnsResponse(int receivedPacketNumber, int errorCode) { }
+
+ // Ensure toString gets overridden
+ @NonNull
+ public abstract String toString();
}
private class DiscoveryListener extends MdnsListener {
@@ -351,13 +355,21 @@
mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId,
DISCOVERY_QUERY_SENT_CALLBACK, new MdnsEvent(mClientRequestId));
}
+
+ @NonNull
+ @Override
+ public String toString() {
+ return String.format("DiscoveryListener: serviceType=%s", getListenedServiceType());
+ }
}
private class ResolutionListener extends MdnsListener {
+ private final String mServiceName;
ResolutionListener(int clientRequestId, int transactionId,
- @NonNull String listenServiceType) {
+ @NonNull String listenServiceType, @NonNull String serviceName) {
super(clientRequestId, transactionId, listenServiceType);
+ mServiceName = serviceName;
}
@Override
@@ -373,13 +385,22 @@
mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId,
DISCOVERY_QUERY_SENT_CALLBACK, new MdnsEvent(mClientRequestId));
}
+
+ @NonNull
+ @Override
+ public String toString() {
+ return String.format("ResolutionListener serviceName=%s, serviceType=%s",
+ mServiceName, getListenedServiceType());
+ }
}
private class ServiceInfoListener extends MdnsListener {
+ private final String mServiceName;
ServiceInfoListener(int clientRequestId, int transactionId,
- @NonNull String listenServiceType) {
+ @NonNull String listenServiceType, @NonNull String serviceName) {
super(clientRequestId, transactionId, listenServiceType);
+ this.mServiceName = serviceName;
}
@Override
@@ -410,6 +431,13 @@
mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId,
DISCOVERY_QUERY_SENT_CALLBACK, new MdnsEvent(mClientRequestId));
}
+
+ @NonNull
+ @Override
+ public String toString() {
+ return String.format("ServiceInfoListener serviceName=%s, serviceType=%s",
+ mServiceName, getListenedServiceType());
+ }
}
private class SocketRequestMonitor implements MdnsSocketProvider.SocketRequestMonitor {
@@ -656,9 +684,12 @@
}
private void storeAdvertiserRequestMap(int clientRequestId, int transactionId,
- ClientInfo clientInfo, @Nullable Network requestedNetwork) {
+ ClientInfo clientInfo, @NonNull NsdServiceInfo serviceInfo) {
+ final String serviceFullName =
+ serviceInfo.getServiceName() + "." + serviceInfo.getServiceType();
clientInfo.mClientRequests.put(clientRequestId, new AdvertiserClientRequest(
- transactionId, requestedNetwork, mClock.elapsedRealtime()));
+ transactionId, serviceInfo.getNetwork(), serviceFullName,
+ mClock.elapsedRealtime()));
mTransactionIdToClientInfoMap.put(transactionId, clientInfo);
updateMulticastLock();
}
@@ -1010,7 +1041,7 @@
mAdvertiser.addOrUpdateService(transactionId, serviceInfo,
mdnsAdvertisingOptions, clientInfo.mUid);
storeAdvertiserRequestMap(clientRequestId, transactionId, clientInfo,
- serviceInfo.getNetwork());
+ serviceInfo);
} else {
maybeStartDaemon();
transactionId = getUniqueId();
@@ -1104,7 +1135,7 @@
maybeStartMonitoringSockets();
final MdnsListener listener = new ResolutionListener(clientRequestId,
- transactionId, resolveServiceType);
+ transactionId, resolveServiceType, info.getServiceName());
final int ifaceIdx = info.getNetwork() != null
? 0 : info.getInterfaceIndex();
final MdnsSearchOptions options = MdnsSearchOptions.newBuilder()
@@ -1207,7 +1238,7 @@
maybeStartMonitoringSockets();
final MdnsListener listener = new ServiceInfoListener(clientRequestId,
- transactionId, resolveServiceType);
+ transactionId, resolveServiceType, info.getServiceName());
final int ifIndex = info.getNetwork() != null
? 0 : info.getInterfaceIndex();
final MdnsSearchOptions options = MdnsSearchOptions.newBuilder()
@@ -2551,6 +2582,17 @@
// Dump state machine logs
mNsdStateMachine.dump(fd, pw, args);
+ // Dump clients
+ pw.println();
+ pw.println("Active clients:");
+ pw.increaseIndent();
+ HandlerUtils.runWithScissorsForDump(mNsdStateMachine.getHandler(), () -> {
+ for (ClientInfo clientInfo : mClients.values()) {
+ pw.println(clientInfo.toString());
+ }
+ }, 10_000);
+ pw.decreaseIndent();
+
// Dump service and clients logs
pw.println();
pw.println("Logs:");
@@ -2623,6 +2665,21 @@
public int getSentQueryCount() {
return mSentQueryCount;
}
+
+ @NonNull
+ @Override
+ public String toString() {
+ return getRequestDescriptor() + " {" + mTransactionId
+ + ", startTime " + mStartTimeMs
+ + ", foundServices " + mFoundServiceCount
+ + ", lostServices " + mLostServiceCount
+ + ", fromCache " + mIsServiceFromCache
+ + ", sentQueries " + mSentQueryCount
+ + "}";
+ }
+
+ @NonNull
+ protected abstract String getRequestDescriptor();
}
private static class LegacyClientRequest extends ClientRequest {
@@ -2632,6 +2689,12 @@
super(transactionId, startTimeMs);
mRequestCode = requestCode;
}
+
+ @NonNull
+ @Override
+ protected String getRequestDescriptor() {
+ return "Legacy (" + mRequestCode + ")";
+ }
}
private abstract static class JavaBackendClientRequest extends ClientRequest {
@@ -2651,9 +2714,20 @@
}
private static class AdvertiserClientRequest extends JavaBackendClientRequest {
+ @NonNull
+ private final String mServiceFullName;
+
private AdvertiserClientRequest(int transactionId, @Nullable Network requestedNetwork,
- long startTimeMs) {
+ @NonNull String serviceFullName, long startTimeMs) {
super(transactionId, requestedNetwork, startTimeMs);
+ mServiceFullName = serviceFullName;
+ }
+
+ @NonNull
+ @Override
+ public String getRequestDescriptor() {
+ return String.format("Advertiser: serviceFullName=%s, net=%s",
+ mServiceFullName, getRequestedNetwork());
}
}
@@ -2666,6 +2740,12 @@
super(transactionId, requestedNetwork, startTimeMs);
mListener = listener;
}
+
+ @NonNull
+ @Override
+ public String getRequestDescriptor() {
+ return String.format("Discovery/%s, net=%s", mListener, getRequestedNetwork());
+ }
}
/* Information tracked per client */
@@ -2710,17 +2790,15 @@
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("mResolvedService ").append(mResolvedService).append("\n");
- sb.append("mIsLegacy ").append(mIsPreSClient).append("\n");
- sb.append("mUseJavaBackend ").append(mUseJavaBackend).append("\n");
- sb.append("mUid ").append(mUid).append("\n");
+ sb.append("mUid ").append(mUid).append(", ");
+ sb.append("mResolvedService ").append(mResolvedService).append(", ");
+ sb.append("mIsLegacy ").append(mIsPreSClient).append(", ");
+ sb.append("mUseJavaBackend ").append(mUseJavaBackend).append(", ");
+ sb.append("mClientRequests:\n");
for (int i = 0; i < mClientRequests.size(); i++) {
int clientRequestId = mClientRequests.keyAt(i);
- sb.append("clientRequestId ")
- .append(clientRequestId)
- .append(" transactionId ").append(mClientRequests.valueAt(i).mTransactionId)
- .append(" type ").append(
- mClientRequests.valueAt(i).getClass().getSimpleName())
+ sb.append(" ").append(clientRequestId)
+ .append(": ").append(mClientRequests.valueAt(i).toString())
.append("\n");
}
return sb.toString();