diff --git a/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java b/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java index 665c41cdf6..597c06ffed 100644 --- a/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java +++ b/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java @@ -160,9 +160,10 @@ public class NetworkNsdReportedMetrics { * @param foundCallbackCount The count of found service callbacks before stop discovery. * @param lostCallbackCount The count of lost service callbacks before stop discovery. * @param servicesCount The count of found services. + * @param sentQueryCount The count of sent queries before stop discovery. */ public void reportServiceDiscoveryStop(int transactionId, long durationMs, - int foundCallbackCount, int lostCallbackCount, int servicesCount) { + int foundCallbackCount, int lostCallbackCount, int servicesCount, int sentQueryCount) { final Builder builder = makeReportedBuilder(); builder.setTransactionId(transactionId); builder.setType(NsdEventType.NET_DISCOVER); @@ -171,6 +172,7 @@ public class NetworkNsdReportedMetrics { builder.setFoundCallbackCount(foundCallbackCount); builder.setLostCallbackCount(lostCallbackCount); builder.setFoundServiceCount(servicesCount); + builder.setSentQueryCount(sentQueryCount); mDependencies.statsWrite(builder.build()); } @@ -180,15 +182,17 @@ public class NetworkNsdReportedMetrics { * @param transactionId The transaction id of service resolution. * @param durationMs The duration of resolving services. * @param isServiceFromCache Whether the resolved service is from cache. + * @param sentQueryCount The count of sent queries during resolving. */ public void reportServiceResolved(int transactionId, long durationMs, - boolean isServiceFromCache) { + boolean isServiceFromCache, int sentQueryCount) { final Builder builder = makeReportedBuilder(); builder.setTransactionId(transactionId); builder.setType(NsdEventType.NET_RESOLVE); builder.setQueryResult(MdnsQueryResult.MQR_SERVICE_RESOLVED); builder.setEventDurationMillisec(durationMs); builder.setIsKnownService(isServiceFromCache); + builder.setSentQueryCount(sentQueryCount); mDependencies.statsWrite(builder.build()); } @@ -256,9 +260,11 @@ public class NetworkNsdReportedMetrics { * @param updateCallbackCount The count of service update callbacks during this registration. * @param lostCallbackCount The count of service lost callbacks during this registration. * @param isServiceFromCache Whether the resolved service is from cache. + * @param sentQueryCount The count of sent queries during this registration. */ public void reportServiceInfoCallbackUnregistered(int transactionId, long durationMs, - int updateCallbackCount, int lostCallbackCount, boolean isServiceFromCache) { + int updateCallbackCount, int lostCallbackCount, boolean isServiceFromCache, + int sentQueryCount) { final Builder builder = makeReportedBuilder(); builder.setTransactionId(transactionId); builder.setType(NsdEventType.NET_SERVICE_INFO_CALLBACK); @@ -267,6 +273,7 @@ public class NetworkNsdReportedMetrics { builder.setFoundCallbackCount(updateCallbackCount); builder.setLostCallbackCount(lostCallbackCount); builder.setIsKnownService(isServiceFromCache); + builder.setSentQueryCount(sentQueryCount); mDependencies.statsWrite(builder.build()); } } diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java index e189d69aca..ff1f02dff6 100644 --- a/service-t/src/com/android/server/NsdService.java +++ b/service-t/src/com/android/server/NsdService.java @@ -172,6 +172,8 @@ public class NsdService extends INsdManager.Stub { private static final int MAX_SERVICES_COUNT_METRIC_PER_CLIENT = 100; @VisibleForTesting static final int NO_TRANSACTION = -1; + private static final int NO_SENT_QUERY_COUNT = 0; + private static final int DISCOVERY_QUERY_SENT_CALLBACK = 1000; private static final SharedLog LOGGER = new SharedLog("serviceDiscovery"); private final Context mContext; @@ -288,7 +290,8 @@ public class NsdService extends INsdManager.Stub { public void onSearchFailedToStart() { } @Override - public void onDiscoveryQuerySent(@NonNull List subtypes, int transactionId) { } + public void onDiscoveryQuerySent(@NonNull List subtypes, + int sentQueryTransactionId) { } @Override public void onFailedToParseMdnsResponse(int receivedPacketNumber, int errorCode) { } @@ -315,6 +318,13 @@ public class NsdService extends INsdManager.Stub { NsdManager.SERVICE_LOST, new MdnsEvent(mClientRequestId, serviceInfo)); } + + @Override + public void onDiscoveryQuerySent(@NonNull List subtypes, + int sentQueryTransactionId) { + mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId, + DISCOVERY_QUERY_SENT_CALLBACK, new MdnsEvent(mClientRequestId)); + } } private class ResolutionListener extends MdnsListener { @@ -330,6 +340,13 @@ public class NsdService extends INsdManager.Stub { NsdManager.RESOLVE_SERVICE_SUCCEEDED, new MdnsEvent(mClientRequestId, serviceInfo, isServiceFromCache)); } + + @Override + public void onDiscoveryQuerySent(@NonNull List subtypes, + int sentQueryTransactionId) { + mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId, + DISCOVERY_QUERY_SENT_CALLBACK, new MdnsEvent(mClientRequestId)); + } } private class ServiceInfoListener extends MdnsListener { @@ -360,6 +377,13 @@ public class NsdService extends INsdManager.Stub { NsdManager.SERVICE_UPDATED_LOST, new MdnsEvent(mClientRequestId, serviceInfo)); } + + @Override + public void onDiscoveryQuerySent(@NonNull List subtypes, + int sentQueryTransactionId) { + mNsdStateMachine.sendMessage(MDNS_DISCOVERY_MANAGER_EVENT, mTransactionId, + DISCOVERY_QUERY_SENT_CALLBACK, new MdnsEvent(mClientRequestId)); + } } private class SocketRequestMonitor implements MdnsSocketProvider.SocketRequestMonitor { @@ -465,15 +489,19 @@ public class NsdService extends INsdManager.Stub { */ private static class MdnsEvent { final int mClientRequestId; - @NonNull + @Nullable final MdnsServiceInfo mMdnsServiceInfo; final boolean mIsServiceFromCache; - MdnsEvent(int clientRequestId, @NonNull MdnsServiceInfo mdnsServiceInfo) { + MdnsEvent(int clientRequestId) { + this(clientRequestId, null /* mdnsServiceInfo */, false /* isServiceFromCache */); + } + + MdnsEvent(int clientRequestId, @Nullable MdnsServiceInfo mdnsServiceInfo) { this(clientRequestId, mdnsServiceInfo, false /* isServiceFromCache */); } - MdnsEvent(int clientRequestId, @NonNull MdnsServiceInfo mdnsServiceInfo, + MdnsEvent(int clientRequestId, @Nullable MdnsServiceInfo mdnsServiceInfo, boolean isServiceFromCache) { mClientRequestId = clientRequestId; mMdnsServiceInfo = mdnsServiceInfo; @@ -1411,17 +1439,25 @@ public class NsdService extends INsdManager.Stub { final MdnsEvent event = (MdnsEvent) obj; final int clientRequestId = event.mClientRequestId; + final ClientRequest request = clientInfo.mClientRequests.get(clientRequestId); + if (request == null) { + Log.e(TAG, "Unknown client request. clientRequestId=" + clientRequestId); + return false; + } + + // Deal with the discovery sent callback + if (code == DISCOVERY_QUERY_SENT_CALLBACK) { + request.onQuerySent(); + return true; + } + + // Deal with other callbacks. final NsdServiceInfo info = buildNsdServiceInfoFromMdnsEvent(event, code); // Errors are already logged if null if (info == null) return false; mServiceLogs.log(String.format( "MdnsDiscoveryManager event code=%s transactionId=%d", NsdManager.nameOf(code), transactionId)); - final ClientRequest request = clientInfo.mClientRequests.get(clientRequestId); - if (request == null) { - Log.e(TAG, "Unknown client request. clientRequestId=" + clientRequestId); - return false; - } switch (code) { case NsdManager.SERVICE_FOUND: clientInfo.onServiceFound(clientRequestId, info, request); @@ -2225,6 +2261,7 @@ public class NsdService extends INsdManager.Stub { private int mLostServiceCount = 0; private final Set mServices = new ArraySet<>(); private boolean mIsServiceFromCache = false; + private int mSentQueryCount = NO_SENT_QUERY_COUNT; private ClientRequest(int transactionId, long startTimeMs) { mTransactionId = transactionId; @@ -2265,6 +2302,14 @@ public class NsdService extends INsdManager.Stub { public boolean isServiceFromCache() { return mIsServiceFromCache; } + + public void onQuerySent() { + mSentQueryCount++; + } + + public int getSentQueryCount() { + return mSentQueryCount; + } } private static class LegacyClientRequest extends ClientRequest { @@ -2399,7 +2444,8 @@ public class NsdService extends INsdManager.Stub { request.calculateRequestDurationMs(mClock.elapsedRealtime()), request.getFoundServiceCount(), request.getLostServiceCount(), - request.getServicesCount()); + request.getServicesCount(), + request.getSentQueryCount()); } else if (listener instanceof ResolutionListener) { mMetrics.reportServiceResolutionStop(transactionId, request.calculateRequestDurationMs(mClock.elapsedRealtime())); @@ -2408,7 +2454,8 @@ public class NsdService extends INsdManager.Stub { request.calculateRequestDurationMs(mClock.elapsedRealtime()), request.getFoundServiceCount(), request.getLostServiceCount(), - request.isServiceFromCache()); + request.isServiceFromCache(), + request.getSentQueryCount()); } continue; } @@ -2431,7 +2478,8 @@ public class NsdService extends INsdManager.Stub { request.calculateRequestDurationMs(mClock.elapsedRealtime()), request.getFoundServiceCount(), request.getLostServiceCount(), - request.getServicesCount()); + request.getServicesCount(), + NO_SENT_QUERY_COUNT); break; case NsdManager.RESOLVE_SERVICE: stopResolveService(transactionId); @@ -2539,7 +2587,8 @@ public class NsdService extends INsdManager.Stub { request.calculateRequestDurationMs(mClock.elapsedRealtime()), request.getFoundServiceCount(), request.getLostServiceCount(), - request.getServicesCount()); + request.getServicesCount(), + request.getSentQueryCount()); try { mCb.onStopDiscoverySucceeded(listenerKey); } catch (RemoteException e) { @@ -2607,7 +2656,8 @@ public class NsdService extends INsdManager.Stub { mMetrics.reportServiceResolved( request.mTransactionId, request.calculateRequestDurationMs(mClock.elapsedRealtime()), - request.isServiceFromCache()); + request.isServiceFromCache(), + request.getSentQueryCount()); try { mCb.onResolveServiceSucceeded(listenerKey, info); } catch (RemoteException e) { @@ -2671,7 +2721,8 @@ public class NsdService extends INsdManager.Stub { request.calculateRequestDurationMs(mClock.elapsedRealtime()), request.getFoundServiceCount(), request.getLostServiceCount(), - request.isServiceFromCache()); + request.isServiceFromCache(), + request.getSentQueryCount()); try { mCb.onServiceInfoCallbackUnregistered(listenerKey); } catch (RemoteException e) { diff --git a/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt b/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt index 740aa883a2..7f893df2c7 100644 --- a/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt +++ b/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt @@ -141,9 +141,10 @@ class NetworkNsdReportedMetricsTest { val foundCallbackCount = 100 val lostCallbackCount = 49 val servicesCount = 75 + val sentQueryCount = 150 val metrics = NetworkNsdReportedMetrics(true /* isLegacy */, clientId, deps) - metrics.reportServiceDiscoveryStop( - transactionId, durationMs, foundCallbackCount, lostCallbackCount, servicesCount) + metrics.reportServiceDiscoveryStop(transactionId, durationMs, foundCallbackCount, + lostCallbackCount, servicesCount, sentQueryCount) val eventCaptor = ArgumentCaptor.forClass(NetworkNsdReported::class.java) verify(deps).statsWrite(eventCaptor.capture()) @@ -158,6 +159,7 @@ class NetworkNsdReportedMetricsTest { assertEquals(lostCallbackCount, it.lostCallbackCount) assertEquals(servicesCount, it.foundServiceCount) assertEquals(durationMs, it.eventDurationMillisec) + assertEquals(sentQueryCount, it.sentQueryCount) } } @@ -166,8 +168,10 @@ class NetworkNsdReportedMetricsTest { val clientId = 99 val transactionId = 100 val durationMs = 10L + val sentQueryCount = 0 val metrics = NetworkNsdReportedMetrics(true /* isLegacy */, clientId, deps) - metrics.reportServiceResolved(transactionId, durationMs, true /* isServiceFromCache */) + metrics.reportServiceResolved(transactionId, durationMs, true /* isServiceFromCache */, + sentQueryCount) val eventCaptor = ArgumentCaptor.forClass(NetworkNsdReported::class.java) verify(deps).statsWrite(eventCaptor.capture()) @@ -179,6 +183,7 @@ class NetworkNsdReportedMetricsTest { assertEquals(MdnsQueryResult.MQR_SERVICE_RESOLVED, it.queryResult) assertTrue(it.isKnownService) assertEquals(durationMs, it.eventDurationMillisec) + assertEquals(sentQueryCount, it.sentQueryCount) } } @@ -266,9 +271,11 @@ class NetworkNsdReportedMetricsTest { val durationMs = 10L val updateCallbackCount = 100 val lostCallbackCount = 10 + val sentQueryCount = 150 val metrics = NetworkNsdReportedMetrics(false /* isLegacy */, clientId, deps) metrics.reportServiceInfoCallbackUnregistered(transactionId, durationMs, - updateCallbackCount, lostCallbackCount, false /* isServiceFromCache */) + updateCallbackCount, lostCallbackCount, false /* isServiceFromCache */, + sentQueryCount) val eventCaptor = ArgumentCaptor.forClass(NetworkNsdReported::class.java) verify(deps).statsWrite(eventCaptor.capture()) @@ -282,6 +289,7 @@ class NetworkNsdReportedMetricsTest { assertEquals(updateCallbackCount, it.foundCallbackCount) assertEquals(lostCallbackCount, it.lostCallbackCount) assertFalse(it.isKnownService) + assertEquals(sentQueryCount, it.sentQueryCount) } } } diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java index ffc7904cbf..7a6424eeb9 100644 --- a/tests/unit/java/com/android/server/NsdServiceTest.java +++ b/tests/unit/java/com/android/server/NsdServiceTest.java @@ -472,8 +472,8 @@ public class NsdServiceTest { final ArgumentCaptor resInfoCaptor = ArgumentCaptor.forClass(NsdServiceInfo.class); verify(resolveListener, timeout(TIMEOUT_MS)).onServiceResolved(resInfoCaptor.capture()); - verify(mMetrics).reportServiceResolved( - getAddrId, 10L /* durationMs */, false /* isServiceFromCache */); + verify(mMetrics).reportServiceResolved(getAddrId, 10L /* durationMs */, + false /* isServiceFromCache */, 0 /* sentQueryCount */); final NsdServiceInfo resolvedService = resInfoCaptor.getValue(); assertEquals(SERVICE_NAME, resolvedService.getServiceName()); @@ -896,7 +896,7 @@ public class NsdServiceTest { verify(serviceInfoCallback, timeout(TIMEOUT_MS)).onServiceInfoCallbackUnregistered(); verify(mMetrics).reportServiceInfoCallbackUnregistered(servInfoId, 10L /* durationMs */, 3 /* updateCallbackCount */, 1 /* lostCallbackCount */, - true /* isServiceFromCache */); + true /* isServiceFromCache */, 1 /* sentQueryCount */); } @Test @@ -989,6 +989,11 @@ public class NsdServiceTest { final int discId = listener.mTransactionId; verify(mMetrics).reportServiceDiscoveryStarted(discId); + // Callbacks for query sent. + listener.onDiscoveryQuerySent(Collections.emptyList(), 1 /* transactionId */); + listener.onDiscoveryQuerySent(Collections.emptyList(), 2 /* transactionId */); + listener.onDiscoveryQuerySent(Collections.emptyList(), 3 /* transactionId */); + final MdnsServiceInfo foundInfo = new MdnsServiceInfo( SERVICE_NAME, /* serviceInstanceName */ serviceTypeWithLocalDomain.split("\\."), /* serviceType */ @@ -1037,7 +1042,8 @@ public class NsdServiceTest { verify(discListener, timeout(TIMEOUT_MS)).onDiscoveryStopped(SERVICE_TYPE); verify(mSocketProvider, timeout(CLEANUP_DELAY_MS + TIMEOUT_MS)).requestStopWhenInactive(); verify(mMetrics).reportServiceDiscoveryStop(discId, 10L /* durationMs */, - 1 /* foundCallbackCount */, 1 /* lostCallbackCount */, 1 /* servicesCount */); + 1 /* foundCallbackCount */, 1 /* lostCallbackCount */, 1 /* servicesCount */, + 3 /* sentQueryCount */); } @Test @@ -1149,8 +1155,8 @@ public class NsdServiceTest { final ArgumentCaptor infoCaptor = ArgumentCaptor.forClass(NsdServiceInfo.class); verify(resolveListener, timeout(TIMEOUT_MS)).onServiceResolved(infoCaptor.capture()); - verify(mMetrics).reportServiceResolved( - listener.mTransactionId, 10 /* durationMs */, true /* isServiceFromCache */); + verify(mMetrics).reportServiceResolved(listener.mTransactionId, 10 /* durationMs */, + true /* isServiceFromCache */, 0 /* sendQueryCount */); final NsdServiceInfo info = infoCaptor.getValue(); assertEquals(SERVICE_NAME, info.getServiceName());