From 9910dbc682118d2527fc17d4b50e8dcb94318534 Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Wed, 22 Mar 2017 18:29:58 +0900 Subject: [PATCH] Add BitUtils bit packing methods (Connectivity metrics: add transports pretty printing) This patch is a partial cherry-pick from commit df456e13a1127e3c8594b1d22ea4a9b3dca67a4b for the BitUtils and NetworkCapabilities classes. Bug: 34901696 Test: none (cherry picked from commit df456e13a1127e3c8594b1d22ea4a9b3dca67a4b) Merged-In: Id04f9080e7f75608deeb49306aec34941e71794c Change-Id: I64eae49f646365b7cd1683a689315fe03bf0bdd9 --- core/java/android/net/NetworkCapabilities.java | 56 ++++++++++++----------- core/java/com/android/internal/util/BitUtils.java | 21 +++++++++ 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 5edc7c64275c..1da0d281538d 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -20,6 +20,7 @@ import android.os.Parcel; import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.BitUtils; import java.util.Objects; @@ -292,7 +293,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public int[] getCapabilities() { - return enumerateBits(mNetworkCapabilities); + return BitUtils.unpackBits(mNetworkCapabilities); } /** @@ -308,19 +309,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; } @@ -433,6 +421,15 @@ public final class NetworkCapabilities implements Parcelable { private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR; private 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 @@ -479,7 +476,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public int[] getTransportTypes() { - return enumerateBits(mTransportTypes); + return BitUtils.unpackBits(mTransportTypes); } /** @@ -886,18 +883,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 ""; + } + 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 transports; + return TRANSPORT_NAMES[transport]; } } diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java index a208ccb8f35f..e349f3d4b473 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; + } } -- 2.11.0