summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2017-01-18 10:29:51 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-01-18 10:29:57 +0000
commit5db17efcf60dfabec46cf1cd774a331b934fd21d (patch)
tree98c6166e903225f798e2bacd981abbf6c56e70e2 /core/java/android
parentfc9c93c2ddc5a1324122f44b09880fae3cbb934d (diff)
parent7a61361724aeba9de7d809bef7d0b0ea113cc6d1 (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.java50
-rw-r--r--core/java/android/app/usage/NetworkStatsManager.java43
-rw-r--r--core/java/android/net/ConnectivityManager.java133
-rw-r--r--core/java/android/net/ConnectivityThread.java23
-rw-r--r--core/java/android/net/EventLogTags.logtags6
-rw-r--r--core/java/android/net/NetworkIdentity.java6
-rw-r--r--core/java/android/net/NetworkStats.java103
-rw-r--r--core/java/android/net/SntpClient.java6
-rw-r--r--core/java/android/net/nsd/NsdManager.java10
-rw-r--r--core/java/android/net/nsd/NsdServiceInfo.java3
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}.