diff options
| author | Lorenzo Colitti <lorenzo@google.com> | 2017-01-18 10:29:51 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-01-18 10:29:57 +0000 |
| commit | 5db17efcf60dfabec46cf1cd774a331b934fd21d (patch) | |
| tree | 98c6166e903225f798e2bacd981abbf6c56e70e2 /core/java/android | |
| parent | fc9c93c2ddc5a1324122f44b09880fae3cbb934d (diff) | |
| parent | 7a61361724aeba9de7d809bef7d0b0ea113cc6d1 (diff) | |
Merge changes from topic 'net-update-mr2-dev-plus-aosp' into nyc-mr2-dev-plus-aosp
* changes:
DO NOT MERGE: Add IP conn metrics to dumpsys and bug reports
DO NOT MERGE: Add missing dependency.
DO NOT MERGE: Show notification for always-on app VPN
DO NOT MERGE: Implement metered tracking for NetworkStats summary queries.
DO NOT MERGE: ConnectivityServiceTest: fix testAvoidBadWifiSettings
DO NOT MERGE: Fix ConnectivityServiceTest testRequestBenchmark
DO NOT MERGE: Switch over to new "time.android.com" NTP pool.
DO NOT MERGE: Define API for metering network stats buckets.
DO NOT MERGE: Refactored NetworkStatsServiceTest to use Mockito instead of EasyMock.
DO NOT MERGE: Use @Ignore to explicitly disable a @Test method.
DO NOT MERGE: Fixed NetworkStatsServiceTest and converted it to JUnit4.
DO NOT MERGE: ConnectivityThread: use lazy holder idiom
DO NOT MERGE: ConnectivityManager: use ConnectivityThread looper
DO NOT MERGE: ConnectivityManager: a simpler CallbackHandler
DO NOT MERGE: Indicate the NsdServiceInfo attributes are only filled in for a resolved service.
DO NOT MERGE: Add a null check for the OnStartTetheringCallback.
DO NOT MERGE: [CS] Remove timeout event after first available
DO NOT MERGE: ApfTest: tag tests with @SmallTest or @MediumTest
DO NOT MERGE: Unbreak TetherInterfaceStateMachineTest.
DO NOT MERGE: Move the connectivity tests to frameworks/base/tests/net.
DO NOT MERGE: De-guava BroadcastInterceptingContext and move it to testutils.
DO NOT MERGE: Move FakeSettingsProvider to a common location.
DO NOT MERGE: ConnectivityServiceTest: mark flaky test as such
DO NOT MERGE: Add fuzzing tests to ApfFilter RA processing
DO NOT MERGE: Support timeouts for requestNetwork() invocations.
DO NOT MERGE: Silence the obnoxious MTU 0 error message that occur when no MTU is specified for a given network.
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/usage/NetworkStats.java | 50 | ||||
| -rw-r--r-- | core/java/android/app/usage/NetworkStatsManager.java | 43 | ||||
| -rw-r--r-- | core/java/android/net/ConnectivityManager.java | 133 | ||||
| -rw-r--r-- | core/java/android/net/ConnectivityThread.java | 23 | ||||
| -rw-r--r-- | core/java/android/net/EventLogTags.logtags | 6 | ||||
| -rw-r--r-- | core/java/android/net/NetworkIdentity.java | 6 | ||||
| -rw-r--r-- | core/java/android/net/NetworkStats.java | 103 | ||||
| -rw-r--r-- | core/java/android/net/SntpClient.java | 6 | ||||
| -rw-r--r-- | core/java/android/net/nsd/NsdManager.java | 10 | ||||
| -rw-r--r-- | core/java/android/net/nsd/NsdServiceInfo.java | 3 |
10 files changed, 253 insertions, 130 deletions
diff --git a/core/java/android/app/usage/NetworkStats.java b/core/java/android/app/usage/NetworkStats.java index 226aa8f2706d..3670b914ecf3 100644 --- a/core/java/android/app/usage/NetworkStats.java +++ b/core/java/android/app/usage/NetworkStats.java @@ -164,6 +164,29 @@ public final class NetworkStats implements AutoCloseable { public static final int UID_TETHERING = TrafficStats.UID_TETHERING; /** @hide */ + @IntDef({METERED_ALL, METERED_NO, METERED_YES}) + @Retention(RetentionPolicy.SOURCE) + public @interface Metered {} + + /** + * Combined usage across all metered states. Covers metered and unmetered usage. + */ + public static final int METERED_ALL = -1; + + /** + * Usage that occurs on an unmetered network. + */ + public static final int METERED_NO = 0x1; + + /** + * Usage that occurs on a metered network. + * + * <p>A network is classified as metered when the user is sensitive to heavy data usage on + * that connection. + */ + public static final int METERED_YES = 0x2; + + /** @hide */ @IntDef({ROAMING_ALL, ROAMING_NO, ROAMING_YES}) @Retention(RetentionPolicy.SOURCE) public @interface Roaming {} @@ -200,6 +223,7 @@ public final class NetworkStats implements AutoCloseable { private int mUid; private int mTag; private int mState; + private int mMetered; private int mRoaming; private long mBeginTimeStamp; private long mEndTimeStamp; @@ -232,6 +256,15 @@ public final class NetworkStats implements AutoCloseable { return tag; } + private static @Metered int convertMetered(int metered) { + switch (metered) { + case android.net.NetworkStats.METERED_ALL : return METERED_ALL; + case android.net.NetworkStats.METERED_NO: return METERED_NO; + case android.net.NetworkStats.METERED_YES: return METERED_YES; + } + return 0; + } + private static @Roaming int convertRoaming(int roaming) { switch (roaming) { case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL; @@ -279,6 +312,21 @@ public final class NetworkStats implements AutoCloseable { } /** + * Metered state. One of the following values:<p/> + * <ul> + * <li>{@link #METERED_ALL}</li> + * <li>{@link #METERED_NO}</li> + * <li>{@link #METERED_YES}</li> + * </ul> + * <p>A network is classified as metered when the user is sensitive to heavy data usage on + * that connection. Apps may warn before using these networks for large downloads. The + * metered state can be set by the user within data usage network restrictions. + */ + public @Metered int getMetered() { + return mMetered; + } + + /** * Roaming state. One of the following values:<p/> * <ul> * <li>{@link #ROAMING_ALL}</li> @@ -491,6 +539,7 @@ public final class NetworkStats implements AutoCloseable { bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid); bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag); bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set); + bucketOut.mMetered = Bucket.convertMetered(mRecycledSummaryEntry.metered); bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming); bucketOut.mBeginTimeStamp = mStartTimeStamp; bucketOut.mEndTimeStamp = mEndTimeStamp; @@ -539,6 +588,7 @@ public final class NetworkStats implements AutoCloseable { bucketOut.mUid = Bucket.convertUid(getUid()); bucketOut.mTag = Bucket.convertTag(mTag); bucketOut.mState = Bucket.STATE_ALL; + bucketOut.mMetered = Bucket.METERED_ALL; bucketOut.mRoaming = Bucket.ROAMING_ALL; bucketOut.mBeginTimeStamp = mRecycledHistoryEntry.bucketStart; bucketOut.mEndTimeStamp = mRecycledHistoryEntry.bucketStart + diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 7961a72a12e4..840413a1151e 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -51,16 +51,17 @@ import android.util.Log; * {@link #querySummaryForUser} <p /> * {@link #querySummary} <p /> * These queries aggregate network usage across the whole interval. Therefore there will be only one - * bucket for a particular key and state and roaming combination. In case of the user-wide and - * device-wide summaries a single bucket containing the totalised network usage is returned. + * bucket for a particular key, state, metered and roaming combination. In case of the user-wide + * and device-wide summaries a single bucket containing the totalised network usage is returned. * <h3> * History queries * </h3> * {@link #queryDetailsForUid} <p /> * {@link #queryDetails} <p /> - * These queries do not aggregate over time but do aggregate over state and roaming. Therefore there - * can be multiple buckets for a particular key but all Bucket's state is going to be - * {@link NetworkStats.Bucket#STATE_ALL} and all Bucket's roaming is going to be + * These queries do not aggregate over time but do aggregate over state, metered and roaming. + * Therefore there can be multiple buckets for a particular key but all Bucket's state is going to + * be {@link NetworkStats.Bucket#STATE_ALL}, all Bucket's metered is going to be + * {@link NetworkStats.Bucket#METERED_ALL}, and all Bucket's roaming is going to be * {@link NetworkStats.Bucket#ROAMING_ALL}. * <p /> * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the @@ -103,10 +104,11 @@ public class NetworkStatsManager { /** * Query network usage statistics summaries. Result is summarised data usage for the whole - * device. Result is a single Bucket aggregated over time, state, uid, tag and roaming. This - * means the bucket's start and end timestamp are going to be the same as the 'startTime' and - * 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid - * {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE} + * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and + * roaming. This means the bucket's start and end timestamp are going to be the same as the + * 'startTime' and 'endTime' parameters. State is going to be + * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL}, + * tag {@link NetworkStats.Bucket#TAG_NONE}, metered {@link NetworkStats.Bucket#METERED_ALL}, * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}. * * @param networkType As defined in {@link ConnectivityManager}, e.g. @@ -142,8 +144,10 @@ public class NetworkStatsManager { * Query network usage statistics summaries. Result is summarised data usage for all uids * belonging to calling user. Result is a single Bucket aggregated over time, state and uid. * This means the bucket's start and end timestamp are going to be the same as the 'startTime' - * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid - * {@link NetworkStats.Bucket#UID_ALL}. + * and 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, + * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE}, + * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming + * {@link NetworkStats.Bucket#ROAMING_ALL}. * * @param networkType As defined in {@link ConnectivityManager}, e.g. * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} @@ -177,9 +181,10 @@ public class NetworkStatsManager { /** * Query network usage statistics summaries. Result filtered to include only uids belonging to * calling user. Result is aggregated over time, hence all buckets will have the same start and - * end timestamps. Not aggregated over state or uid. This means buckets' start and end - * timestamps are going to be the same as the 'startTime' and 'endTime' parameters. - * State and uid are going to vary, and tag is going to be the same. + * end timestamps. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, + * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE}, + * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming + * {@link NetworkStats.Bucket#ROAMING_ALL}. * * @param networkType As defined in {@link ConnectivityManager}, e.g. * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} @@ -262,10 +267,12 @@ public class NetworkStatsManager { /** * Query network usage statistics details. Result filtered to include only uids belonging to - * calling user. Result is aggregated over state but not aggregated over time or uid. This means - * buckets' start and end timestamps are going to be between 'startTime' and 'endTime' - * parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid will vary, - * tag {@link NetworkStats.Bucket#TAG_NONE} and roaming is going to be + * calling user. Result is aggregated over state but not aggregated over time, uid, tag, + * metered, nor roaming. This means buckets' start and end timestamps are going to be between + * 'startTime' and 'endTime' parameters. State is going to be + * {@link NetworkStats.Bucket#STATE_ALL}, uid will vary, + * tag {@link NetworkStats.Bucket#TAG_NONE}, metered is going to be + * {@link NetworkStats.Bucket#METERED_ALL}, and roaming is going to be * {@link NetworkStats.Bucket#ROAMING_ALL}. * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't * interpolate across partial buckets. Since bucket length is in the order of hours, this diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 2b5afa725de6..dc37a149a884 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2093,6 +2093,8 @@ public class ConnectivityManager { @SystemApi public void startTethering(int type, boolean showProvisioningUi, final OnStartTetheringCallback callback, Handler handler) { + checkNotNull(callback, "OnStartTetheringCallback cannot be null."); + ResultReceiver wrappedCallback = new ResultReceiver(handler) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { @@ -2103,6 +2105,7 @@ public class ConnectivityManager { } } }; + try { mService.startTethering(type, wrappedCallback, showProvisioningUi); } catch (RemoteException e) { @@ -2606,7 +2609,8 @@ public class ConnectivityManager { /** * Called if no network is found in the given timeout time. If no timeout is given, - * this will not be called. + * this will not be called. The associated {@link NetworkRequest} will have already + * been removed and released, as if {@link #unregisterNetworkCallback} had been called. * @hide */ public void onUnavailable() {} @@ -2670,6 +2674,7 @@ public class ConnectivityManager { public static final int CALLBACK_IP_CHANGED = BASE + 7; /** @hide */ public static final int CALLBACK_RELEASED = BASE + 8; + // TODO: consider deleting CALLBACK_EXIT and shifting following enum codes down by 1. /** @hide */ public static final int CALLBACK_EXIT = BASE + 9; /** @hide obj = NetworkCapabilities, arg1 = seq number */ @@ -2679,25 +2684,38 @@ public class ConnectivityManager { /** @hide */ public static final int CALLBACK_RESUMED = BASE + 12; + /** @hide */ + public static String getCallbackName(int whichCallback) { + switch (whichCallback) { + case CALLBACK_PRECHECK: return "CALLBACK_PRECHECK"; + case CALLBACK_AVAILABLE: return "CALLBACK_AVAILABLE"; + case CALLBACK_LOSING: return "CALLBACK_LOSING"; + case CALLBACK_LOST: return "CALLBACK_LOST"; + case CALLBACK_UNAVAIL: return "CALLBACK_UNAVAIL"; + case CALLBACK_CAP_CHANGED: return "CALLBACK_CAP_CHANGED"; + case CALLBACK_IP_CHANGED: return "CALLBACK_IP_CHANGED"; + case CALLBACK_RELEASED: return "CALLBACK_RELEASED"; + case CALLBACK_EXIT: return "CALLBACK_EXIT"; + case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST"; + case CALLBACK_SUSPENDED: return "CALLBACK_SUSPENDED"; + case CALLBACK_RESUMED: return "CALLBACK_RESUMED"; + default: + return Integer.toString(whichCallback); + } + } + private class CallbackHandler extends Handler { - private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap; - private final AtomicInteger mRefCount; private static final String TAG = "ConnectivityManager.CallbackHandler"; - private final ConnectivityManager mCm; private static final boolean DBG = false; - CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap, - AtomicInteger refCount, ConnectivityManager cm) { + CallbackHandler(Looper looper) { super(looper); - mCallbackMap = callbackMap; - mRefCount = refCount; - mCm = cm; } @Override public void handleMessage(Message message) { - NetworkRequest request = (NetworkRequest) getObject(message, NetworkRequest.class); - Network network = (Network) getObject(message, Network.class); + NetworkRequest request = getObject(message, NetworkRequest.class); + Network network = getObject(message, Network.class); if (DBG) { Log.d(TAG, whatToString(message.what) + " for network " + network); } @@ -2740,9 +2758,7 @@ public class ConnectivityManager { case CALLBACK_CAP_CHANGED: { NetworkCallback callback = getCallback(request, "CAP_CHANGED"); if (callback != null) { - NetworkCapabilities cap = (NetworkCapabilities)getObject(message, - NetworkCapabilities.class); - + NetworkCapabilities cap = getObject(message, NetworkCapabilities.class); callback.onCapabilitiesChanged(network, cap); } break; @@ -2750,9 +2766,7 @@ public class ConnectivityManager { case CALLBACK_IP_CHANGED: { NetworkCallback callback = getCallback(request, "IP_CHANGED"); if (callback != null) { - LinkProperties lp = (LinkProperties)getObject(message, - LinkProperties.class); - + LinkProperties lp = getObject(message, LinkProperties.class); callback.onLinkPropertiesChanged(network, lp); } break; @@ -2772,24 +2786,16 @@ public class ConnectivityManager { break; } case CALLBACK_RELEASED: { - NetworkCallback callback = null; - synchronized(mCallbackMap) { - callback = mCallbackMap.remove(request); + final NetworkCallback callback; + synchronized(sCallbacks) { + callback = sCallbacks.remove(request); } - if (callback != null) { - synchronized(mRefCount) { - if (mRefCount.decrementAndGet() == 0) { - getLooper().quit(); - } - } - } else { + if (callback == null) { Log.e(TAG, "callback not found for RELEASED message"); } break; } case CALLBACK_EXIT: { - Log.d(TAG, "Listener quitting"); - getLooper().quit(); break; } case EXPIRE_LEGACY_REQUEST: { @@ -2799,14 +2805,14 @@ public class ConnectivityManager { } } - private Object getObject(Message msg, Class c) { - return msg.getData().getParcelable(c.getSimpleName()); + private <T> T getObject(Message msg, Class<T> c) { + return (T) msg.getData().getParcelable(c.getSimpleName()); } private NetworkCallback getCallback(NetworkRequest req, String name) { NetworkCallback callback; - synchronized(mCallbackMap) { - callback = mCallbackMap.get(req); + synchronized(sCallbacks) { + callback = sCallbacks.get(req); } if (callback == null) { Log.e(TAG, "callback not found for " + name + " message"); @@ -2815,63 +2821,56 @@ public class ConnectivityManager { } } - private void incCallbackHandlerRefCount() { - synchronized(sCallbackRefCount) { - if (sCallbackRefCount.incrementAndGet() == 1) { - // TODO: switch this to ConnectivityThread - HandlerThread callbackThread = new HandlerThread("ConnectivityManager"); - callbackThread.start(); - sCallbackHandler = new CallbackHandler(callbackThread.getLooper(), - sNetworkCallback, sCallbackRefCount, this); + private CallbackHandler getHandler() { + synchronized (sCallbacks) { + if (sCallbackHandler == null) { + sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper()); } + return sCallbackHandler; } } - private void decCallbackHandlerRefCount() { - synchronized(sCallbackRefCount) { - if (sCallbackRefCount.decrementAndGet() == 0) { - sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget(); - sCallbackHandler = null; - } - } - } - - static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback = - new HashMap<NetworkRequest, NetworkCallback>(); - static final AtomicInteger sCallbackRefCount = new AtomicInteger(0); - static CallbackHandler sCallbackHandler = null; + static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>(); + static CallbackHandler sCallbackHandler; private final static int LISTEN = 1; private final static int REQUEST = 2; private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, - NetworkCallback networkCallback, int timeoutSec, int action, - int legacyType) { - if (networkCallback == null) { + NetworkCallback callback, int timeoutMs, int action, int legacyType) { + return sendRequestForNetwork(need, callback, getHandler(), timeoutMs, action, legacyType); + } + + private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, + NetworkCallback callback, Handler handler, int timeoutMs, int action, int legacyType) { + if (callback == null) { throw new IllegalArgumentException("null NetworkCallback"); } if (need == null && action != REQUEST) { throw new IllegalArgumentException("null NetworkCapabilities"); } + // TODO: throw an exception if callback.networkRequest is not null. + // http://b/20701525 + final NetworkRequest request; try { - incCallbackHandlerRefCount(); - synchronized(sNetworkCallback) { + synchronized(sCallbacks) { + Messenger messenger = new Messenger(handler); + Binder binder = new Binder(); if (action == LISTEN) { - networkCallback.networkRequest = mService.listenForNetwork(need, - new Messenger(sCallbackHandler), new Binder()); + request = mService.listenForNetwork(need, messenger, binder); } else { - networkCallback.networkRequest = mService.requestNetwork(need, - new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType); + request = mService.requestNetwork( + need, messenger, timeoutMs, binder, legacyType); } - if (networkCallback.networkRequest != null) { - sNetworkCallback.put(networkCallback.networkRequest, networkCallback); + if (request != null) { + sCallbacks.put(request, callback); } + callback.networkRequest = request; } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } - if (networkCallback.networkRequest == null) decCallbackHandlerRefCount(); - return networkCallback.networkRequest; + return request; } /** diff --git a/core/java/android/net/ConnectivityThread.java b/core/java/android/net/ConnectivityThread.java index 55c3402bf39d..0b218e738b77 100644 --- a/core/java/android/net/ConnectivityThread.java +++ b/core/java/android/net/ConnectivityThread.java @@ -27,25 +27,30 @@ import android.os.Looper; * @hide */ public final class ConnectivityThread extends HandlerThread { - private static ConnectivityThread sInstance; + + // A class implementing the lazy holder idiom: the unique static instance + // of ConnectivityThread is instantiated in a thread-safe way (guaranteed by + // the language specs) the first time that Singleton is referenced in get() + // or getInstanceLooper(). + private static class Singleton { + private static final ConnectivityThread INSTANCE = createInstance(); + } private ConnectivityThread() { super("ConnectivityThread"); } - private static synchronized ConnectivityThread getInstance() { - if (sInstance == null) { - sInstance = new ConnectivityThread(); - sInstance.start(); - } - return sInstance; + private static ConnectivityThread createInstance() { + ConnectivityThread t = new ConnectivityThread(); + t.start(); + return t; } public static ConnectivityThread get() { - return getInstance(); + return Singleton.INSTANCE; } public static Looper getInstanceLooper() { - return getInstance().getLooper(); + return Singleton.INSTANCE.getLooper(); } } diff --git a/core/java/android/net/EventLogTags.logtags b/core/java/android/net/EventLogTags.logtags new file mode 100644 index 000000000000..d5ed01496eba --- /dev/null +++ b/core/java/android/net/EventLogTags.logtags @@ -0,0 +1,6 @@ +# See system/core/logcat/event.logtags for a description of the format of this file. + +option java_package android.net + +50080 ntp_success (server|3),(rtt|2),(offset|2) +50081 ntp_failure (server|3),(msg|3) diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index d570e66a2435..c704ef0c9ca7 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -171,7 +171,8 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { String subscriberId = null; String networkId = null; boolean roaming = false; - boolean metered = false; + boolean metered = !state.networkCapabilities.hasCapability( + NetworkCapabilities.NET_CAPABILITY_NOT_METERED); if (isNetworkTypeMobile(type)) { if (state.subscriberId == null) { @@ -185,9 +186,6 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { subscriberId = state.subscriberId; roaming = state.networkInfo.isRoaming(); - metered = !state.networkCapabilities.hasCapability( - NetworkCapabilities.NET_CAPABILITY_NOT_METERED); - } else if (type == TYPE_WIFI) { if (state.networkId != null) { networkId = state.networkId; diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index f65a50f02df3..77ce65b0815a 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -68,11 +68,18 @@ public class NetworkStats implements Parcelable { // TODO: Rename TAG_NONE to TAG_ALL. public static final int TAG_NONE = 0; - /** {@link #set} value for all roaming values. */ + /** {@link #metered} value to account for all metered states. */ + public static final int METERED_ALL = -1; + /** {@link #metered} value where native, unmetered data is accounted. */ + public static final int METERED_NO = 0; + /** {@link #metered} value where metered data is accounted. */ + public static final int METERED_YES = 1; + + /** {@link #roaming} value to account for all roaming states. */ public static final int ROAMING_ALL = -1; - /** {@link #set} value where native, non-roaming data is accounted. */ + /** {@link #roaming} value where native, non-roaming data is accounted. */ public static final int ROAMING_NO = 0; - /** {@link #set} value where roaming data is accounted. */ + /** {@link #roaming} value where roaming data is accounted. */ public static final int ROAMING_YES = 1; // TODO: move fields to "mVariable" notation @@ -88,6 +95,7 @@ public class NetworkStats implements Parcelable { private int[] uid; private int[] set; private int[] tag; + private int[] metered; private int[] roaming; private long[] rxBytes; private long[] rxPackets; @@ -105,6 +113,12 @@ public class NetworkStats implements Parcelable { * to disk. We merge in the correct value when reporting this value to clients of * getSummary(). */ + public int metered; + /** + * Note that this is only populated w/ the default value when read from /proc or written + * to disk. We merge in the correct value when reporting this value to clients of + * getSummary(). + */ public int roaming; public long rxBytes; public long rxPackets; @@ -123,16 +137,17 @@ public class NetworkStats implements Parcelable { public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { - this(iface, uid, set, tag, ROAMING_NO, rxBytes, rxPackets, txBytes, txPackets, - operations); + this(iface, uid, set, tag, METERED_NO, ROAMING_NO, rxBytes, rxPackets, txBytes, + txPackets, operations); } - public Entry(String iface, int uid, int set, int tag, int roaming, long rxBytes, - long rxPackets, long txBytes, long txPackets, long operations) { + public Entry(String iface, int uid, int set, int tag, int metered, int roaming, + long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { this.iface = iface; this.uid = uid; this.set = set; this.tag = tag; + this.metered = metered; this.roaming = roaming; this.rxBytes = rxBytes; this.rxPackets = rxPackets; @@ -165,6 +180,7 @@ public class NetworkStats implements Parcelable { builder.append(" uid=").append(uid); builder.append(" set=").append(setToString(set)); builder.append(" tag=").append(tagToString(tag)); + builder.append(" metered=").append(meteredToString(metered)); builder.append(" roaming=").append(roamingToString(roaming)); builder.append(" rxBytes=").append(rxBytes); builder.append(" rxPackets=").append(rxPackets); @@ -178,13 +194,18 @@ public class NetworkStats implements Parcelable { public boolean equals(Object o) { if (o instanceof Entry) { final Entry e = (Entry) o; - return uid == e.uid && set == e.set && tag == e.tag && roaming == e.roaming - && rxBytes == e.rxBytes && rxPackets == e.rxPackets && txBytes == e.txBytes - && txPackets == e.txPackets && operations == e.operations - && iface.equals(e.iface); + return uid == e.uid && set == e.set && tag == e.tag && metered == e.metered + && roaming == e.roaming && rxBytes == e.rxBytes && rxPackets == e.rxPackets + && txBytes == e.txBytes && txPackets == e.txPackets + && operations == e.operations && iface.equals(e.iface); } return false; } + + @Override + public int hashCode() { + return Objects.hash(uid, set, tag, metered, roaming, iface); + } } public NetworkStats(long elapsedRealtime, int initialSize) { @@ -196,6 +217,7 @@ public class NetworkStats implements Parcelable { this.uid = new int[initialSize]; this.set = new int[initialSize]; this.tag = new int[initialSize]; + this.metered = new int[initialSize]; this.roaming = new int[initialSize]; this.rxBytes = new long[initialSize]; this.rxPackets = new long[initialSize]; @@ -209,6 +231,7 @@ public class NetworkStats implements Parcelable { this.uid = EmptyArray.INT; this.set = EmptyArray.INT; this.tag = EmptyArray.INT; + this.metered = EmptyArray.INT; this.roaming = EmptyArray.INT; this.rxBytes = EmptyArray.LONG; this.rxPackets = EmptyArray.LONG; @@ -226,6 +249,7 @@ public class NetworkStats implements Parcelable { uid = parcel.createIntArray(); set = parcel.createIntArray(); tag = parcel.createIntArray(); + metered = parcel.createIntArray(); roaming = parcel.createIntArray(); rxBytes = parcel.createLongArray(); rxPackets = parcel.createLongArray(); @@ -243,6 +267,7 @@ public class NetworkStats implements Parcelable { dest.writeIntArray(uid); dest.writeIntArray(set); dest.writeIntArray(tag); + dest.writeIntArray(metered); dest.writeIntArray(roaming); dest.writeLongArray(rxBytes); dest.writeLongArray(rxPackets); @@ -277,10 +302,11 @@ public class NetworkStats implements Parcelable { } @VisibleForTesting - public NetworkStats addValues(String iface, int uid, int set, int tag, int roaming, + public NetworkStats addValues(String iface, int uid, int set, int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { return addValues(new Entry( - iface, uid, set, tag, roaming, rxBytes, rxPackets, txBytes, txPackets, operations)); + iface, uid, set, tag, metered, roaming, rxBytes, rxPackets, txBytes, txPackets, + operations)); } /** @@ -294,6 +320,7 @@ public class NetworkStats implements Parcelable { uid = Arrays.copyOf(uid, newLength); set = Arrays.copyOf(set, newLength); tag = Arrays.copyOf(tag, newLength); + metered = Arrays.copyOf(metered, newLength); roaming = Arrays.copyOf(roaming, newLength); rxBytes = Arrays.copyOf(rxBytes, newLength); rxPackets = Arrays.copyOf(rxPackets, newLength); @@ -307,6 +334,7 @@ public class NetworkStats implements Parcelable { uid[size] = entry.uid; set[size] = entry.set; tag[size] = entry.tag; + metered[size] = entry.metered; roaming[size] = entry.roaming; rxBytes[size] = entry.rxBytes; rxPackets[size] = entry.rxPackets; @@ -327,6 +355,7 @@ public class NetworkStats implements Parcelable { entry.uid = uid[i]; entry.set = set[i]; entry.tag = tag[i]; + entry.metered = metered[i]; entry.roaming = roaming[i]; entry.rxBytes = rxBytes[i]; entry.rxPackets = rxPackets[i]; @@ -381,7 +410,8 @@ public class NetworkStats implements Parcelable { * also be used to subtract values from existing rows. */ public NetworkStats combineValues(Entry entry) { - final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.roaming); + final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.metered, + entry.roaming); if (i == -1) { // only create new entry when positive contribution addValues(entry); @@ -409,10 +439,11 @@ public class NetworkStats implements Parcelable { /** * Find first stats index that matches the requested parameters. */ - public int findIndex(String iface, int uid, int set, int tag, int roaming) { + public int findIndex(String iface, int uid, int set, int tag, int metered, int roaming) { for (int i = 0; i < size; i++) { if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] - && roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) { + && metered == this.metered[i] && roaming == this.roaming[i] + && Objects.equals(iface, this.iface[i])) { return i; } } @@ -424,7 +455,7 @@ public class NetworkStats implements Parcelable { * search around the hinted index as an optimization. */ @VisibleForTesting - public int findIndexHinted(String iface, int uid, int set, int tag, int roaming, + public int findIndexHinted(String iface, int uid, int set, int tag, int metered, int roaming, int hintIndex) { for (int offset = 0; offset < size; offset++) { final int halfOffset = offset / 2; @@ -438,7 +469,8 @@ public class NetworkStats implements Parcelable { } if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] - && roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) { + && metered == this.metered[i] && roaming == this.roaming[i] + && Objects.equals(iface, this.iface[i])) { return i; } } @@ -452,7 +484,7 @@ public class NetworkStats implements Parcelable { */ public void spliceOperationsFrom(NetworkStats stats) { for (int i = 0; i < size; i++) { - final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], roaming[i]); + final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], metered[i], roaming[i]); if (j == -1) { operations[i] = 0; } else { @@ -542,6 +574,7 @@ public class NetworkStats implements Parcelable { entry.uid = limitUid; entry.set = SET_ALL; entry.tag = TAG_NONE; + entry.metered = METERED_ALL; entry.roaming = ROAMING_ALL; entry.rxBytes = 0; entry.rxPackets = 0; @@ -637,11 +670,12 @@ public class NetworkStats implements Parcelable { entry.uid = left.uid[i]; entry.set = left.set[i]; entry.tag = left.tag[i]; + entry.metered = left.metered[i]; entry.roaming = left.roaming[i]; // find remote row that matches, and subtract final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, - entry.roaming, i); + entry.metered, entry.roaming, i); if (j == -1) { // newly appearing row, return entire value entry.rxBytes = left.rxBytes[i]; @@ -687,6 +721,7 @@ public class NetworkStats implements Parcelable { entry.uid = UID_ALL; entry.set = SET_ALL; entry.tag = TAG_NONE; + entry.metered = METERED_ALL; entry.roaming = ROAMING_ALL; entry.operations = 0L; @@ -716,6 +751,7 @@ public class NetworkStats implements Parcelable { entry.iface = IFACE_ALL; entry.set = SET_ALL; entry.tag = TAG_NONE; + entry.metered = METERED_ALL; entry.roaming = ROAMING_ALL; for (int i = 0; i < size; i++) { @@ -762,6 +798,7 @@ public class NetworkStats implements Parcelable { pw.print(" uid="); pw.print(uid[i]); pw.print(" set="); pw.print(setToString(set[i])); pw.print(" tag="); pw.print(tagToString(tag[i])); + pw.print(" metered="); pw.print(meteredToString(metered[i])); pw.print(" roaming="); pw.print(roamingToString(roaming[i])); pw.print(" rxBytes="); pw.print(rxBytes[i]); pw.print(" rxPackets="); pw.print(rxPackets[i]); @@ -830,6 +867,22 @@ public class NetworkStats implements Parcelable { } /** + * Return text description of {@link #metered} value. + */ + public static String meteredToString(int metered) { + switch (metered) { + case METERED_ALL: + return "ALL"; + case METERED_NO: + return "NO"; + case METERED_YES: + return "YES"; + default: + return "UNKNOWN"; + } + } + + /** * Return text description of {@link #roaming} value. */ public static String roamingToString(int roaming) { @@ -998,6 +1051,7 @@ public class NetworkStats implements Parcelable { tmpEntry.uid = uid[i]; tmpEntry.tag = tag[i]; tmpEntry.set = set[i]; + tmpEntry.metered = metered[i]; tmpEntry.roaming = roaming[i]; combineValues(tmpEntry); if (tag[i] == TAG_NONE) { @@ -1017,24 +1071,25 @@ public class NetworkStats implements Parcelable { moved.set = SET_DBG_VPN_OUT; moved.tag = TAG_NONE; moved.iface = underlyingIface; + moved.metered = METERED_ALL; moved.roaming = ROAMING_ALL; combineValues(moved); // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than // the TAG_NONE traffic. // - // Relies on the fact that the underlying traffic only has state ROAMING_NO, which - // should be the case as it comes directly from the /proc file. We only blend in the + // Relies on the fact that the underlying traffic only has state ROAMING_NO and METERED_NO, + // which should be the case as it comes directly from the /proc file. We only blend in the // roaming data after applying these adjustments, by checking the NetworkIdentity of the // underlying iface. int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, - ROAMING_NO); + METERED_NO, ROAMING_NO); if (idxVpnBackground != -1) { tunSubtract(idxVpnBackground, this, moved); } int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, - ROAMING_NO); + METERED_NO, ROAMING_NO); if (idxVpnForeground != -1) { tunSubtract(idxVpnForeground, this, moved); } diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java index cf9243f7e7a3..cea56b53d763 100644 --- a/core/java/android/net/SntpClient.java +++ b/core/java/android/net/SntpClient.java @@ -36,8 +36,7 @@ import java.util.Arrays; * } * </pre> */ -public class SntpClient -{ +public class SntpClient { private static final String TAG = "SntpClient"; private static final boolean DBG = true; @@ -88,6 +87,7 @@ public class SntpClient try { address = InetAddress.getByName(host); } catch (Exception e) { + EventLogTags.writeNtpFailure(host, e.toString()); if (DBG) Log.d(TAG, "request time failed: " + e); return false; } @@ -142,6 +142,7 @@ public class SntpClient // = (transit + skew - transit + skew)/2 // = (2 * skew)/2 = skew long clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime))/2; + EventLogTags.writeNtpSuccess(address.toString(), roundTripTime, clockOffset); if (DBG) { Log.d(TAG, "round trip: " + roundTripTime + "ms, " + "clock offset: " + clockOffset + "ms"); @@ -153,6 +154,7 @@ public class SntpClient mNtpTimeReference = responseTicks; mRoundTripTime = roundTripTime; } catch (Exception e) { + EventLogTags.writeNtpFailure(address.toString(), e.toString()); if (DBG) Log.d(TAG, "request time failed: " + e); return false; } finally { diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java index 86bd5028266b..33d12a3a3fb8 100644 --- a/core/java/android/net/nsd/NsdManager.java +++ b/core/java/android/net/nsd/NsdManager.java @@ -103,11 +103,11 @@ import com.android.internal.util.Protocol; * to {@link DiscoveryListener#onServiceFound} and a service lost is notified on * {@link DiscoveryListener#onServiceLost}. * - * <p> Once the peer application discovers the "Example" http srevice, and needs to receive data - * from the "Example" application, it can initiate a resolve with {@link #resolveService} to - * resolve the host and port details for the purpose of establishing a connection. A successful - * resolve is notified on {@link ResolveListener#onServiceResolved} and a failure is notified - * on {@link ResolveListener#onResolveFailed}. + * <p> Once the peer application discovers the "Example" http service, and either needs to read the + * attributes of the service or wants to receive data from the "Example" application, it can + * initiate a resolve with {@link #resolveService} to resolve the attributes, host, and port + * details. A successful resolve is notified on {@link ResolveListener#onServiceResolved} and a + * failure is notified on {@link ResolveListener#onResolveFailed}. * * Applications can reserve for a service type at * http://www.iana.org/form/ports-service. Existing services can be found at diff --git a/core/java/android/net/nsd/NsdServiceInfo.java b/core/java/android/net/nsd/NsdServiceInfo.java index 4a06fb1220a7..7b845be74921 100644 --- a/core/java/android/net/nsd/NsdServiceInfo.java +++ b/core/java/android/net/nsd/NsdServiceInfo.java @@ -250,7 +250,8 @@ public final class NsdServiceInfo implements Parcelable { } /** - * Retrive attributes as a map of String keys to byte[] values. + * Retrieve attributes as a map of String keys to byte[] values. The attributes map is only + * valid for a resolved service. * * <p> The returned map is unmodifiable; changes must be made through {@link #setAttribute} and * {@link #removeAttribute}. |
