diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java index 63ccaaea14cf1..46bb346706112 100644 --- a/core/java/android/net/ConnectivityMetricsEvent.java +++ b/core/java/android/net/ConnectivityMetricsEvent.java @@ -18,6 +18,7 @@ package android.net; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.util.BitUtils; /** * Represents a core networking event defined in package android.net.metrics. @@ -78,13 +79,15 @@ public final class ConnectivityMetricsEvent implements Parcelable { public String toString() { StringBuilder buffer = new StringBuilder("ConnectivityMetricsEvent("); buffer.append(String.format("%tT.%tL", timestamp, timestamp)); - // TODO: add transports if (netId != 0) { buffer.append(", ").append(netId); } if (ifname != null) { buffer.append(", ").append(ifname); } + for (int t : BitUtils.unpackBits(transports)) { + buffer.append(", ").append(NetworkCapabilities.transportNameOf(t)); + } buffer.append("): ").append(data.toString()); return buffer.toString(); } diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 8665b9c5cf52b..a594befbd5068 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -19,7 +19,7 @@ package android.net; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; -import java.lang.IllegalArgumentException; +import com.android.internal.util.BitUtils; /** * This class represents the capabilities of a network. This is used both to specify @@ -289,7 +289,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public int[] getCapabilities() { - return enumerateBits(mNetworkCapabilities); + return BitUtils.unpackBits(mNetworkCapabilities); } /** @@ -305,19 +305,6 @@ public final class NetworkCapabilities implements Parcelable { return ((mNetworkCapabilities & (1 << capability)) != 0); } - private int[] enumerateBits(long val) { - int size = Long.bitCount(val); - int[] result = new int[size]; - int index = 0; - int resource = 0; - while (val > 0) { - if ((val & 1) == 1) result[index++] = resource; - val = val >> 1; - resource++; - } - return result; - } - private void combineNetCapabilities(NetworkCapabilities nc) { this.mNetworkCapabilities |= nc.mNetworkCapabilities; } @@ -428,6 +415,15 @@ public final class NetworkCapabilities implements Parcelable { /** @hide */ public static final int MAX_TRANSPORT = TRANSPORT_WIFI_AWARE; + private static final String[] TRANSPORT_NAMES = { + "CELLULAR", + "WIFI", + "BLUETOOTH", + "ETHERNET", + "VPN", + "WIFI_AWARE" + }; + /** * Adds the given transport type to this {@code NetworkCapability} instance. * Multiple transports may be applied sequentially. Note that when searching @@ -474,18 +470,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public int[] getTransportTypes() { - return enumerateBits(mTransportTypes); - } - - /** - * Gets all the transports set on this {@code NetworkCapability} instance. - * - * @return a bit field composed of up bits at indexes defined by - * {@code NetworkCapabilities.TRANSPORT_*} values for this instance. - * @hide - */ - public long getTransports() { - return mTransportTypes; + return BitUtils.unpackBits(mTransportTypes); } /** @@ -899,18 +884,23 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public static String transportNamesOf(int[] types) { - String transports = ""; - for (int i = 0; i < types.length;) { - switch (types[i]) { - case TRANSPORT_CELLULAR: transports += "CELLULAR"; break; - case TRANSPORT_WIFI: transports += "WIFI"; break; - case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break; - case TRANSPORT_ETHERNET: transports += "ETHERNET"; break; - case TRANSPORT_VPN: transports += "VPN"; break; - case TRANSPORT_WIFI_AWARE: transports += "WIFI_AWARE"; break; - } - if (++i < types.length) transports += "|"; + if (types == null || types.length == 0) { + return ""; } - return transports; + StringBuilder transports = new StringBuilder(); + for (int t : types) { + transports.append("|").append(transportNameOf(t)); + } + return transports.substring(1); + } + + /** + * @hide + */ + public static String transportNameOf(int transport) { + if (transport < 0 || TRANSPORT_NAMES.length <= transport) { + return "UNKNOWN"; + } + return TRANSPORT_NAMES[transport]; } } diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java index ac727ca2e4db1..4e57efa4d47b4 100644 --- a/core/java/android/net/metrics/IpConnectivityLog.java +++ b/core/java/android/net/metrics/IpConnectivityLog.java @@ -23,6 +23,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.BitUtils; /** * Class for logging IpConnectvity events with IpConnectivityMetrics @@ -117,10 +118,10 @@ public class IpConnectivityLog { * @param data is a Parcelable instance representing the event. * @return true if the event was successfully logged. */ - public boolean log(int netid, long transports, Parcelable data) { + public boolean log(int netid, int[] transports, Parcelable data) { ConnectivityMetricsEvent ev = makeEv(data); ev.netId = netid; - ev.transports = transports; + ev.transports = BitUtils.packBits(transports); return log(ev); } diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java index a208ccb8f35f1..e349f3d4b4737 100644 --- a/core/java/com/android/internal/util/BitUtils.java +++ b/core/java/com/android/internal/util/BitUtils.java @@ -55,4 +55,25 @@ public class BitUtils { && maskedEquals(a.getMostSignificantBits(), b.getMostSignificantBits(), mask.getMostSignificantBits()); } + + public static int[] unpackBits(long val) { + int size = Long.bitCount(val); + int[] result = new int[size]; + int index = 0; + int bitPos = 0; + while (val > 0) { + if ((val & 1) == 1) result[index++] = bitPos; + val = val >> 1; + bitPos++; + } + return result; + } + + public static long packBits(int[] bits) { + long packed = 0; + for (int b : bits) { + packed |= (1 << b); + } + return packed; + } } diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index 3e53aca434417..c4ad45576b085 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -1061,7 +1061,7 @@ public class NetworkMonitor extends StateMachine { } private void logValidationProbe(long durationMs, int probeType, int probeResult) { - long transports = mNetworkAgentInfo.networkCapabilities.getTransports(); + int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes(); boolean isFirstValidation = validationStage().isFirstValidation; ValidationProbeEvent ev = new ValidationProbeEvent(); ev.probeType = ValidationProbeEvent.makeProbeType(probeType, isFirstValidation);