Merge changes I59b6e04f,I55694d89

* changes:
  Remove Parcelable interface from DefaultNetworkEvent
  Extract logging of default network events
This commit is contained in:
Hugo Benichi
2017-10-26 06:01:06 +00:00
committed by Gerrit Code Review
8 changed files with 386 additions and 137 deletions

View File

@@ -16,73 +16,43 @@
package android.net.metrics;
import static android.net.ConnectivityManager.NETID_UNSET;
import android.net.NetworkCapabilities;
import android.os.Parcel;
import android.os.Parcelable;
/**
* An event recorded by ConnectivityService when there is a change in the default network.
* {@hide}
*/
public final class DefaultNetworkEvent implements Parcelable {
public class DefaultNetworkEvent {
// The ID of the network that has become the new default or NETID_UNSET if none.
public final int netId;
public int netId = NETID_UNSET;
// The list of transport types of the new default network, for example TRANSPORT_WIFI, as
// defined in NetworkCapabilities.java.
public final int[] transportTypes;
public int[] transportTypes = new int[0];
// The ID of the network that was the default before or NETID_UNSET if none.
public final int prevNetId;
public int prevNetId = NETID_UNSET;
// Whether the previous network had IPv4/IPv6 connectivity.
public final boolean prevIPv4;
public final boolean prevIPv6;
public DefaultNetworkEvent(int netId, int[] transportTypes,
int prevNetId, boolean prevIPv4, boolean prevIPv6) {
this.netId = netId;
this.transportTypes = transportTypes;
this.prevNetId = prevNetId;
this.prevIPv4 = prevIPv4;
this.prevIPv6 = prevIPv6;
}
private DefaultNetworkEvent(Parcel in) {
this.netId = in.readInt();
this.transportTypes = in.createIntArray();
this.prevNetId = in.readInt();
this.prevIPv4 = (in.readByte() > 0);
this.prevIPv6 = (in.readByte() > 0);
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(netId);
out.writeIntArray(transportTypes);
out.writeInt(prevNetId);
out.writeByte(prevIPv4 ? (byte) 1 : (byte) 0);
out.writeByte(prevIPv6 ? (byte) 1 : (byte) 0);
}
@Override
public int describeContents() {
return 0;
}
public boolean prevIPv4;
public boolean prevIPv6;
@Override
public String toString() {
String prevNetwork = String.valueOf(prevNetId);
String newNetwork = String.valueOf(netId);
if (prevNetId != 0) {
prevNetwork += ":" + ipSupport();
}
if (netId != 0) {
newNetwork += ":" + NetworkCapabilities.transportNamesOf(transportTypes);
}
return String.format("DefaultNetworkEvent(%s -> %s)", prevNetwork, newNetwork);
String prevNetwork = String.valueOf(prevNetId);
String newNetwork = String.valueOf(netId);
if (prevNetId != 0) {
prevNetwork += ":" + ipSupport();
}
if (netId != 0) {
newNetwork += ":" + NetworkCapabilities.transportNamesOf(transportTypes);
}
return String.format("DefaultNetworkEvent(%s -> %s)", prevNetwork, newNetwork);
}
private String ipSupport() {
if (prevIPv4 && prevIPv6) {
return "DUAL";
return "IPv4v6";
}
if (prevIPv6) {
return "IPv6";
@@ -92,15 +62,4 @@ public final class DefaultNetworkEvent implements Parcelable {
}
return "NONE";
}
public static final Parcelable.Creator<DefaultNetworkEvent> CREATOR
= new Parcelable.Creator<DefaultNetworkEvent>() {
public DefaultNetworkEvent createFromParcel(Parcel in) {
return new DefaultNetworkEvent(in);
}
public DefaultNetworkEvent[] newArray(int size) {
return new DefaultNetworkEvent[size];
}
};
}

View File

@@ -71,7 +71,6 @@ import android.net.ProxyInfo;
import android.net.RouteInfo;
import android.net.UidRange;
import android.net.Uri;
import android.net.metrics.DefaultNetworkEvent;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.util.MultinetworkPolicyTracker;
@@ -129,6 +128,7 @@ import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.DataConnectionStats;
import com.android.server.connectivity.IpConnectivityMetrics;
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.LingerMonitor;
import com.android.server.connectivity.MockableSystemProperties;
@@ -2283,7 +2283,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Let rematchAllNetworksAndRequests() below record a new default network event
// if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
// whose timestamps tell how long it takes to recover a default network.
logDefaultNetworkEvent(null, nai);
metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(null, nai);
}
notifyIfacesChangedForNetworkStats();
// TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
@@ -5012,7 +5012,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Notify system services that this network is up.
makeDefault(newNetwork);
// Log 0 -> X and Y -> X default network transitions, where X is the new default.
logDefaultNetworkEvent(newNetwork, oldDefaultNetwork);
metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(
newNetwork, oldDefaultNetwork);
// Have a new default network, release the transition wakelock in
scheduleReleaseNetworkTransitionWakelock();
}
@@ -5571,25 +5572,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
return ServiceManager.checkService(name) != null;
}
private void logDefaultNetworkEvent(NetworkAgentInfo newNai, NetworkAgentInfo prevNai) {
int newNetid = NETID_UNSET;
int prevNetid = NETID_UNSET;
int[] transports = new int[0];
boolean hadIPv4 = false;
boolean hadIPv6 = false;
if (newNai != null) {
newNetid = newNai.network.netId;
transports = newNai.networkCapabilities.getTransportTypes();
}
if (prevNai != null) {
prevNetid = prevNai.network.netId;
final LinkProperties lp = prevNai.linkProperties;
hadIPv4 = lp.hasIPv4Address() && lp.hasIPv4DefaultRoute();
hadIPv6 = lp.hasGlobalIPv6Address() && lp.hasIPv6DefaultRoute();
}
mMetricsLog.log(new DefaultNetworkEvent(newNetid, transports, prevNetid, hadIPv4, hadIPv6));
@VisibleForTesting
protected IpConnectivityMetrics.Logger metricsLogger() {
return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
"no IpConnectivityMetrics service");
}
private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2017 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.server.connectivity;
import android.net.LinkProperties;
import android.net.metrics.DefaultNetworkEvent;
import android.net.metrics.IpConnectivityLog;
import com.android.internal.annotations.GuardedBy;
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
/**
* Tracks events related to the default network for the purpose of default network metrics.
* {@hide}
*/
public class DefaultNetworkMetrics {
private static final int ROLLING_LOG_SIZE = 64;
// Event buffer used for metrics upload. The buffer is cleared when events are collected.
@GuardedBy("this")
private final List<DefaultNetworkEvent> mEvents = new ArrayList<>();
public synchronized void listEvents(PrintWriter pw) {
long localTimeMs = System.currentTimeMillis();
for (DefaultNetworkEvent ev : mEvents) {
pw.println(ev);
}
}
public synchronized void listEventsAsProto(PrintWriter pw) {
for (DefaultNetworkEvent ev : mEvents) {
pw.print(IpConnectivityEventBuilder.toProto(ev));
}
}
public synchronized void flushEvents(List<IpConnectivityEvent> out) {
for (DefaultNetworkEvent ev : mEvents) {
out.add(IpConnectivityEventBuilder.toProto(ev));
}
mEvents.clear();
}
public synchronized void logDefaultNetworkEvent(
NetworkAgentInfo newNai, NetworkAgentInfo prevNai) {
DefaultNetworkEvent ev = new DefaultNetworkEvent();
if (newNai != null) {
ev.netId = newNai.network().netId;
ev.transportTypes = newNai.networkCapabilities.getTransportTypes();
}
if (prevNai != null) {
ev.prevNetId = prevNai.network().netId;
final LinkProperties lp = prevNai.linkProperties;
ev.prevIPv4 = lp.hasIPv4Address() && lp.hasIPv4DefaultRoute();
ev.prevIPv6 = lp.hasGlobalIPv6Address() && lp.hasIPv6DefaultRoute();
}
mEvents.add(ev);
}
}

View File

@@ -132,6 +132,18 @@ final public class IpConnectivityEventBuilder {
return out;
}
public static IpConnectivityEvent toProto(DefaultNetworkEvent in) {
IpConnectivityLogClass.DefaultNetworkEvent ev =
new IpConnectivityLogClass.DefaultNetworkEvent();
ev.networkId = netIdOf(in.netId);
ev.previousNetworkId = netIdOf(in.prevNetId);
ev.transportTypes = in.transportTypes;
ev.previousNetworkIpSupport = ipSupportOf(in);
final IpConnectivityEvent out = buildEvent(in.netId, 0, null);
out.setDefaultNetworkEvent(ev);
return out;
}
private static IpConnectivityEvent buildEvent(int netId, long transports, String ifname) {
final IpConnectivityEvent ev = new IpConnectivityEvent();
ev.networkId = netId;
@@ -164,11 +176,6 @@ final public class IpConnectivityEventBuilder {
return true;
}
if (in instanceof DefaultNetworkEvent) {
setDefaultNetworkEvent(out, (DefaultNetworkEvent) in);
return true;
}
if (in instanceof NetworkEvent) {
setNetworkEvent(out, (NetworkEvent) in);
return true;
@@ -225,16 +232,6 @@ final public class IpConnectivityEventBuilder {
out.setIpReachabilityEvent(ipReachabilityEvent);
}
private static void setDefaultNetworkEvent(IpConnectivityEvent out, DefaultNetworkEvent in) {
IpConnectivityLogClass.DefaultNetworkEvent defaultNetworkEvent =
new IpConnectivityLogClass.DefaultNetworkEvent();
defaultNetworkEvent.networkId = netIdOf(in.netId);
defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId);
defaultNetworkEvent.transportTypes = in.transportTypes;
defaultNetworkEvent.previousNetworkIpSupport = ipSupportOf(in);
out.setDefaultNetworkEvent(defaultNetworkEvent);
}
private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) {
IpConnectivityLogClass.NetworkEvent networkEvent =
new IpConnectivityLogClass.NetworkEvent();

View File

@@ -32,12 +32,15 @@ import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.Base64;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.RingBuffer;
import com.android.internal.util.TokenBucket;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
@@ -112,6 +115,9 @@ final public class IpConnectivityMetrics extends SystemService {
private final ToIntFunction<Context> mCapacityGetter;
@VisibleForTesting
final DefaultNetworkMetrics mDefaultNetworkMetrics = new DefaultNetworkMetrics();
public IpConnectivityMetrics(Context ctx, ToIntFunction<Context> capacityGetter) {
super(ctx);
mCapacityGetter = capacityGetter;
@@ -135,6 +141,8 @@ final public class IpConnectivityMetrics extends SystemService {
publishBinderService(SERVICE_NAME, impl);
publishBinderService(mNetdListener.SERVICE_NAME, mNetdListener);
LocalServices.addService(Logger.class, new LoggerImpl());
}
}
@@ -188,6 +196,8 @@ final public class IpConnectivityMetrics extends SystemService {
final List<IpConnectivityEvent> protoEvents = IpConnectivityEventBuilder.toProto(events);
mDefaultNetworkMetrics.flushEvents(protoEvents);
if (mNetdListener != null) {
mNetdListener.flushStatistics(protoEvents);
}
@@ -228,6 +238,7 @@ final public class IpConnectivityMetrics extends SystemService {
if (mNetdListener != null) {
mNetdListener.listAsProtos(pw);
}
mDefaultNetworkMetrics.listEventsAsProto(pw);
return;
}
@@ -237,6 +248,7 @@ final public class IpConnectivityMetrics extends SystemService {
if (mNetdListener != null) {
mNetdListener.list(pw);
}
mDefaultNetworkMetrics.listEvents(pw);
}
/**
@@ -254,6 +266,7 @@ final public class IpConnectivityMetrics extends SystemService {
if (mNetdListener != null) {
mNetdListener.list(pw);
}
mDefaultNetworkMetrics.listEvents(pw);
}
private void cmdStats(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -366,4 +379,15 @@ final public class IpConnectivityMetrics extends SystemService {
map.put(ApfProgramEvent.class, new TokenBucket((int)DateUtils.MINUTE_IN_MILLIS, 50));
return map;
}
/** Direct non-Binder interface for event producer clients within the system servers. */
public interface Logger {
DefaultNetworkMetrics defaultNetworkMetrics();
}
private class LoggerImpl implements Logger {
public DefaultNetworkMetrics defaultNetworkMetrics() {
return mDefaultNetworkMetrics;
}
}
}

View File

@@ -104,6 +104,8 @@ import android.util.LogPrinter;
import com.android.internal.util.WakeupMessage;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.connectivity.DefaultNetworkMetrics;
import com.android.server.connectivity.IpConnectivityMetrics;
import com.android.server.connectivity.MockableSystemProperties;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
@@ -156,6 +158,9 @@ public class ConnectivityServiceTest {
private MockNetworkAgent mEthernetNetworkAgent;
private Context mContext;
@Mock IpConnectivityMetrics.Logger mMetricsService;
@Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
// This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
// do not go through ConnectivityService but talk to netd directly, so they don't automatically
// reflect the state of our test ConnectivityService.
@@ -805,6 +810,11 @@ public class ConnectivityServiceTest {
return Context.ETHERNET_SERVICE.equals(name);
}
@Override
protected IpConnectivityMetrics.Logger metricsLogger() {
return mMetricsService;
}
public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
return mLastCreatedNetworkMonitor;
}
@@ -833,6 +843,9 @@ public class ConnectivityServiceTest {
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getContext();
MockitoAnnotations.initMocks(this);
when(mMetricsService.defaultNetworkMetrics()).thenReturn(mDefaultNetworkMetrics);
// InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
// http://b/25897652 .
if (Looper.myLooper() == null) {

View File

@@ -198,21 +198,20 @@ public class IpConnectivityEventBuilderTest {
@Test
public void testDefaultNetworkEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(DefaultNetworkEvent.class),
anInt(102),
anIntArray(1, 2, 3),
anInt(101),
aBool(true),
aBool(false));
DefaultNetworkEvent ev = new DefaultNetworkEvent();
ev.netId = 102;
ev.prevNetId = 101;
ev.transportTypes = new int[]{1, 2, 3};
ev.prevIPv4 = true;
ev.prevIPv6 = true;
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 0",
" time_ms: 1",
" network_id: 102",
" time_ms: 0",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
@@ -226,7 +225,7 @@ public class IpConnectivityEventBuilderTest {
" previous_network_id <",
" network_id: 101",
" >",
" previous_network_ip_support: 1",
" previous_network_ip_support: 3",
" transport_types: 1",
" transport_types: 2",
" transport_types: 3",
@@ -234,7 +233,7 @@ public class IpConnectivityEventBuilderTest {
">",
"version: 2\n");
verifySerialization(want, ev);
verifySerialization(want, IpConnectivityEventBuilder.toProto(ev));
}
@Test

View File

@@ -18,6 +18,7 @@ package com.android.server.connectivity;
import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,6 +31,10 @@ import android.content.Context;
import android.net.ConnectivityManager;
import android.net.ConnectivityMetricsEvent;
import android.net.IIpConnectivityMetrics;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.RouteInfo;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.metrics.ApfProgramEvent;
@@ -41,18 +46,22 @@ import android.net.metrics.IpManagerEvent;
import android.net.metrics.IpReachabilityEvent;
import android.net.metrics.RaEvent;
import android.net.metrics.ValidationProbeEvent;
import android.system.OsConstants;
import android.os.Parcelable;
import android.support.test.runner.AndroidJUnit4;
import android.system.OsConstants;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Base64;
import com.android.internal.util.BitUtils;
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -161,6 +170,144 @@ public class IpConnectivityMetricsTest {
assertEquals("", output2);
}
@Test
public void testDefaultNetworkEvents() throws Exception {
final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR});
final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI});
NetworkAgentInfo[][] defaultNetworks = {
// nothing -> cell
{null, makeNai(100, 10, false, true, cell)},
// cell -> wifi
{makeNai(100, 50, true, true, cell), makeNai(101, 20, true, false, wifi)},
// wifi -> nothing
{makeNai(101, 60, true, false, wifi), null},
// nothing -> cell
{null, makeNai(102, 10, true, true, cell)},
// cell -> wifi
{makeNai(102, 50, true, true, cell), makeNai(103, 20, true, false, wifi)},
};
for (NetworkAgentInfo[] pair : defaultNetworks) {
mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(pair[1], pair[0]);
}
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 100",
" time_ms: 0",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
" network_id <",
" network_id: 100",
" >",
" no_default_network_duration_ms: 0",
" previous_network_id <",
" network_id: 0",
" >",
" previous_network_ip_support: 0",
" transport_types: 0",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 101",
" time_ms: 0",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
" network_id <",
" network_id: 101",
" >",
" no_default_network_duration_ms: 0",
" previous_network_id <",
" network_id: 100",
" >",
" previous_network_ip_support: 3",
" transport_types: 1",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 0",
" time_ms: 0",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
" network_id <",
" network_id: 0",
" >",
" no_default_network_duration_ms: 0",
" previous_network_id <",
" network_id: 101",
" >",
" previous_network_ip_support: 1",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 102",
" time_ms: 0",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
" network_id <",
" network_id: 102",
" >",
" no_default_network_duration_ms: 0",
" previous_network_id <",
" network_id: 0",
" >",
" previous_network_ip_support: 0",
" transport_types: 0",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 103",
" time_ms: 0",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
" network_id <",
" network_id: 103",
" >",
" no_default_network_duration_ms: 0",
" previous_network_id <",
" network_id: 102",
" >",
" previous_network_ip_support: 3",
" transport_types: 1",
" >",
">",
"version: 2\n");
verifySerialization(want, getdump("flush"));
}
@Test
public void testEndToEndLogging() throws Exception {
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
@@ -194,7 +341,6 @@ public class IpConnectivityMetricsTest {
Parcelable[] events = {
new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED),
new DhcpClientEvent("SomeState", 192),
new DefaultNetworkEvent(102, new int[]{1,2,3}, 101, true, false),
new IpManagerEvent(IpManagerEvent.PROVISIONING_OK, 5678),
validationEv,
apfStats,
@@ -233,6 +379,13 @@ public class IpConnectivityMetricsTest {
wakeupEvent("wlan0", 10008);
wakeupEvent("rmnet0", 1000);
final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR});
final long wifi = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_WIFI});
NetworkAgentInfo cellNai = makeNai(100, 50, false, true, cell);
NetworkAgentInfo wifiNai = makeNai(101, 60, true, false, wifi);
mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(cellNai, null);
mService.mDefaultNetworkMetrics.logDefaultNetworkEvent(wifiNai, cellNai);
String want = String.join("\n",
"dropped_events: 0",
"events <",
@@ -264,30 +417,6 @@ public class IpConnectivityMetricsTest {
" network_id: 0",
" time_ms: 300",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
" network_id <",
" network_id: 102",
" >",
" no_default_network_duration_ms: 0",
" previous_network_id <",
" network_id: 101",
" >",
" previous_network_ip_support: 1",
" transport_types: 1",
" transport_types: 2",
" transport_types: 3",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 4",
" network_id: 0",
" time_ms: 400",
" transports: 0",
" ip_provisioning_event <",
" event_type: 1",
" if_name: \"\"",
@@ -298,7 +427,7 @@ public class IpConnectivityMetricsTest {
" if_name: \"\"",
" link_layer: 4",
" network_id: 0",
" time_ms: 500",
" time_ms: 400",
" transports: 0",
" validation_probe_event <",
" latency_ms: 40730",
@@ -310,7 +439,7 @@ public class IpConnectivityMetricsTest {
" if_name: \"\"",
" link_layer: 4",
" network_id: 0",
" time_ms: 600",
" time_ms: 500",
" transports: 0",
" apf_statistics <",
" dropped_ras: 2",
@@ -331,7 +460,7 @@ public class IpConnectivityMetricsTest {
" if_name: \"\"",
" link_layer: 4",
" network_id: 0",
" time_ms: 700",
" time_ms: 600",
" transports: 0",
" ra_event <",
" dnssl_lifetime: -1",
@@ -344,6 +473,50 @@ public class IpConnectivityMetricsTest {
">",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 100",
" time_ms: 0",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
" network_id <",
" network_id: 100",
" >",
" no_default_network_duration_ms: 0",
" previous_network_id <",
" network_id: 0",
" >",
" previous_network_ip_support: 0",
" transport_types: 0",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 101",
" time_ms: 0",
" transports: 0",
" default_network_event <",
" default_network_duration_ms: 0",
" final_score: 0",
" initial_score: 0",
" ip_support: 0",
" network_id <",
" network_id: 101",
" >",
" no_default_network_duration_ms: 0",
" previous_network_id <",
" network_id: 100",
" >",
" previous_network_ip_support: 2",
" transport_types: 1",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 4",
" network_id: 100",
" time_ms: 0",
@@ -471,6 +644,26 @@ public class IpConnectivityMetricsTest {
mNetdListener.onWakeupEvent(prefix, uid, uid, 0);
}
NetworkAgentInfo makeNai(int netId, int score, boolean ipv4, boolean ipv6, long transports) {
NetworkAgentInfo nai = mock(NetworkAgentInfo.class);
when(nai.network()).thenReturn(new Network(netId));
when(nai.getCurrentScore()).thenReturn(score);
nai.linkProperties = new LinkProperties();
nai.networkCapabilities = new NetworkCapabilities();
for (int t : BitUtils.unpackBits(transports)) {
nai.networkCapabilities.addTransportType(t);
}
if (ipv4) {
nai.linkProperties.addLinkAddress(new LinkAddress("192.0.2.12/24"));
nai.linkProperties.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0")));
}
if (ipv6) {
nai.linkProperties.addLinkAddress(new LinkAddress("2001:db8:dead:beef:f00::a0/64"));
nai.linkProperties.addRoute(new RouteInfo(new IpPrefix("::/0")));
}
return nai;
}
List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
ArgumentCaptor<ConnectivityMetricsEvent> captor =
ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);