Merge "Injecting networkstack Quirk stats into statsd" am: 1206788018 am: f46020e884
Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/1316085
Change-Id: I95b42ff98c5ba31e60cdf91804921abfb1eeafe4
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 67512cc..efe1054 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -73,6 +73,7 @@
import android.os.ServiceSpecificException;
import android.os.SystemClock;
import android.stats.connectivity.DisconnectCode;
+import android.stats.connectivity.NetworkQuirkEvent;
import android.system.ErrnoException;
import android.system.Os;
import android.text.TextUtils;
@@ -98,6 +99,7 @@
import com.android.networkstack.apishim.common.ShimUtils;
import com.android.networkstack.arp.ArpPacket;
import com.android.networkstack.metrics.IpProvisioningMetrics;
+import com.android.networkstack.metrics.NetworkQuirkMetrics;
import com.android.networkstack.packets.NeighborAdvertisement;
import com.android.server.NetworkObserverRegistry;
import com.android.server.NetworkStackService.NetworkStackServiceManager;
@@ -155,6 +157,7 @@
private final NetworkStackIpMemoryStore mIpMemoryStore;
private final NetworkInformationShim mShim = NetworkInformationShimImpl.newInstance();
private final IpProvisioningMetrics mIpProvisioningMetrics = new IpProvisioningMetrics();
+ private final NetworkQuirkMetrics mNetworkQuirkMetrics;
/**
* Dump all state machine and connectivity packet logs to the specified writer.
@@ -588,6 +591,10 @@
return new IpConnectivityLog();
}
+ public NetworkQuirkMetrics getNetworkQuirkMetrics() {
+ return new NetworkQuirkMetrics();
+ }
+
/**
* Return whether a feature guarded by a feature flag is enabled.
* @see NetworkStackUtils#isFeatureEnabled(Context, String, String)
@@ -619,6 +626,7 @@
mClatInterfaceName = CLAT_PREFIX + ifName;
mDependencies = deps;
mMetricsLog = deps.getIpConnectivityLog();
+ mNetworkQuirkMetrics = deps.getNetworkQuirkMetrics();
mShutdownLatch = new CountDownLatch(1);
mCm = mContext.getSystemService(ConnectivityManager.class);
mObserverRegistry = observerRegistry;
@@ -1262,6 +1270,8 @@
// b/131781810.
if (newLp.isIpv4Provisioned()) {
mInterfaceCtrl.disableIPv6();
+ mNetworkQuirkMetrics.setEvent(NetworkQuirkEvent.QE_IPV6_PROVISIONING_ROUTER_LOST);
+ mNetworkQuirkMetrics.statsWrite();
mHasDisabledIPv6OnProvLoss = true;
delta = PROV_CHANGE_STILL_PROVISIONED;
mLog.log("Disable IPv6 stack completely when the default router has gone");
diff --git a/src/com/android/networkstack/metrics/NetworkQuirkMetrics.java b/src/com/android/networkstack/metrics/NetworkQuirkMetrics.java
new file mode 100644
index 0000000..dee4504
--- /dev/null
+++ b/src/com/android/networkstack/metrics/NetworkQuirkMetrics.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 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.networkstack.metrics;
+
+import android.stats.connectivity.NetworkQuirkEvent;
+
+import androidx.annotation.VisibleForTesting;
+
+/**
+ * Class to record the network Quirk event into statsd.
+ * @hide
+ */
+public class NetworkQuirkMetrics {
+ private final Dependencies mDependencies;
+ private final NetworkStackQuirkReported.Builder mStatsBuilder =
+ NetworkStackQuirkReported.newBuilder();
+ /**
+ * Dependencies of {@link NetworkQuirkMetrics}, useful for testing.
+ */
+ @VisibleForTesting
+ public static class Dependencies {
+ /**
+ * @see NetworkStackStatsLog#write.
+ */
+ public void writeStats(int event) {
+ NetworkStackStatsLog.write(NetworkStackStatsLog.NETWORK_STACK_QUIRK_REPORTED,
+ 0, event);
+ }
+ }
+
+ /**
+ * Get a NetworkQuirkMetrics instance.
+ */
+ public NetworkQuirkMetrics() {
+ this(new Dependencies());
+ }
+
+ @VisibleForTesting
+ public NetworkQuirkMetrics(Dependencies deps) {
+ mDependencies = deps;
+ }
+
+ /**
+ * Write the network Quirk Event into mStatsBuilder.
+ */
+ public void setEvent(NetworkQuirkEvent event) {
+ mStatsBuilder.setEvent(event);
+ }
+
+ /**
+ * Write the NetworkStackQuirkReported proto into statsd.
+ */
+ public NetworkStackQuirkReported statsWrite() {
+ final NetworkStackQuirkReported stats = mStatsBuilder.build();
+ mDependencies.writeStats(stats.getEvent().getNumber());
+ return stats;
+ }
+}
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
index e217e91..c5a8b89 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
@@ -128,6 +128,7 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.stats.connectivity.NetworkQuirkEvent;
import android.system.ErrnoException;
import android.system.Os;
@@ -147,6 +148,7 @@
import com.android.networkstack.apishim.common.ShimUtils;
import com.android.networkstack.arp.ArpPacket;
import com.android.networkstack.metrics.IpProvisioningMetrics;
+import com.android.networkstack.metrics.NetworkQuirkMetrics;
import com.android.networkstack.packets.NeighborAdvertisement;
import com.android.server.NetworkObserver;
import com.android.server.NetworkObserverRegistry;
@@ -260,6 +262,7 @@
@Mock private IpMemoryStoreService mIpMemoryStoreService;
@Mock private PowerManager.WakeLock mTimeoutWakeLock;
@Mock protected NetworkStackIpMemoryStore mIpMemoryStore;
+ @Mock private NetworkQuirkMetrics.Dependencies mNetworkQuirkMetricsDeps;
@Spy private INetd mNetd;
private NetworkObserverRegistry mNetworkObserverRegistry;
@@ -448,6 +451,11 @@
public void setDeviceConfigProperty(String name, int value) {
mIntConfigProperties.put(name, value);
}
+
+ @Override
+ public NetworkQuirkMetrics getNetworkQuirkMetrics() {
+ return new NetworkQuirkMetrics(mNetworkQuirkMetricsDeps);
+ }
}
@NonNull
@@ -2427,6 +2435,11 @@
assertNotNull(lp);
assertEquals(lp.getAddresses().get(0), CLIENT_ADDR);
assertEquals(lp.getDnsServers().get(0), SERVER_ADDR);
+
+ final ArgumentCaptor<Integer> quirkEvent = ArgumentCaptor.forClass(Integer.class);
+ verify(mNetworkQuirkMetricsDeps, timeout(TEST_TIMEOUT_MS)).writeStats(quirkEvent.capture());
+ assertEquals((long) quirkEvent.getValue(),
+ (long) NetworkQuirkEvent.QE_IPV6_PROVISIONING_ROUTER_LOST.ordinal());
}
@Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required")