Report registration metrics data
Collect information about registration successes, failures, and
unregistrations, then build metrics data from this information
and report it.
Bug: 287546772
Test: atest FrameworksNetTestCases NsdManagerTest
Change-Id: I6324279b479da2e61b7519d96df5ad24a432e54a
diff --git a/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java b/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
index 6c8e273..bcedbef 100644
--- a/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
+++ b/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
@@ -16,6 +16,14 @@
package com.android.metrics;
+import static com.android.metrics.NetworkNsdReported.Builder;
+
+import android.stats.connectivity.MdnsQueryResult;
+import android.stats.connectivity.NsdEventType;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.ConnectivityStatsLog;
+
/**
* Class to record the NetworkNsdReported into statsd. Each client should create this class to
* report its data.
@@ -25,11 +33,93 @@
private final boolean mIsLegacy;
// The client id.
private final int mClientId;
+ private final Dependencies mDependencies;
public NetworkNsdReportedMetrics(boolean isLegacy, int clientId) {
- mIsLegacy = isLegacy;
- mClientId = clientId;
+ this(isLegacy, clientId, new Dependencies());
}
- // TODO: Report metrics data.
+ @VisibleForTesting
+ NetworkNsdReportedMetrics(boolean isLegacy, int clientId, Dependencies dependencies) {
+ mIsLegacy = isLegacy;
+ mClientId = clientId;
+ mDependencies = dependencies;
+ }
+
+ /**
+ * Dependencies of NetworkNsdReportedMetrics, for injection in tests.
+ */
+ public static class Dependencies {
+
+ /**
+ * @see ConnectivityStatsLog
+ */
+ public void statsWrite(NetworkNsdReported event) {
+ ConnectivityStatsLog.write(ConnectivityStatsLog.NETWORK_NSD_REPORTED,
+ event.getIsLegacy(),
+ event.getClientId(),
+ event.getTransactionId(),
+ event.getIsKnownService(),
+ event.getType().getNumber(),
+ event.getEventDurationMillisec(),
+ event.getQueryResult().getNumber(),
+ event.getFoundServiceCount(),
+ event.getFoundCallbackCount(),
+ event.getLostCallbackCount(),
+ event.getRepliedRequestsCount());
+ }
+ }
+
+ private Builder makeReportedBuilder() {
+ final Builder builder = NetworkNsdReported.newBuilder();
+ builder.setIsLegacy(mIsLegacy);
+ builder.setClientId(mClientId);
+ return builder;
+ }
+
+ /**
+ * Report service registration succeeded metric data.
+ *
+ * @param transactionId The transaction id of service registration.
+ * @param durationMs The duration of service registration success.
+ */
+ public void reportServiceRegistrationSucceeded(int transactionId, long durationMs) {
+ final Builder builder = makeReportedBuilder();
+ builder.setTransactionId(transactionId);
+ builder.setType(NsdEventType.NET_REGISTER);
+ builder.setQueryResult(MdnsQueryResult.MQR_SERVICE_REGISTERED);
+ builder.setEventDurationMillisec(durationMs);
+ mDependencies.statsWrite(builder.build());
+ }
+
+ /**
+ * Report service registration failed metric data.
+ *
+ * @param transactionId The transaction id of service registration.
+ * @param durationMs The duration of service registration failed.
+ */
+ public void reportServiceRegistrationFailed(int transactionId, long durationMs) {
+ final Builder builder = makeReportedBuilder();
+ builder.setTransactionId(transactionId);
+ builder.setType(NsdEventType.NET_REGISTER);
+ builder.setQueryResult(MdnsQueryResult.MQR_SERVICE_REGISTRATION_FAILED);
+ builder.setEventDurationMillisec(durationMs);
+ mDependencies.statsWrite(builder.build());
+ }
+
+ /**
+ * Report service unregistration success metric data.
+ *
+ * @param transactionId The transaction id of service registration.
+ * @param durationMs The duration of service stayed registered.
+ */
+ public void reportServiceUnregistration(int transactionId, long durationMs) {
+ final Builder builder = makeReportedBuilder();
+ builder.setTransactionId(transactionId);
+ builder.setType(NsdEventType.NET_REGISTER);
+ builder.setQueryResult(MdnsQueryResult.MQR_SERVICE_UNREGISTERED);
+ builder.setEventDurationMillisec(durationMs);
+ // TODO: Report repliedRequestsCount
+ 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 95717c2..745c5bc 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -162,6 +162,7 @@
public static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
private static final long CLEANUP_DELAY_MS = 10000;
private static final int IFACE_IDX_ANY = 0;
+ private static final int NO_TRANSACTION = -1;
private static final SharedLog LOGGER = new SharedLog("serviceDiscovery");
private final Context mContext;
@@ -178,6 +179,8 @@
private final MdnsSocketProvider mMdnsSocketProvider;
@NonNull
private final MdnsAdvertiser mAdvertiser;
+ @NonNull
+ private final Clock mClock;
private final SharedLog mServiceLogs = LOGGER.forSubComponent(TAG);
// WARNING : Accessing these values in any thread is not safe, it must only be changed in the
// state machine thread. If change this outside state machine, it will need to introduce
@@ -530,8 +533,9 @@
try {
cb.asBinder().linkToDeath(arg.connector, 0);
final String tag = "Client" + arg.uid + "-" + mClientNumberId++;
- final NetworkNsdReportedMetrics metrics = new NetworkNsdReportedMetrics(
- !arg.useJavaBackend, (int) new Clock().elapsedRealtime());
+ final NetworkNsdReportedMetrics metrics =
+ mDeps.makeNetworkNsdReportedMetrics(
+ !arg.useJavaBackend, (int) mClock.elapsedRealtime());
cInfo = new ClientInfo(cb, arg.uid, arg.useJavaBackend,
mServiceLogs.forSubComponent(tag), metrics);
mClients.put(arg.connector, cInfo);
@@ -569,7 +573,7 @@
case NsdManager.REGISTER_SERVICE:
cInfo = getClientInfoForReply(msg);
if (cInfo != null) {
- cInfo.onRegisterServiceFailed(
+ cInfo.onRegisterServiceFailedImmediately(
clientRequestId, NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
@@ -651,8 +655,8 @@
private void storeLegacyRequestMap(int clientRequestId, int transactionId,
ClientInfo clientInfo, int what) {
- clientInfo.mClientRequests.put(
- clientRequestId, new LegacyClientRequest(transactionId, what));
+ clientInfo.mClientRequests.put(clientRequestId, new LegacyClientRequest(
+ transactionId, what, mClock, mClock.elapsedRealtime()));
mTransactionIdToClientInfoMap.put(transactionId, clientInfo);
// Remove the cleanup event because here comes a new request.
cancelStop();
@@ -660,8 +664,8 @@
private void storeAdvertiserRequestMap(int clientRequestId, int transactionId,
ClientInfo clientInfo, @Nullable Network requestedNetwork) {
- clientInfo.mClientRequests.put(clientRequestId,
- new AdvertiserClientRequest(transactionId, requestedNetwork));
+ clientInfo.mClientRequests.put(clientRequestId, new AdvertiserClientRequest(
+ transactionId, requestedNetwork, mClock, mClock.elapsedRealtime()));
mTransactionIdToClientInfoMap.put(transactionId, clientInfo);
updateMulticastLock();
}
@@ -684,8 +688,9 @@
private void storeDiscoveryManagerRequestMap(int clientRequestId, int transactionId,
MdnsListener listener, ClientInfo clientInfo,
@Nullable Network requestedNetwork) {
- clientInfo.mClientRequests.put(clientRequestId,
- new DiscoveryManagerRequest(transactionId, listener, requestedNetwork));
+ clientInfo.mClientRequests.put(clientRequestId, new DiscoveryManagerRequest(
+ transactionId, listener, requestedNetwork, mClock,
+ mClock.elapsedRealtime()));
mTransactionIdToClientInfoMap.put(transactionId, clientInfo);
updateMulticastLock();
}
@@ -838,7 +843,7 @@
}
if (requestLimitReached(clientInfo)) {
- clientInfo.onRegisterServiceFailed(
+ clientInfo.onRegisterServiceFailedImmediately(
clientRequestId, NsdManager.FAILURE_MAX_LIMIT);
break;
}
@@ -854,8 +859,8 @@
|| useAdvertiserForType(registerServiceType)) {
if (registerServiceType == null) {
Log.e(TAG, "Invalid service type: " + serviceType);
- clientInfo.onRegisterServiceFailed(clientRequestId,
- NsdManager.FAILURE_INTERNAL_ERROR);
+ clientInfo.onRegisterServiceFailedImmediately(
+ clientRequestId, NsdManager.FAILURE_INTERNAL_ERROR);
break;
}
serviceInfo.setServiceType(registerServiceType);
@@ -882,7 +887,7 @@
// Return success after mDns reports success
} else {
unregisterService(transactionId);
- clientInfo.onRegisterServiceFailed(
+ clientInfo.onRegisterServiceFailedImmediately(
clientRequestId, NsdManager.FAILURE_INTERNAL_ERROR);
}
@@ -914,10 +919,12 @@
// instead of looking at the flag value.
if (request instanceof AdvertiserClientRequest) {
mAdvertiser.removeService(transactionId);
- clientInfo.onUnregisterServiceSucceeded(clientRequestId);
+ clientInfo.onUnregisterServiceSucceeded(clientRequestId, transactionId,
+ request.calculateRequestDurationMs());
} else {
if (unregisterService(transactionId)) {
- clientInfo.onUnregisterServiceSucceeded(clientRequestId);
+ clientInfo.onUnregisterServiceSucceeded(clientRequestId,
+ transactionId, request.calculateRequestDurationMs());
} else {
clientInfo.onUnregisterServiceFailed(
clientRequestId, NsdManager.FAILURE_INTERNAL_ERROR);
@@ -1181,12 +1188,18 @@
final RegistrationInfo info = (RegistrationInfo) obj;
final String name = info.serviceName;
servInfo = new NsdServiceInfo(name, null /* serviceType */);
- clientInfo.onRegisterServiceSucceeded(clientRequestId, servInfo);
+ final ClientRequest request =
+ clientInfo.mClientRequests.get(clientRequestId);
+ clientInfo.onRegisterServiceSucceeded(clientRequestId, servInfo,
+ transactionId, request.calculateRequestDurationMs());
break;
}
case IMDnsEventListener.SERVICE_REGISTRATION_FAILED:
- clientInfo.onRegisterServiceFailed(
- clientRequestId, NsdManager.FAILURE_INTERNAL_ERROR);
+ final ClientRequest request =
+ clientInfo.mClientRequests.get(clientRequestId);
+ clientInfo.onRegisterServiceFailed(clientRequestId,
+ NsdManager.FAILURE_INTERNAL_ERROR, transactionId,
+ request.calculateRequestDurationMs());
break;
case IMDnsEventListener.SERVICE_RESOLVED: {
final ResolutionInfo info = (ResolutionInfo) obj;
@@ -1566,6 +1579,7 @@
handler.post(() -> mMdnsSocketClient.setCallback(mMdnsDiscoveryManager));
mAdvertiser = deps.makeMdnsAdvertiser(handler.getLooper(), mMdnsSocketProvider,
new AdvertiserCallback(), LOGGER.forSubComponent("MdnsAdvertiser"));
+ mClock = deps.makeClock();
}
/**
@@ -1655,6 +1669,21 @@
public int getCallingUid() {
return Binder.getCallingUid();
}
+
+ /**
+ * @see NetworkNsdReportedMetrics
+ */
+ public NetworkNsdReportedMetrics makeNetworkNsdReportedMetrics(
+ boolean isLegacy, int clientId) {
+ return new NetworkNsdReportedMetrics(isLegacy, clientId);
+ }
+
+ /**
+ * @see MdnsUtils.Clock
+ */
+ public Clock makeClock() {
+ return new Clock();
+ }
}
/**
@@ -1755,7 +1784,9 @@
// onRegisterServiceSucceeded only has the service name in its info. This aligns with
// historical behavior.
final NsdServiceInfo cbInfo = new NsdServiceInfo(registeredInfo.getServiceName(), null);
- clientInfo.onRegisterServiceSucceeded(clientRequestId, cbInfo);
+ final ClientRequest request = clientInfo.mClientRequests.get(clientRequestId);
+ clientInfo.onRegisterServiceSucceeded(
+ clientRequestId, cbInfo, transactionId, request.calculateRequestDurationMs());
}
@Override
@@ -1765,8 +1796,9 @@
final int clientRequestId = getClientRequestIdOrLog(clientInfo, transactionId);
if (clientRequestId < 0) return;
-
- clientInfo.onRegisterServiceFailed(clientRequestId, errorCode);
+ final ClientRequest request = clientInfo.mClientRequests.get(clientRequestId);
+ clientInfo.onRegisterServiceFailed(clientRequestId, errorCode, transactionId,
+ request.calculateRequestDurationMs());
}
private ClientInfo getClientInfoOrLog(int transactionId) {
@@ -2026,17 +2058,27 @@
private abstract static class ClientRequest {
private final int mTransactionId;
+ private final Clock mClock;
+ private final long mStartTimeMs;
- private ClientRequest(int transactionId) {
+ private ClientRequest(int transactionId, @NonNull Clock clock, long startTimeMs) {
mTransactionId = transactionId;
+ mClock = clock;
+ mStartTimeMs = startTimeMs;
+ }
+
+ public long calculateRequestDurationMs() {
+ final long stopTimeMs = mClock.elapsedRealtime();
+ return stopTimeMs - mStartTimeMs;
}
}
private static class LegacyClientRequest extends ClientRequest {
private final int mRequestCode;
- private LegacyClientRequest(int transactionId, int requestCode) {
- super(transactionId);
+ private LegacyClientRequest(int transactionId, int requestCode, @NonNull Clock clock,
+ long startTimeMs) {
+ super(transactionId, clock, startTimeMs);
mRequestCode = requestCode;
}
}
@@ -2045,8 +2087,9 @@
@Nullable
private final Network mRequestedNetwork;
- private JavaBackendClientRequest(int transactionId, @Nullable Network requestedNetwork) {
- super(transactionId);
+ private JavaBackendClientRequest(int transactionId, @Nullable Network requestedNetwork,
+ @NonNull Clock clock, long startTimeMs) {
+ super(transactionId, clock, startTimeMs);
mRequestedNetwork = requestedNetwork;
}
@@ -2057,8 +2100,9 @@
}
private static class AdvertiserClientRequest extends JavaBackendClientRequest {
- private AdvertiserClientRequest(int transactionId, @Nullable Network requestedNetwork) {
- super(transactionId, requestedNetwork);
+ private AdvertiserClientRequest(int transactionId, @Nullable Network requestedNetwork,
+ @NonNull Clock clock, long startTimeMs) {
+ super(transactionId, requestedNetwork, clock, startTimeMs);
}
}
@@ -2067,8 +2111,8 @@
private final MdnsListener mListener;
private DiscoveryManagerRequest(int transactionId, @NonNull MdnsListener listener,
- @Nullable Network requestedNetwork) {
- super(transactionId, requestedNetwork);
+ @Nullable Network requestedNetwork, @NonNull Clock clock, long startTimeMs) {
+ super(transactionId, requestedNetwork, clock, startTimeMs);
mListener = listener;
}
}
@@ -2161,6 +2205,8 @@
if (request instanceof AdvertiserClientRequest) {
mAdvertiser.removeService(transactionId);
+ mMetrics.reportServiceUnregistration(
+ transactionId, request.calculateRequestDurationMs());
continue;
}
@@ -2177,6 +2223,8 @@
break;
case NsdManager.REGISTER_SERVICE:
unregisterService(transactionId);
+ mMetrics.reportServiceUnregistration(
+ transactionId, request.calculateRequestDurationMs());
break;
default:
break;
@@ -2268,7 +2316,13 @@
}
}
- void onRegisterServiceFailed(int listenerKey, int error) {
+ void onRegisterServiceFailedImmediately(int listenerKey, int error) {
+ onRegisterServiceFailed(listenerKey, error, NO_TRANSACTION, 0 /* durationMs */);
+ }
+
+ void onRegisterServiceFailed(int listenerKey, int error, int transactionId,
+ long durationMs) {
+ mMetrics.reportServiceRegistrationFailed(transactionId, durationMs);
try {
mCb.onRegisterServiceFailed(listenerKey, error);
} catch (RemoteException e) {
@@ -2276,7 +2330,9 @@
}
}
- void onRegisterServiceSucceeded(int listenerKey, NsdServiceInfo info) {
+ void onRegisterServiceSucceeded(int listenerKey, NsdServiceInfo info, int transactionId,
+ long durationMs) {
+ mMetrics.reportServiceRegistrationSucceeded(transactionId, durationMs);
try {
mCb.onRegisterServiceSucceeded(listenerKey, info);
} catch (RemoteException e) {
@@ -2292,7 +2348,8 @@
}
}
- void onUnregisterServiceSucceeded(int listenerKey) {
+ void onUnregisterServiceSucceeded(int listenerKey, int transactionId, long durationMs) {
+ mMetrics.reportServiceUnregistration(transactionId, durationMs);
try {
mCb.onUnregisterServiceSucceeded(listenerKey);
} catch (RemoteException e) {
diff --git a/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt b/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt
new file mode 100644
index 0000000..961c422
--- /dev/null
+++ b/tests/unit/java/com/android/metrics/NetworkNsdReportedMetricsTest.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.metrics
+
+import android.os.Build
+import android.stats.connectivity.MdnsQueryResult
+import android.stats.connectivity.NsdEventType
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRunner
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+
+@RunWith(DevSdkIgnoreRunner::class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
+class NetworkNsdReportedMetricsTest {
+ private val deps = mock(NetworkNsdReportedMetrics.Dependencies::class.java)
+
+ @Test
+ fun testReportServiceRegistrationSucceeded() {
+ val clientId = 99
+ val transactionId = 100
+ val durationMs = 10L
+ val metrics = NetworkNsdReportedMetrics(true /* isLegacy */, clientId, deps)
+ metrics.reportServiceRegistrationSucceeded(transactionId, durationMs)
+
+ val eventCaptor = ArgumentCaptor.forClass(NetworkNsdReported::class.java)
+ verify(deps).statsWrite(eventCaptor.capture())
+ eventCaptor.value.let {
+ assertTrue(it.isLegacy)
+ assertEquals(clientId, it.clientId)
+ assertEquals(transactionId, it.transactionId)
+ assertEquals(NsdEventType.NET_REGISTER, it.type)
+ assertEquals(MdnsQueryResult.MQR_SERVICE_REGISTERED, it.queryResult)
+ assertEquals(durationMs, it.eventDurationMillisec)
+ }
+ }
+
+ @Test
+ fun testReportServiceRegistrationFailed() {
+ val clientId = 99
+ val transactionId = 100
+ val durationMs = 10L
+ val metrics = NetworkNsdReportedMetrics(false /* isLegacy */, clientId, deps)
+ metrics.reportServiceRegistrationFailed(transactionId, durationMs)
+
+ val eventCaptor = ArgumentCaptor.forClass(NetworkNsdReported::class.java)
+ verify(deps).statsWrite(eventCaptor.capture())
+ eventCaptor.value.let {
+ assertFalse(it.isLegacy)
+ assertEquals(clientId, it.clientId)
+ assertEquals(transactionId, it.transactionId)
+ assertEquals(NsdEventType.NET_REGISTER, it.type)
+ assertEquals(MdnsQueryResult.MQR_SERVICE_REGISTRATION_FAILED, it.queryResult)
+ assertEquals(durationMs, it.eventDurationMillisec)
+ }
+ }
+
+ @Test
+ fun testReportServiceUnregistration() {
+ val clientId = 99
+ val transactionId = 100
+ val durationMs = 10L
+ val metrics = NetworkNsdReportedMetrics(true /* isLegacy */, clientId, deps)
+ metrics.reportServiceUnregistration(transactionId, durationMs)
+
+ val eventCaptor = ArgumentCaptor.forClass(NetworkNsdReported::class.java)
+ verify(deps).statsWrite(eventCaptor.capture())
+ eventCaptor.value.let {
+ assertTrue(it.isLegacy)
+ assertEquals(clientId, it.clientId)
+ assertEquals(transactionId, it.transactionId)
+ assertEquals(NsdEventType.NET_REGISTER, it.type)
+ assertEquals(MdnsQueryResult.MQR_SERVICE_UNREGISTERED, it.queryResult)
+ assertEquals(durationMs, it.eventDurationMillisec)
+ }
+ }
+}
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index f51b28d..55384b3 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -43,7 +43,9 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.any;
@@ -95,6 +97,7 @@
import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
+import com.android.metrics.NetworkNsdReportedMetrics;
import com.android.server.NsdService.Dependencies;
import com.android.server.connectivity.mdns.MdnsAdvertiser;
import com.android.server.connectivity.mdns.MdnsDiscoveryManager;
@@ -104,6 +107,7 @@
import com.android.server.connectivity.mdns.MdnsServiceInfo;
import com.android.server.connectivity.mdns.MdnsSocketProvider;
import com.android.server.connectivity.mdns.MdnsSocketProvider.SocketRequestMonitor;
+import com.android.server.connectivity.mdns.util.MdnsUtils;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
import com.android.testutils.HandlerUtils;
@@ -138,6 +142,7 @@
static final int PROTOCOL = NsdManager.PROTOCOL_DNS_SD;
private static final long CLEANUP_DELAY_MS = 500;
private static final long TIMEOUT_MS = 500;
+ private static final long TEST_TIME_MS = 123L;
private static final String SERVICE_NAME = "a_name";
private static final String SERVICE_TYPE = "_test._tcp";
private static final String SERVICE_FULL_NAME = SERVICE_NAME + "." + SERVICE_TYPE;
@@ -164,6 +169,8 @@
@Mock WifiManager mWifiManager;
@Mock WifiManager.MulticastLock mMulticastLock;
@Mock ActivityManager mActivityManager;
+ @Mock NetworkNsdReportedMetrics mMetrics;
+ @Mock MdnsUtils.Clock mClock;
SocketRequestMonitor mSocketRequestMonitor;
OnUidImportanceListener mUidImportanceListener;
HandlerThread mThread;
@@ -210,6 +217,9 @@
doReturn(DEFAULT_RUNNING_APP_ACTIVE_IMPORTANCE_CUTOFF).when(mDeps).getDeviceConfigInt(
eq(NsdService.MDNS_CONFIG_RUNNING_APP_ACTIVE_IMPORTANCE_CUTOFF), anyInt());
doReturn(mAdvertiser).when(mDeps).makeMdnsAdvertiser(any(), any(), any(), any());
+ doReturn(mMetrics).when(mDeps).makeNetworkNsdReportedMetrics(anyBoolean(), anyInt());
+ doReturn(mClock).when(mDeps).makeClock();
+ doReturn(TEST_TIME_MS).when(mClock).elapsedRealtime();
mService = makeService();
final ArgumentCaptor<SocketRequestMonitor> cbMonitorCaptor =
ArgumentCaptor.forClass(SocketRequestMonitor.class);
@@ -512,14 +522,16 @@
eq(SERVICE_NAME), eq(SERVICE_TYPE), eq(PORT), any(), eq(IFACE_IDX_ANY));
// Register service successfully.
+ final int regId = regIdCaptor.getValue();
final RegistrationInfo registrationInfo = new RegistrationInfo(
- regIdCaptor.getValue(),
+ regId,
IMDnsEventListener.SERVICE_REGISTERED,
SERVICE_NAME,
SERVICE_TYPE,
PORT,
new byte[0] /* txtRecord */,
IFACE_IDX_ANY);
+ doReturn(TEST_TIME_MS + 10L).when(mClock).elapsedRealtime();
eventListener.onServiceRegistrationStatus(registrationInfo);
final ArgumentCaptor<NsdServiceInfo> registeredInfoCaptor =
@@ -528,19 +540,22 @@
.onServiceRegistered(registeredInfoCaptor.capture());
final NsdServiceInfo registeredInfo = registeredInfoCaptor.getValue();
assertEquals(SERVICE_NAME, registeredInfo.getServiceName());
+ verify(mMetrics).reportServiceRegistrationSucceeded(regId, 10L /* durationMs */);
// Fail to register service.
final RegistrationInfo registrationFailedInfo = new RegistrationInfo(
- regIdCaptor.getValue(),
+ regId,
IMDnsEventListener.SERVICE_REGISTRATION_FAILED,
null /* serviceName */,
null /* registrationType */,
0 /* port */,
new byte[0] /* txtRecord */,
IFACE_IDX_ANY);
+ doReturn(TEST_TIME_MS + 20L).when(mClock).elapsedRealtime();
eventListener.onServiceRegistrationStatus(registrationFailedInfo);
verify(regListener, timeout(TIMEOUT_MS))
.onRegistrationFailed(any(), eq(FAILURE_INTERNAL_ERROR));
+ verify(mMetrics).reportServiceRegistrationFailed(regId, 20L /* durationMs */);
}
@Test
@@ -1215,17 +1230,22 @@
// Verify onServiceRegistered callback
final MdnsAdvertiser.AdvertiserCallback cb = cbCaptor.getValue();
- cb.onRegisterServiceSucceeded(idCaptor.getValue(), regInfo);
+ final int regId = idCaptor.getValue();
+ doReturn(TEST_TIME_MS + 10L).when(mClock).elapsedRealtime();
+ cb.onRegisterServiceSucceeded(regId, regInfo);
verify(regListener, timeout(TIMEOUT_MS)).onServiceRegistered(argThat(info -> matches(info,
new NsdServiceInfo(regInfo.getServiceName(), null))));
+ verify(mMetrics).reportServiceRegistrationSucceeded(regId, 10L /* durationMs */);
+ doReturn(TEST_TIME_MS + 100L).when(mClock).elapsedRealtime();
client.unregisterService(regListener);
waitForIdle();
verify(mAdvertiser).removeService(idCaptor.getValue());
verify(regListener, timeout(TIMEOUT_MS)).onServiceUnregistered(
argThat(info -> matches(info, regInfo)));
verify(mSocketProvider, timeout(TIMEOUT_MS)).requestStopWhenInactive();
+ verify(mMetrics).reportServiceUnregistration(regId, 100L /* durationMs */);
}
@Test
@@ -1251,6 +1271,7 @@
verify(regListener, timeout(TIMEOUT_MS)).onRegistrationFailed(
argThat(info -> matches(info, regInfo)), eq(FAILURE_INTERNAL_ERROR));
+ verify(mMetrics).reportServiceRegistrationFailed(anyInt(), anyLong());
}
@Test
@@ -1280,10 +1301,13 @@
// Verify onServiceRegistered callback
final MdnsAdvertiser.AdvertiserCallback cb = cbCaptor.getValue();
- cb.onRegisterServiceSucceeded(idCaptor.getValue(), regInfo);
+ final int regId = idCaptor.getValue();
+ doReturn(TEST_TIME_MS + 10L).when(mClock).elapsedRealtime();
+ cb.onRegisterServiceSucceeded(regId, regInfo);
verify(regListener, timeout(TIMEOUT_MS)).onServiceRegistered(
argThat(info -> matches(info, new NsdServiceInfo(regInfo.getServiceName(), null))));
+ verify(mMetrics).reportServiceRegistrationSucceeded(regId, 10L /* durationMs */);
}
@Test