Merge changes from topic 'framework-net-aosp'
* changes: DO NOT MERGE: frameworks-test: adding missing @SmallTest DO NOT MERGE: Netd events: record connect() success/errno 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: NetworkMonitor: send one DNS probe per web probe DO NOT MERGE: NetworkMonitor metrics: add first validation information DO NOT MERGE: APF: also drop any ICMPv6 RSs 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: VPN network stat accounting changes. 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.
This commit is contained in:
@@ -45,6 +45,7 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/app/admin/SecurityLogTags.logtags \
|
||||
core/java/android/content/EventLogTags.logtags \
|
||||
core/java/android/speech/tts/EventLogTags.logtags \
|
||||
core/java/android/net/EventLogTags.logtags \
|
||||
core/java/android/webkit/EventLogTags.logtags \
|
||||
core/java/com/android/internal/logging/EventLogTags.logtags \
|
||||
|
||||
|
||||
12
]
Normal file
12
]
Normal file
@@ -0,0 +1,12 @@
|
||||
NetworkNotificationManager: logging improvements
|
||||
|
||||
TODO: squash me
|
||||
# Please enter the commit message for your changes. Lines starting
|
||||
# with '#' will be ignored, and an empty message aborts the commit.
|
||||
# On branch notification_tagging
|
||||
# Your branch is ahead of 'goog/master' by 2 commits.
|
||||
# (use "git push" to publish your local commits)
|
||||
#
|
||||
# Changes to be committed:
|
||||
# modified: services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
|
||||
#
|
||||
@@ -6447,6 +6447,7 @@ package android.app.usage {
|
||||
public static class NetworkStats.Bucket {
|
||||
ctor public NetworkStats.Bucket();
|
||||
method public long getEndTimeStamp();
|
||||
method public int getMetered();
|
||||
method public int getRoaming();
|
||||
method public long getRxBytes();
|
||||
method public long getRxPackets();
|
||||
@@ -6456,6 +6457,9 @@ package android.app.usage {
|
||||
method public long getTxBytes();
|
||||
method public long getTxPackets();
|
||||
method public int getUid();
|
||||
field public static final int METERED_ALL = -1; // 0xffffffff
|
||||
field public static final int METERED_NO = 1; // 0x1
|
||||
field public static final int METERED_YES = 2; // 0x2
|
||||
field public static final int ROAMING_ALL = -1; // 0xffffffff
|
||||
field public static final int ROAMING_NO = 1; // 0x1
|
||||
field public static final int ROAMING_YES = 2; // 0x2
|
||||
|
||||
@@ -6739,6 +6739,7 @@ package android.app.usage {
|
||||
public static class NetworkStats.Bucket {
|
||||
ctor public NetworkStats.Bucket();
|
||||
method public long getEndTimeStamp();
|
||||
method public int getMetered();
|
||||
method public int getRoaming();
|
||||
method public long getRxBytes();
|
||||
method public long getRxPackets();
|
||||
@@ -6748,6 +6749,9 @@ package android.app.usage {
|
||||
method public long getTxBytes();
|
||||
method public long getTxPackets();
|
||||
method public int getUid();
|
||||
field public static final int METERED_ALL = -1; // 0xffffffff
|
||||
field public static final int METERED_NO = 1; // 0x1
|
||||
field public static final int METERED_YES = 2; // 0x2
|
||||
field public static final int ROAMING_ALL = -1; // 0xffffffff
|
||||
field public static final int ROAMING_NO = 1; // 0x1
|
||||
field public static final int ROAMING_YES = 2; // 0x2
|
||||
|
||||
@@ -6456,6 +6456,7 @@ package android.app.usage {
|
||||
public static class NetworkStats.Bucket {
|
||||
ctor public NetworkStats.Bucket();
|
||||
method public long getEndTimeStamp();
|
||||
method public int getMetered();
|
||||
method public int getRoaming();
|
||||
method public long getRxBytes();
|
||||
method public long getRxPackets();
|
||||
@@ -6465,6 +6466,9 @@ package android.app.usage {
|
||||
method public long getTxBytes();
|
||||
method public long getTxPackets();
|
||||
method public int getUid();
|
||||
field public static final int METERED_ALL = -1; // 0xffffffff
|
||||
field public static final int METERED_NO = 1; // 0x1
|
||||
field public static final int METERED_YES = 2; // 0x2
|
||||
field public static final int ROAMING_ALL = -1; // 0xffffffff
|
||||
field public static final int ROAMING_NO = 1; // 0x1
|
||||
field public static final int ROAMING_YES = 2; // 0x2
|
||||
|
||||
@@ -163,6 +163,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)
|
||||
@@ -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;
|
||||
@@ -278,6 +311,21 @@ public final class NetworkStats implements AutoCloseable {
|
||||
return mState;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
@@ -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 +
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2079,6 +2079,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) {
|
||||
@@ -2089,6 +2091,7 @@ public class ConnectivityManager {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
mService.startTethering(type, wrappedCallback, showProvisioningUi);
|
||||
} catch (RemoteException e) {
|
||||
@@ -2657,6 +2660,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 */
|
||||
@@ -2687,24 +2691,17 @@ public class ConnectivityManager {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -2747,9 +2744,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;
|
||||
@@ -2757,9 +2752,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;
|
||||
@@ -2779,24 +2772,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: {
|
||||
@@ -2806,14 +2791,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");
|
||||
@@ -2822,63 +2807,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 timeoutMs, 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), timeoutMs, 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
6
core/java/android/net/EventLogTags.logtags
Normal file
6
core/java/android/net/EventLogTags.logtags
Normal file
@@ -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)
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -100,6 +108,12 @@ public class NetworkStats implements Parcelable {
|
||||
public int uid;
|
||||
public int set;
|
||||
public int tag;
|
||||
/**
|
||||
* 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 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
|
||||
@@ -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]);
|
||||
@@ -829,6 +866,22 @@ public class NetworkStats implements Parcelable {
|
||||
return "0x" + Integer.toHexString(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@@ -904,7 +957,8 @@ public class NetworkStats implements Parcelable {
|
||||
if (pool.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
Entry moved = addTrafficToApplications(tunIface, underlyingIface, tunIfaceTotal, pool);
|
||||
Entry moved =
|
||||
addTrafficToApplications(tunUid, tunIface, underlyingIface, tunIfaceTotal, pool);
|
||||
deductTrafficFromVpnApp(tunUid, underlyingIface, moved);
|
||||
|
||||
if (!moved.isEmpty()) {
|
||||
@@ -919,9 +973,9 @@ public class NetworkStats implements Parcelable {
|
||||
* Initializes the data used by the migrateTun() method.
|
||||
*
|
||||
* This is the first pass iteration which does the following work:
|
||||
* (1) Adds up all the traffic through tun0.
|
||||
* (2) Adds up all the traffic through the tunUid's underlyingIface
|
||||
* (1) Adds up all the traffic through the tunUid's underlyingIface
|
||||
* (both foreground and background).
|
||||
* (2) Adds up all the traffic through tun0 excluding traffic from the vpn app itself.
|
||||
*/
|
||||
private void tunAdjustmentInit(int tunUid, String tunIface, String underlyingIface,
|
||||
Entry tunIfaceTotal, Entry underlyingIfaceTotal) {
|
||||
@@ -941,8 +995,9 @@ public class NetworkStats implements Parcelable {
|
||||
underlyingIfaceTotal.add(recycle);
|
||||
}
|
||||
|
||||
if (recycle.tag == TAG_NONE && Objects.equals(tunIface, recycle.iface)) {
|
||||
// Add up all tunIface traffic.
|
||||
if (recycle.uid != tunUid && recycle.tag == TAG_NONE
|
||||
&& Objects.equals(tunIface, recycle.iface)) {
|
||||
// Add up all tunIface traffic excluding traffic from the vpn app itself.
|
||||
tunIfaceTotal.add(recycle);
|
||||
}
|
||||
}
|
||||
@@ -958,13 +1013,15 @@ public class NetworkStats implements Parcelable {
|
||||
return pool;
|
||||
}
|
||||
|
||||
private Entry addTrafficToApplications(String tunIface, String underlyingIface,
|
||||
private Entry addTrafficToApplications(int tunUid, String tunIface, String underlyingIface,
|
||||
Entry tunIfaceTotal, Entry pool) {
|
||||
Entry moved = new Entry();
|
||||
Entry tmpEntry = new Entry();
|
||||
tmpEntry.iface = underlyingIface;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (Objects.equals(iface[i], tunIface)) {
|
||||
// the vpn app is excluded from the redistribution but all moved traffic will be
|
||||
// deducted from the vpn app (see deductTrafficFromVpnApp below).
|
||||
if (Objects.equals(iface[i], tunIface) && uid[i] != tunUid) {
|
||||
if (tunIfaceTotal.rxBytes > 0) {
|
||||
tmpEntry.rxBytes = pool.rxBytes * rxBytes[i] / tunIfaceTotal.rxBytes;
|
||||
} else {
|
||||
@@ -994,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) {
|
||||
@@ -1013,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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -41,6 +41,15 @@ public final class NetworkEvent implements Parcelable {
|
||||
public static final int NETWORK_UNLINGER = 6;
|
||||
public static final int NETWORK_DISCONNECTED = 7;
|
||||
|
||||
/** {@hide} */
|
||||
public static final int NETWORK_FIRST_VALIDATION_SUCCESS = 8;
|
||||
/** {@hide} */
|
||||
public static final int NETWORK_REVALIDATION_SUCCESS = 9;
|
||||
/** {@hide} */
|
||||
public static final int NETWORK_FIRST_VALIDATION_PORTAL_FOUND = 10;
|
||||
/** {@hide} */
|
||||
public static final int NETWORK_REVALIDATION_PORTAL_FOUND = 11;
|
||||
|
||||
/** {@hide} */
|
||||
@IntDef(value = {
|
||||
NETWORK_CONNECTED,
|
||||
@@ -50,6 +59,10 @@ public final class NetworkEvent implements Parcelable {
|
||||
NETWORK_LINGER,
|
||||
NETWORK_UNLINGER,
|
||||
NETWORK_DISCONNECTED,
|
||||
NETWORK_FIRST_VALIDATION_SUCCESS,
|
||||
NETWORK_REVALIDATION_SUCCESS,
|
||||
NETWORK_FIRST_VALIDATION_PORTAL_FOUND,
|
||||
NETWORK_REVALIDATION_PORTAL_FOUND,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface EventType {}
|
||||
|
||||
@@ -44,10 +44,8 @@ public final class ValidationProbeEvent implements Parcelable {
|
||||
public static final int DNS_FAILURE = 0;
|
||||
public static final int DNS_SUCCESS = 1;
|
||||
|
||||
/** {@hide} */
|
||||
@IntDef(value = {PROBE_DNS, PROBE_HTTP, PROBE_HTTPS, PROBE_PAC})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ProbeType {}
|
||||
private static final int FIRST_VALIDATION = 1 << 8;
|
||||
private static final int REVALIDATION = 2 << 8;
|
||||
|
||||
/** {@hide} */
|
||||
@IntDef(value = {DNS_FAILURE, DNS_SUCCESS})
|
||||
@@ -56,12 +54,17 @@ public final class ValidationProbeEvent implements Parcelable {
|
||||
|
||||
public final int netId;
|
||||
public final long durationMs;
|
||||
public final @ProbeType int probeType;
|
||||
// probeType byte format (MSB to LSB):
|
||||
// byte 0: unused
|
||||
// byte 1: unused
|
||||
// byte 2: 0 = UNKNOWN, 1 = FIRST_VALIDATION, 2 = REVALIDATION
|
||||
// byte 3: PROBE_* constant
|
||||
public final int probeType;
|
||||
public final @ReturnCode int returnCode;
|
||||
|
||||
/** {@hide} */
|
||||
public ValidationProbeEvent(
|
||||
int netId, long durationMs, @ProbeType int probeType, @ReturnCode int returnCode) {
|
||||
int netId, long durationMs, int probeType, @ReturnCode int returnCode) {
|
||||
this.netId = netId;
|
||||
this.durationMs = durationMs;
|
||||
this.probeType = probeType;
|
||||
@@ -99,9 +102,19 @@ public final class ValidationProbeEvent implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
/** @hide */
|
||||
public static int makeProbeType(int probeType, boolean firstValidation) {
|
||||
return (probeType & 0xff) | (firstValidation ? FIRST_VALIDATION : REVALIDATION);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static String getProbeName(int probeType) {
|
||||
return Decoder.constants.get(probeType, "PROBE_???");
|
||||
return Decoder.constants.get(probeType & 0xff, "PROBE_???");
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static String getValidationStage(int probeType) {
|
||||
return Decoder.constants.get(probeType & 0xff00, "UNKNOWN");
|
||||
}
|
||||
|
||||
public static void logEvent(int netId, long durationMs, int probeType, int returnCode) {
|
||||
@@ -109,12 +122,13 @@ public final class ValidationProbeEvent implements Parcelable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("ValidationProbeEvent(%d, %s:%d, %dms)",
|
||||
netId, getProbeName(probeType), returnCode, durationMs);
|
||||
return String.format("ValidationProbeEvent(%d, %s:%d %s, %dms)", netId,
|
||||
getProbeName(probeType), returnCode, getValidationStage(probeType), durationMs);
|
||||
}
|
||||
|
||||
final static class Decoder {
|
||||
static final SparseArray<String> constants = MessageUtils.findMessageNames(
|
||||
new Class[]{ValidationProbeEvent.class}, new String[]{"PROBE_"});
|
||||
new Class[]{ValidationProbeEvent.class},
|
||||
new String[]{"PROBE_", "FIRST_", "REVALIDATION"});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}.
|
||||
|
||||
@@ -43,6 +43,7 @@ static struct {
|
||||
jfieldID uid;
|
||||
jfieldID set;
|
||||
jfieldID tag;
|
||||
jfieldID metered;
|
||||
jfieldID roaming;
|
||||
jfieldID rxBytes;
|
||||
jfieldID rxPackets;
|
||||
@@ -239,6 +240,9 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
|
||||
ScopedIntArrayRW tag(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.tag, size, grow));
|
||||
if (tag.get() == NULL) return -1;
|
||||
ScopedIntArrayRW metered(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.metered, size, grow));
|
||||
if (metered.get() == NULL) return -1;
|
||||
ScopedIntArrayRW roaming(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.roaming, size, grow));
|
||||
if (roaming.get() == NULL) return -1;
|
||||
@@ -265,7 +269,7 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
|
||||
uid[i] = lines[i].uid;
|
||||
set[i] = lines[i].set;
|
||||
tag[i] = lines[i].tag;
|
||||
// Roaming is populated in Java-land by inspecting the iface properties.
|
||||
// Metered and Roaming are populated in Java-land by inspecting the iface properties.
|
||||
rxBytes[i] = lines[i].rxBytes;
|
||||
rxPackets[i] = lines[i].rxPackets;
|
||||
txBytes[i] = lines[i].txBytes;
|
||||
@@ -279,6 +283,7 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
|
||||
env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
|
||||
env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
|
||||
env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
|
||||
env->SetObjectField(stats, gNetworkStatsClassInfo.metered, metered.getJavaArray());
|
||||
env->SetObjectField(stats, gNetworkStatsClassInfo.roaming, roaming.getJavaArray());
|
||||
env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
|
||||
env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
|
||||
@@ -311,6 +316,7 @@ int register_com_android_internal_net_NetworkStatsFactory(JNIEnv* env) {
|
||||
gNetworkStatsClassInfo.uid = GetFieldIDOrDie(env, clazz, "uid", "[I");
|
||||
gNetworkStatsClassInfo.set = GetFieldIDOrDie(env, clazz, "set", "[I");
|
||||
gNetworkStatsClassInfo.tag = GetFieldIDOrDie(env, clazz, "tag", "[I");
|
||||
gNetworkStatsClassInfo.metered = GetFieldIDOrDie(env, clazz, "metered", "[I");
|
||||
gNetworkStatsClassInfo.roaming = GetFieldIDOrDie(env, clazz, "roaming", "[I");
|
||||
gNetworkStatsClassInfo.rxBytes = GetFieldIDOrDie(env, clazz, "rxBytes", "[J");
|
||||
gNetworkStatsClassInfo.rxPackets = GetFieldIDOrDie(env, clazz, "rxPackets", "[J");
|
||||
|
||||
@@ -1681,7 +1681,7 @@
|
||||
<bool name="config_actionMenuItemAllCaps">true</bool>
|
||||
|
||||
<!-- Remote server that can provide NTP responses. -->
|
||||
<string translatable="false" name="config_ntpServer">2.android.pool.ntp.org</string>
|
||||
<string translatable="false" name="config_ntpServer">time.android.com</string>
|
||||
<!-- Normal polling frequency in milliseconds -->
|
||||
<integer name="config_ntpPollingInterval">86400000</integer>
|
||||
<!-- Try-again polling interval in milliseconds, in case the network request failed -->
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import static android.net.NetworkStats.METERED_ALL;
|
||||
import static android.net.NetworkStats.METERED_NO;
|
||||
import static android.net.NetworkStats.METERED_YES;
|
||||
import static android.net.NetworkStats.ROAMING_ALL;
|
||||
import static android.net.NetworkStats.ROAMING_NO;
|
||||
import static android.net.NetworkStats.ROAMING_YES;
|
||||
@@ -45,103 +48,124 @@ public class NetworkStatsTest extends TestCase {
|
||||
private static final long TEST_START = 1194220800000L;
|
||||
|
||||
public void testFindIndex() throws Exception {
|
||||
final NetworkStats stats = new NetworkStats(TEST_START, 4)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, 0L,
|
||||
0L, 10)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 1024L,
|
||||
8L, 11)
|
||||
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
|
||||
1024L, 8L, 12)
|
||||
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES, 1024L, 8L,
|
||||
1024L, 8L, 12);
|
||||
final NetworkStats stats = new NetworkStats(TEST_START, 5)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
|
||||
8L, 0L, 0L, 10)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
|
||||
1024L, 8L, 11)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 0L, 0L,
|
||||
1024L, 8L, 11)
|
||||
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
|
||||
8L, 1024L, 8L, 12)
|
||||
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 1024L,
|
||||
8L, 1024L, 8L, 12);
|
||||
|
||||
assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES));
|
||||
assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO));
|
||||
assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO));
|
||||
assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO));
|
||||
assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, ROAMING_NO));
|
||||
assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES,
|
||||
ROAMING_YES));
|
||||
assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO));
|
||||
assertEquals(2, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES,
|
||||
ROAMING_NO));
|
||||
assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO));
|
||||
assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO));
|
||||
assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO));
|
||||
}
|
||||
|
||||
public void testFindIndexHinted() {
|
||||
final NetworkStats stats = new NetworkStats(TEST_START, 3)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, 0L,
|
||||
0L, 10)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 1024L,
|
||||
8L, 11)
|
||||
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
|
||||
1024L, 8L, 12)
|
||||
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 1024L, 8L,
|
||||
0L, 0L, 10)
|
||||
.addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 0L, 0L, 1024L,
|
||||
8L, 11)
|
||||
.addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
|
||||
1024L, 8L, 12)
|
||||
.addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES, 1024L, 8L,
|
||||
1024L, 8L, 12);
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
|
||||
8L, 0L, 0L, 10)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
|
||||
1024L, 8L, 11)
|
||||
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
|
||||
8L, 1024L, 8L, 12)
|
||||
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
1024L, 8L, 0L, 0L, 10)
|
||||
.addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 0L, 0L,
|
||||
1024L, 8L, 11)
|
||||
.addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, 0L, 0L,
|
||||
1024L, 8L, 11)
|
||||
.addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
|
||||
8L, 1024L, 8L, 12)
|
||||
.addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 1024L,
|
||||
8L, 1024L, 8L, 12);
|
||||
|
||||
// verify that we correctly find across regardless of hinting
|
||||
for (int hint = 0; hint < stats.size(); hint++) {
|
||||
assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE,
|
||||
ROAMING_NO, hint));
|
||||
METERED_NO, ROAMING_NO, hint));
|
||||
assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE,
|
||||
ROAMING_NO, hint));
|
||||
METERED_NO, ROAMING_NO, hint));
|
||||
assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE,
|
||||
ROAMING_NO, hint));
|
||||
METERED_NO, ROAMING_NO, hint));
|
||||
assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE,
|
||||
ROAMING_NO, hint));
|
||||
METERED_NO, ROAMING_NO, hint));
|
||||
assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D,
|
||||
ROAMING_NO, hint));
|
||||
assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
|
||||
ROAMING_NO, hint));
|
||||
METERED_NO, ROAMING_NO, hint));
|
||||
assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D,
|
||||
METERED_YES, ROAMING_NO, hint));
|
||||
assertEquals(6, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
|
||||
ROAMING_YES, hint));
|
||||
METERED_NO, ROAMING_NO, hint));
|
||||
assertEquals(7, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
|
||||
METERED_YES, ROAMING_YES, hint));
|
||||
assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE,
|
||||
ROAMING_NO, hint));
|
||||
METERED_NO, ROAMING_NO, hint));
|
||||
}
|
||||
}
|
||||
|
||||
public void testAddEntryGrow() throws Exception {
|
||||
final NetworkStats stats = new NetworkStats(TEST_START, 3);
|
||||
final NetworkStats stats = new NetworkStats(TEST_START, 4);
|
||||
|
||||
assertEquals(0, stats.size());
|
||||
assertEquals(3, stats.internalSize());
|
||||
assertEquals(4, stats.internalSize());
|
||||
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L, 2L,
|
||||
2L, 3);
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2L, 2L, 2L,
|
||||
2L, 4);
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 3L, 3L, 2L,
|
||||
2L, 5);
|
||||
|
||||
assertEquals(3, stats.size());
|
||||
assertEquals(3, stats.internalSize());
|
||||
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 4L, 40L, 4L,
|
||||
40L, 7);
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 5L, 50L, 4L,
|
||||
40L, 8);
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 6L, 60L, 5L,
|
||||
50L, 10);
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 7L, 70L, 5L,
|
||||
50L, 11);
|
||||
|
||||
assertEquals(7, stats.size());
|
||||
assertTrue(stats.internalSize() >= 7);
|
||||
|
||||
assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L,
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1L, 1L,
|
||||
2L, 2L, 3);
|
||||
assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2L, 2L,
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 2L, 2L,
|
||||
2L, 2L, 4);
|
||||
assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 3L, 3L,
|
||||
2L, 2L, 5);
|
||||
assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 4L,
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 3L,
|
||||
3L, 2L, 2L, 5);
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 3L,
|
||||
3L, 2L, 2L, 5);
|
||||
|
||||
assertEquals(4, stats.size());
|
||||
assertEquals(4, stats.internalSize());
|
||||
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 4L,
|
||||
40L, 4L, 40L, 7);
|
||||
assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 5L,
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 5L,
|
||||
50L, 4L, 40L, 8);
|
||||
assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 6L,
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 6L,
|
||||
60L, 5L, 50L, 10);
|
||||
assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 7L,
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 7L,
|
||||
70L, 5L, 50L, 11);
|
||||
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 7L,
|
||||
70L, 5L, 50L, 11);
|
||||
|
||||
assertEquals(9, stats.size());
|
||||
assertTrue(stats.internalSize() >= 9);
|
||||
|
||||
assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
1L, 1L, 2L, 2L, 3);
|
||||
assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
2L, 2L, 2L, 2L, 4);
|
||||
assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
|
||||
3L, 3L, 2L, 2L, 5);
|
||||
assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES,
|
||||
ROAMING_YES, 3L, 3L, 2L, 2L, 5);
|
||||
assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
4L, 40L, 4L, 40L, 7);
|
||||
assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
5L, 50L, 4L, 40L, 8);
|
||||
assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
6L, 60L, 5L, 50L, 10);
|
||||
assertValues(stats, 7, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
|
||||
7L, 70L, 5L, 50L, 11);
|
||||
assertValues(stats, 8, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES,
|
||||
ROAMING_YES, 7L, 70L, 5L, 50L, 11);
|
||||
}
|
||||
|
||||
public void testCombineExisting() throws Exception {
|
||||
@@ -152,20 +176,18 @@ public class NetworkStatsTest extends TestCase {
|
||||
stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L,
|
||||
-128L, -1L, -1);
|
||||
|
||||
assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, ROAMING_NO, 384L, 3L,
|
||||
128L, 1L, 9);
|
||||
assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, ROAMING_NO, 128L, 1L, 128L,
|
||||
1L, 2);
|
||||
assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
384L, 3L, 128L, 1L, 9);
|
||||
assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, METERED_NO, ROAMING_NO, 128L,
|
||||
1L, 128L, 1L, 2);
|
||||
|
||||
// now try combining that should create row
|
||||
stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L,
|
||||
128L, 1L, 3);
|
||||
assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 1L,
|
||||
128L, 1L, 3);
|
||||
stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L,
|
||||
128L, 1L, 3);
|
||||
assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_NO, 256L, 2L,
|
||||
256L, 2L, 6);
|
||||
stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
|
||||
assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
128L, 1L, 128L, 1L, 3);
|
||||
stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
|
||||
assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
256L, 2L, 256L, 2L, 6);
|
||||
}
|
||||
|
||||
public void testSubtractIdenticalData() throws Exception {
|
||||
@@ -180,10 +202,10 @@ public class NetworkStatsTest extends TestCase {
|
||||
final NetworkStats result = after.subtract(before);
|
||||
|
||||
// identical data should result in zero delta
|
||||
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
|
||||
0L, 0);
|
||||
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
|
||||
0L, 0);
|
||||
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
|
||||
0L, 0L, 0L, 0);
|
||||
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
|
||||
0L, 0L, 0L, 0);
|
||||
}
|
||||
|
||||
public void testSubtractIdenticalRows() throws Exception {
|
||||
@@ -198,10 +220,10 @@ public class NetworkStatsTest extends TestCase {
|
||||
final NetworkStats result = after.subtract(before);
|
||||
|
||||
// expect delta between measurements
|
||||
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L, 2L,
|
||||
1L, 4);
|
||||
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 3L, 1L, 4L,
|
||||
1L, 8);
|
||||
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1L,
|
||||
1L, 2L, 1L, 4);
|
||||
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 3L,
|
||||
1L, 4L, 1L, 8);
|
||||
}
|
||||
|
||||
public void testSubtractNewRows() throws Exception {
|
||||
@@ -217,12 +239,12 @@ public class NetworkStatsTest extends TestCase {
|
||||
final NetworkStats result = after.subtract(before);
|
||||
|
||||
// its okay to have new rows
|
||||
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
|
||||
0L, 0);
|
||||
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
|
||||
0L, 0);
|
||||
assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
|
||||
1024L, 8L, 20);
|
||||
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
|
||||
0L, 0L, 0L, 0);
|
||||
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
|
||||
0L, 0L, 0L, 0);
|
||||
assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
1024L, 8L, 1024L, 8L, 20);
|
||||
}
|
||||
|
||||
public void testSubtractMissingRows() throws Exception {
|
||||
@@ -237,8 +259,8 @@ public class NetworkStatsTest extends TestCase {
|
||||
|
||||
// should silently drop omitted rows
|
||||
assertEquals(1, result.size());
|
||||
assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L,
|
||||
2L, 3L, 4L, 0);
|
||||
assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 1L, 2L, 3L, 4L, 0);
|
||||
assertEquals(4L, result.getTotalBytes());
|
||||
}
|
||||
|
||||
@@ -263,13 +285,22 @@ public class NetworkStatsTest extends TestCase {
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
|
||||
assertEquals(64L, uidTag.getTotalBytes());
|
||||
|
||||
final NetworkStats uidMetered = new NetworkStats(TEST_START, 3)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L, 0L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
|
||||
0L, 0L, 0L);
|
||||
assertEquals(96L, uidMetered.getTotalBytes());
|
||||
|
||||
final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
|
||||
0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
|
||||
0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_YES, 32L, 0L, 0L, 0L,
|
||||
0L);
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L, 0L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 32L, 0L,
|
||||
0L, 0L, 0L);
|
||||
assertEquals(96L, uidRoaming.getTotalBytes());
|
||||
}
|
||||
|
||||
@@ -283,95 +314,95 @@ public class NetworkStatsTest extends TestCase {
|
||||
|
||||
public void testGroupedByIfaceAll() throws Exception {
|
||||
final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
|
||||
.addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, ROAMING_NO, 128L, 8L, 0L, 2L,
|
||||
20L)
|
||||
.addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
|
||||
.addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L, 0L,
|
||||
2L, 20L)
|
||||
.addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, ROAMING_YES, 128L, 8L, 0L, 2L,
|
||||
20L);
|
||||
.addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, 128L,
|
||||
8L, 0L, 2L, 20L)
|
||||
.addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES, 128L, 8L, 0L,
|
||||
2L, 20L);
|
||||
final NetworkStats grouped = uidStats.groupedByIface();
|
||||
|
||||
assertEquals(3, uidStats.size());
|
||||
assertEquals(1, grouped.size());
|
||||
|
||||
assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 384L, 24L, 0L,
|
||||
6L, 0L);
|
||||
assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
|
||||
384L, 24L, 0L, 6L, 0L);
|
||||
}
|
||||
|
||||
public void testGroupedByIface() throws Exception {
|
||||
final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
|
||||
2L, 20L)
|
||||
.addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 512L, 32L, 0L,
|
||||
0L, 0L)
|
||||
.addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 4L, 0L, 0L,
|
||||
0L)
|
||||
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 512L, 32L,
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
|
||||
0L, 2L, 20L)
|
||||
.addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
|
||||
32L, 0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L, 4L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
|
||||
0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, 0L,
|
||||
0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 8L, 0L,
|
||||
0L, 0L);
|
||||
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
|
||||
32L, 0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, 128L, 8L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 128L,
|
||||
8L, 0L, 0L, 0L);
|
||||
|
||||
final NetworkStats grouped = uidStats.groupedByIface();
|
||||
|
||||
assertEquals(7, uidStats.size());
|
||||
|
||||
assertEquals(2, grouped.size());
|
||||
assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 384L, 24L, 0L,
|
||||
2L, 0L);
|
||||
assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 1024L, 64L,
|
||||
0L, 0L, 0L);
|
||||
assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
|
||||
384L, 24L, 0L, 2L, 0L);
|
||||
assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
|
||||
1024L, 64L, 0L, 0L, 0L);
|
||||
}
|
||||
|
||||
public void testAddAllValues() {
|
||||
final NetworkStats first = new NetworkStats(TEST_START, 5)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
|
||||
0L)
|
||||
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 0L, 0L,
|
||||
0L, 0L)
|
||||
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 32L, 0L, 0L,
|
||||
0L, 0L);
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 32L,
|
||||
0L, 0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, 32L,
|
||||
0L, 0L, 0L, 0L);
|
||||
|
||||
final NetworkStats second = new NetworkStats(TEST_START, 2)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
|
||||
0L)
|
||||
.addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L,
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 32L, 0L, 0L,
|
||||
0L, 0L);
|
||||
.addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L,
|
||||
0L, 0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, 32L,
|
||||
0L, 0L, 0L, 0L);
|
||||
|
||||
first.combineAllValues(second);
|
||||
|
||||
assertEquals(4, first.size());
|
||||
assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 64L, 0L, 0L,
|
||||
0L, 0L);
|
||||
assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 0L,
|
||||
0L, 0L, 0L);
|
||||
assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 64L, 0L,
|
||||
0L, 0L, 0L);
|
||||
assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L,
|
||||
assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 64L,
|
||||
0L, 0L, 0L, 0L);
|
||||
assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
32L, 0L, 0L, 0L, 0L);
|
||||
assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
|
||||
64L, 0L, 0L, 0L, 0L);
|
||||
assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
32L, 0L, 0L, 0L, 0L);
|
||||
}
|
||||
|
||||
public void testGetTotal() {
|
||||
final NetworkStats stats = new NetworkStats(TEST_START, 7)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
|
||||
2L, 20L)
|
||||
.addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 512L, 32L, 0L,
|
||||
0L, 0L)
|
||||
.addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 4L, 0L, 0L,
|
||||
0L)
|
||||
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 512L, 32L,
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
|
||||
0L, 2L, 20L)
|
||||
.addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
|
||||
32L, 0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L, 4L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
|
||||
0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, 0L,
|
||||
0L)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 8L, 0L,
|
||||
0L, 0L);
|
||||
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
|
||||
32L, 0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 128L,
|
||||
8L, 0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 128L, 8L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 128L,
|
||||
8L, 0L, 0L, 0L);
|
||||
|
||||
assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L);
|
||||
assertValues(stats.getTotal(null, 100), 1280L, 80L, 0L, 2L, 20L);
|
||||
@@ -396,10 +427,10 @@ public class NetworkStatsTest extends TestCase {
|
||||
final NetworkStats after = before.withoutUids(new int[] { 100 });
|
||||
assertEquals(6, before.size());
|
||||
assertEquals(2, after.size());
|
||||
assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L,
|
||||
0L, 0L, 0L);
|
||||
assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L,
|
||||
0L, 0L);
|
||||
assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
128L, 8L, 0L, 0L, 0L);
|
||||
assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 128L,
|
||||
8L, 0L, 0L, 0L);
|
||||
}
|
||||
|
||||
public void testClone() throws Exception {
|
||||
@@ -434,105 +465,175 @@ public class NetworkStatsTest extends TestCase {
|
||||
final String underlyingIface = "wlan0";
|
||||
final int testTag1 = 8888;
|
||||
NetworkStats delta = new NetworkStats(TEST_START, 17)
|
||||
.addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, 39605L, 46L, 12259L, 55L, 0L)
|
||||
.addValues(tunIface, 10100, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L)
|
||||
.addValues(tunIface, 10120, SET_DEFAULT, TAG_NONE, 72667L, 197L, 43909L, 241L, 0L)
|
||||
.addValues(tunIface, 10120, SET_FOREGROUND, TAG_NONE, 9297L, 17L, 4128L, 21L, 0L)
|
||||
.addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 39605L, 46L,
|
||||
12259L, 55L, 0L)
|
||||
.addValues(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
|
||||
0L, 0L, 0L)
|
||||
.addValues(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 72667L, 197L,
|
||||
43909L, 241L, 0L)
|
||||
.addValues(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 9297L,
|
||||
17L, 4128L, 21L, 0L)
|
||||
// VPN package also uses some traffic through unprotected network.
|
||||
.addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, 4983L, 10L, 1801L, 12L, 0L)
|
||||
.addValues(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L)
|
||||
.addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 4983L, 10L,
|
||||
1801L, 12L, 0L)
|
||||
.addValues(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
|
||||
0L, 0L, 0L)
|
||||
// Tag entries
|
||||
.addValues(tunIface, 10120, SET_DEFAULT, testTag1, 21691L, 41L, 13820L, 51L, 0L)
|
||||
.addValues(tunIface, 10120, SET_FOREGROUND, testTag1, 1281L, 2L, 665L, 2L, 0L)
|
||||
.addValues(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, 21691L, 41L,
|
||||
13820L, 51L, 0L)
|
||||
.addValues(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, 1281L, 2L,
|
||||
665L, 2L, 0L)
|
||||
// Irrelevant entries
|
||||
.addValues(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, 1685L, 5L, 2070L, 6L, 0L)
|
||||
.addValues(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1685L, 5L,
|
||||
2070L, 6L, 0L)
|
||||
// Underlying Iface entries
|
||||
.addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, 5178L, 8L, 2139L, 11L, 0L)
|
||||
.addValues(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L)
|
||||
.addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, 149873L, 287L,
|
||||
59217L /* smaller than sum(tun0) */, 299L /* smaller than sum(tun0) */, 0L)
|
||||
.addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
|
||||
.addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 5178L,
|
||||
8L, 2139L, 11L, 0L)
|
||||
.addValues(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
|
||||
0L, 0L, 0L, 0L)
|
||||
.addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
149873L, 287L, 59217L /* smaller than sum(tun0) */,
|
||||
299L /* smaller than sum(tun0) */, 0L)
|
||||
.addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
0L, 0L, 0L, 0L, 0L);
|
||||
|
||||
assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
|
||||
assertEquals(21, delta.size());
|
||||
assertEquals(20, delta.size());
|
||||
|
||||
// tunIface and TEST_IFACE entries are not changed.
|
||||
assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
39605L, 46L, 12259L, 55L, 0L);
|
||||
assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 0L, 0L,
|
||||
0L, 0L, 0L);
|
||||
assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
0L, 0L, 0L, 0L, 0L);
|
||||
assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
72667L, 197L, 43909L, 241L, 0L);
|
||||
assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
|
||||
assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
9297L, 17L, 4128L, 21L, 0L);
|
||||
assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
4983L, 10L, 1801L, 12L, 0L);
|
||||
assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 0L, 0L,
|
||||
0L, 0L, 0L);
|
||||
assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, ROAMING_NO,
|
||||
assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
0L, 0L, 0L, 0L, 0L);
|
||||
assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
|
||||
21691L, 41L, 13820L, 51L, 0L);
|
||||
assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, ROAMING_NO, 1281L,
|
||||
2L, 665L, 2L, 0L);
|
||||
assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1685L, 5L,
|
||||
2070L, 6L, 0L);
|
||||
assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
|
||||
1281L, 2L, 665L, 2L, 0L);
|
||||
assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
1685L, 5L, 2070L, 6L, 0L);
|
||||
|
||||
// Existing underlying Iface entries are updated
|
||||
assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
44783L, 54L, 13829L, 60L, 0L);
|
||||
assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
|
||||
0L, 0L, 0L, 0L, 0L);
|
||||
assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 44783L, 54L, 14178L, 62L, 0L);
|
||||
assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 0L, 0L, 0L, 0L, 0L);
|
||||
|
||||
// VPN underlying Iface entries are updated
|
||||
assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
28304L, 27L, 1719L, 12L, 0L);
|
||||
assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
|
||||
0L, 0L, 0L, 0L, 0L);
|
||||
assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 28304L, 27L, 1L, 2L, 0L);
|
||||
assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 0L, 0L, 0L, 0L, 0L);
|
||||
|
||||
// New entries are added for new application's underlying Iface traffic
|
||||
assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
72667L, 197L, 41872L, 219L, 0L);
|
||||
assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
|
||||
9297L, 17L, 3936, 19L, 0L);
|
||||
assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, ROAMING_NO,
|
||||
21691L, 41L, 13179L, 46L, 0L);
|
||||
assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, ROAMING_NO,
|
||||
1281L, 2L, 634L, 1L, 0L);
|
||||
assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 72667L, 197L, 43123L, 227L, 0L);
|
||||
assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 9297L, 17L, 4054, 19L, 0L);
|
||||
assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, METERED_NO,
|
||||
ROAMING_NO, 21691L, 41L, 13572L, 48L, 0L);
|
||||
assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, METERED_NO,
|
||||
ROAMING_NO, 1281L, 2L, 653L, 1L, 0L);
|
||||
|
||||
// New entries are added for debug purpose
|
||||
assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
|
||||
39605L, 46L, 11690, 49, 0);
|
||||
assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
|
||||
81964, 214, 45808, 238, 0);
|
||||
assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
|
||||
4983, 10, 1717, 10, 0);
|
||||
assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, ROAMING_ALL,
|
||||
126552, 270, 59215, 297, 0);
|
||||
assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 39605L, 46L, 12039, 51, 0);
|
||||
assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 81964, 214, 47177, 246, 0);
|
||||
assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, METERED_ALL,
|
||||
ROAMING_ALL, 121569, 260, 59216, 297, 0);
|
||||
|
||||
}
|
||||
|
||||
// Tests a case where all of the data received by the tun0 interface is echo back into the tun0
|
||||
// interface by the vpn app before it's sent out of the underlying interface. The VPN app should
|
||||
// not be charged for the echoed data but it should still be charged for any extra data it sends
|
||||
// via the underlying interface.
|
||||
public void testMigrateTun_VpnAsLoopback() {
|
||||
final int tunUid = 10030;
|
||||
final String tunIface = "tun0";
|
||||
final String underlyingIface = "wlan0";
|
||||
NetworkStats delta = new NetworkStats(TEST_START, 9)
|
||||
// 2 different apps sent/receive data via tun0.
|
||||
.addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 50000L, 25L,
|
||||
100000L, 50L, 0L)
|
||||
.addValues(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 500L, 2L,
|
||||
200L, 5L, 0L)
|
||||
// VPN package resends data through the tunnel (with exaggerated overhead)
|
||||
.addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 240000,
|
||||
100L, 120000L, 60L, 0L)
|
||||
// 1 app already has some traffic on the underlying interface, the other doesn't yet
|
||||
.addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1000L,
|
||||
10L, 2000L, 20L, 0L)
|
||||
// Traffic through the underlying interface via the vpn app.
|
||||
// This test should redistribute this data correctly.
|
||||
.addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
75500L, 37L, 130000L, 70L, 0L);
|
||||
|
||||
assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
|
||||
assertEquals(9, delta.size());
|
||||
|
||||
// tunIface entries should not be changed.
|
||||
assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
50000L, 25L, 100000L, 50L, 0L);
|
||||
assertValues(delta, 1, tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
500L, 2L, 200L, 5L, 0L);
|
||||
assertValues(delta, 2, tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
240000L, 100L, 120000L, 60L, 0L);
|
||||
|
||||
// Existing underlying Iface entries are updated
|
||||
assertValues(delta, 3, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 51000L, 35L, 102000L, 70L, 0L);
|
||||
|
||||
// VPN underlying Iface entries are updated
|
||||
assertValues(delta, 4, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 25000L, 10L, 29800L, 15L, 0L);
|
||||
|
||||
// New entries are added for new application's underlying Iface traffic
|
||||
assertContains(delta, underlyingIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 500L, 2L, 200L, 5L, 0L);
|
||||
|
||||
// New entries are added for debug purpose
|
||||
assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 50000L, 25L, 100000L, 50L, 0L);
|
||||
assertContains(delta, underlyingIface, 20100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, 500, 2L, 200L, 5L, 0L);
|
||||
assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, METERED_ALL,
|
||||
ROAMING_ALL, 50500L, 27L, 100200L, 55, 0);
|
||||
}
|
||||
|
||||
private static void assertContains(NetworkStats stats, String iface, int uid, int set,
|
||||
int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
|
||||
long operations) {
|
||||
int index = stats.findIndex(iface, uid, set, tag, roaming);
|
||||
int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes,
|
||||
long txPackets, long operations) {
|
||||
int index = stats.findIndex(iface, uid, set, tag, metered, roaming);
|
||||
assertTrue(index != -1);
|
||||
assertValues(stats, index, iface, uid, set, tag, roaming,
|
||||
assertValues(stats, index, iface, uid, set, tag, metered, roaming,
|
||||
rxBytes, rxPackets, txBytes, txPackets, operations);
|
||||
}
|
||||
|
||||
private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
|
||||
int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
|
||||
long operations) {
|
||||
int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes,
|
||||
long txPackets, long operations) {
|
||||
final NetworkStats.Entry entry = stats.getValues(index, null);
|
||||
assertValues(entry, iface, uid, set, tag, roaming);
|
||||
assertValues(entry, iface, uid, set, tag, metered, roaming);
|
||||
assertValues(entry, rxBytes, rxPackets, txBytes, txPackets, operations);
|
||||
}
|
||||
|
||||
private static void assertValues(
|
||||
NetworkStats.Entry entry, String iface, int uid, int set, int tag, int roaming) {
|
||||
NetworkStats.Entry entry, String iface, int uid, int set, int tag, int metered,
|
||||
int roaming) {
|
||||
assertEquals(iface, entry.iface);
|
||||
assertEquals(uid, entry.uid);
|
||||
assertEquals(set, entry.set);
|
||||
assertEquals(tag, entry.tag);
|
||||
assertEquals(metered, entry.metered);
|
||||
assertEquals(roaming, entry.roaming);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.internal.net;
|
||||
|
||||
import static android.net.NetworkStats.METERED_NO;
|
||||
import static android.net.NetworkStats.ROAMING_NO;
|
||||
import static android.net.NetworkStats.SET_ALL;
|
||||
import static android.net.NetworkStats.SET_DEFAULT;
|
||||
@@ -101,12 +102,14 @@ public class NetworkStatsFactoryTest extends AndroidTestCase {
|
||||
|
||||
final NetworkStats stats = mFactory.readNetworkStatsDetail();
|
||||
assertEquals(70, stats.size());
|
||||
assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L, 676L);
|
||||
assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L,
|
||||
676L);
|
||||
assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L);
|
||||
}
|
||||
|
||||
public void testNetworkStatsSingle() throws Exception {
|
||||
stageFile(R.raw.xt_qtaguid_iface_typical, new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
|
||||
stageFile(R.raw.xt_qtaguid_iface_typical,
|
||||
new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
|
||||
|
||||
final NetworkStats stats = mFactory.readNetworkStatsSummaryDev();
|
||||
assertEquals(6, stats.size());
|
||||
@@ -122,7 +125,8 @@ public class NetworkStatsFactoryTest extends AndroidTestCase {
|
||||
final NetworkStats stats = mFactory.readNetworkStatsSummaryXt();
|
||||
assertEquals(3, stats.size());
|
||||
assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 6824L, 16L, 5692L, 10L);
|
||||
assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L, 2468L);
|
||||
assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L,
|
||||
2468L);
|
||||
assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
|
||||
}
|
||||
|
||||
@@ -157,7 +161,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase {
|
||||
|
||||
private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
|
||||
int tag, long rxBytes, long txBytes) {
|
||||
final int i = stats.findIndex(iface, uid, set, tag, ROAMING_NO);
|
||||
final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
|
||||
final NetworkStats.Entry entry = stats.getValues(i, null);
|
||||
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
|
||||
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
|
||||
@@ -165,7 +169,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase {
|
||||
|
||||
private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
|
||||
int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
|
||||
final int i = stats.findIndex(iface, uid, set, tag, ROAMING_NO);
|
||||
final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
|
||||
final NetworkStats.Entry entry = stats.getValues(i, null);
|
||||
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
|
||||
assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.net.NetworkRequest;
|
||||
import android.net.metrics.DnsEvent;
|
||||
import android.net.metrics.INetdEventListener;
|
||||
import android.net.metrics.IpConnectivityLog;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -44,7 +45,7 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
||||
public static final String SERVICE_NAME = "netd_listener";
|
||||
|
||||
private static final String TAG = NetdEventListenerService.class.getSimpleName();
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean DBG = false;
|
||||
private static final boolean VDBG = false;
|
||||
|
||||
// TODO: read this constant from system property
|
||||
@@ -86,7 +87,7 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
||||
byte[] returnCodes = Arrays.copyOf(mReturnCodes, mEventCount);
|
||||
int[] latenciesMs = Arrays.copyOf(mLatenciesMs, mEventCount);
|
||||
mMetricsLog.log(new DnsEvent(mNetId, eventTypes, returnCodes, latenciesMs));
|
||||
maybeLog(String.format("Logging %d results for netId %d", mEventCount, mNetId));
|
||||
maybeLog("Logging %d results for netId %d", mEventCount, mNetId);
|
||||
mEventCount = 0;
|
||||
}
|
||||
|
||||
@@ -136,9 +137,9 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
||||
// Called concurrently by multiple binder threads.
|
||||
// This method must not block or perform long-running operations.
|
||||
public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
|
||||
String hostname, String[] ipAddresses, int ipAddressesCount, int uid) {
|
||||
maybeVerboseLog(String.format("onDnsEvent(%d, %d, %d, %d)",
|
||||
netId, eventType, returnCode, latencyMs));
|
||||
String hostname, String[] ipAddresses, int ipAddressesCount, int uid)
|
||||
throws RemoteException {
|
||||
maybeVerboseLog("onDnsEvent(%d, %d, %d, %dms)", netId, eventType, returnCode, latencyMs);
|
||||
|
||||
DnsEventBatch batch = mEventBatches.get(netId);
|
||||
if (batch == null) {
|
||||
@@ -151,9 +152,9 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
||||
@Override
|
||||
// Called concurrently by multiple binder threads.
|
||||
// This method must not block or perform long-running operations.
|
||||
public synchronized void onConnectEvent(int netId, int latencyMs, String ipAddr, int port,
|
||||
int uid) {
|
||||
maybeVerboseLog(String.format("onConnectEvent(%d, %d)", netId, latencyMs));
|
||||
public synchronized void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port,
|
||||
int uid) throws RemoteException {
|
||||
maybeVerboseLog("onConnectEvent(%d, %d, %dms)", netId, error, latencyMs);
|
||||
}
|
||||
|
||||
public synchronized void dump(PrintWriter writer) {
|
||||
@@ -166,11 +167,11 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
|
||||
private static void maybeLog(String s) {
|
||||
if (DBG) Log.d(TAG, s);
|
||||
private static void maybeLog(String s, Object... args) {
|
||||
if (DBG) Log.d(TAG, String.format(s, args));
|
||||
}
|
||||
|
||||
private static void maybeVerboseLog(String s) {
|
||||
if (VDBG) Log.d(TAG, s);
|
||||
private static void maybeVerboseLog(String s, Object... args) {
|
||||
if (VDBG) Log.d(TAG, String.format(s, args));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,24 @@ public class NetworkMonitor extends StateMachine {
|
||||
private static final int SOCKET_TIMEOUT_MS = 10000;
|
||||
private static final int PROBE_TIMEOUT_MS = 3000;
|
||||
|
||||
static enum EvaluationResult {
|
||||
VALIDATED(true),
|
||||
CAPTIVE_PORTAL(false);
|
||||
final boolean isValidated;
|
||||
EvaluationResult(boolean isValidated) {
|
||||
this.isValidated = isValidated;
|
||||
}
|
||||
}
|
||||
|
||||
static enum ValidationStage {
|
||||
FIRST_VALIDATION(true),
|
||||
REVALIDATION(false);
|
||||
final boolean isFirstValidation;
|
||||
ValidationStage(boolean isFirstValidation) {
|
||||
this.isFirstValidation = isFirstValidation;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String ACTION_NETWORK_CONDITIONS_MEASURED =
|
||||
"android.net.conn.NETWORK_CONDITIONS_MEASURED";
|
||||
public static final String EXTRA_CONNECTIVITY_TYPE = "extra_connectivity_type";
|
||||
@@ -215,6 +233,8 @@ public class NetworkMonitor extends StateMachine {
|
||||
protected boolean mIsCaptivePortalCheckEnabled;
|
||||
|
||||
private boolean mUseHttps;
|
||||
// The total number of captive portal detection attempts for this NetworkMonitor instance.
|
||||
private int mValidations = 0;
|
||||
|
||||
// Set if the user explicitly selected "Do not use this network" in captive portal sign-in app.
|
||||
private boolean mUserDoesNotWant = false;
|
||||
@@ -289,6 +309,10 @@ public class NetworkMonitor extends StateMachine {
|
||||
return validationLogs.readOnlyLocalLog();
|
||||
}
|
||||
|
||||
private ValidationStage validationStage() {
|
||||
return 0 == mValidations ? ValidationStage.FIRST_VALIDATION : ValidationStage.REVALIDATION;
|
||||
}
|
||||
|
||||
// DefaultState is the parent of all States. It exists only to handle CMD_* messages but
|
||||
// does not entail any real state (hence no enter() or exit() routines).
|
||||
private class DefaultState extends State {
|
||||
@@ -365,9 +389,11 @@ public class NetworkMonitor extends StateMachine {
|
||||
private class ValidatedState extends State {
|
||||
@Override
|
||||
public void enter() {
|
||||
maybeLogEvaluationResult(NetworkEvent.NETWORK_VALIDATED);
|
||||
maybeLogEvaluationResult(
|
||||
networkEventType(validationStage(), EvaluationResult.VALIDATED));
|
||||
mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
|
||||
NETWORK_TEST_RESULT_VALID, mNetworkAgentInfo.network.netId, null));
|
||||
mValidations++;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -583,7 +609,8 @@ public class NetworkMonitor extends StateMachine {
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
maybeLogEvaluationResult(NetworkEvent.NETWORK_CAPTIVE_PORTAL_FOUND);
|
||||
maybeLogEvaluationResult(
|
||||
networkEventType(validationStage(), EvaluationResult.CAPTIVE_PORTAL));
|
||||
// Don't annoy user with sign-in notifications.
|
||||
if (mDontDisplaySigninNotification) return;
|
||||
// Create a CustomIntentReceiver that sends us a
|
||||
@@ -603,6 +630,7 @@ public class NetworkMonitor extends StateMachine {
|
||||
// Retest for captive portal occasionally.
|
||||
sendMessageDelayed(CMD_CAPTIVE_PORTAL_RECHECK, 0 /* no UID */,
|
||||
CAPTIVE_PORTAL_REEVALUATE_DELAY_MS);
|
||||
mValidations++;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -678,48 +706,13 @@ public class NetworkMonitor extends StateMachine {
|
||||
|
||||
long startTime = SystemClock.elapsedRealtime();
|
||||
|
||||
// Pre-resolve the captive portal server host so we can log it.
|
||||
// Only do this if HttpURLConnection is about to, to avoid any potentially
|
||||
// unnecessary resolution.
|
||||
String hostToResolve = null;
|
||||
final CaptivePortalProbeResult result;
|
||||
if (pacUrl != null) {
|
||||
hostToResolve = pacUrl.getHost();
|
||||
} else if (proxyInfo != null) {
|
||||
hostToResolve = proxyInfo.getHost();
|
||||
} else {
|
||||
hostToResolve = httpUrl.getHost();
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(hostToResolve)) {
|
||||
String probeName = ValidationProbeEvent.getProbeName(ValidationProbeEvent.PROBE_DNS);
|
||||
final Stopwatch dnsTimer = new Stopwatch().start();
|
||||
int dnsResult;
|
||||
long dnsLatency;
|
||||
try {
|
||||
InetAddress[] addresses = mNetworkAgentInfo.network.getAllByName(hostToResolve);
|
||||
dnsResult = ValidationProbeEvent.DNS_SUCCESS;
|
||||
dnsLatency = dnsTimer.stop();
|
||||
final StringBuffer connectInfo = new StringBuffer(", " + hostToResolve + "=");
|
||||
for (InetAddress address : addresses) {
|
||||
connectInfo.append(address.getHostAddress());
|
||||
if (address != addresses[addresses.length-1]) connectInfo.append(",");
|
||||
}
|
||||
validationLog(probeName + " OK " + dnsLatency + "ms" + connectInfo);
|
||||
} catch (UnknownHostException e) {
|
||||
dnsResult = ValidationProbeEvent.DNS_FAILURE;
|
||||
dnsLatency = dnsTimer.stop();
|
||||
validationLog(probeName + " FAIL " + dnsLatency + "ms, " + hostToResolve);
|
||||
}
|
||||
logValidationProbe(dnsLatency, ValidationProbeEvent.PROBE_DNS, dnsResult);
|
||||
}
|
||||
|
||||
CaptivePortalProbeResult result;
|
||||
if (pacUrl != null) {
|
||||
result = sendHttpProbe(pacUrl, ValidationProbeEvent.PROBE_PAC);
|
||||
result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
|
||||
} else if (mUseHttps) {
|
||||
result = sendParallelHttpProbes(httpsUrl, httpUrl, fallbackUrl);
|
||||
result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl, fallbackUrl);
|
||||
} else {
|
||||
result = sendHttpProbe(httpUrl, ValidationProbeEvent.PROBE_HTTP);
|
||||
result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
|
||||
}
|
||||
|
||||
long endTime = SystemClock.elapsedRealtime();
|
||||
@@ -732,8 +725,50 @@ public class NetworkMonitor extends StateMachine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a URL fetch on a known server to see if we get the data we expect.
|
||||
* Returns HTTP response code.
|
||||
* Do a DNS resolution and URL fetch on a known web server to see if we get the data we expect.
|
||||
* @return a CaptivePortalProbeResult inferred from the HTTP response.
|
||||
*/
|
||||
private CaptivePortalProbeResult sendDnsAndHttpProbes(ProxyInfo proxy, URL url, int probeType) {
|
||||
// Pre-resolve the captive portal server host so we can log it.
|
||||
// Only do this if HttpURLConnection is about to, to avoid any potentially
|
||||
// unnecessary resolution.
|
||||
final String host = (proxy != null) ? proxy.getHost() : url.getHost();
|
||||
sendDnsProbe(host);
|
||||
return sendHttpProbe(url, probeType);
|
||||
}
|
||||
|
||||
/** Do a DNS resolution of the given server. */
|
||||
private void sendDnsProbe(String host) {
|
||||
if (TextUtils.isEmpty(host)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String name = ValidationProbeEvent.getProbeName(ValidationProbeEvent.PROBE_DNS);
|
||||
final Stopwatch watch = new Stopwatch().start();
|
||||
int result;
|
||||
String connectInfo;
|
||||
try {
|
||||
InetAddress[] addresses = mNetworkAgentInfo.network.getAllByName(host);
|
||||
result = ValidationProbeEvent.DNS_SUCCESS;
|
||||
StringBuffer buffer = new StringBuffer(host).append("=");
|
||||
for (InetAddress address : addresses) {
|
||||
buffer.append(address.getHostAddress());
|
||||
if (address != addresses[addresses.length-1]) buffer.append(",");
|
||||
}
|
||||
connectInfo = buffer.toString();
|
||||
} catch (UnknownHostException e) {
|
||||
result = ValidationProbeEvent.DNS_FAILURE;
|
||||
connectInfo = host;
|
||||
}
|
||||
final long latency = watch.stop();
|
||||
String resultString = (ValidationProbeEvent.DNS_SUCCESS == result) ? "OK" : "FAIL";
|
||||
validationLog(String.format("%s %s %dms, %s", name, resultString, latency, connectInfo));
|
||||
logValidationProbe(latency, ValidationProbeEvent.PROBE_DNS, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a URL fetch on a known web server to see if we get the data we expect.
|
||||
* @return a CaptivePortalProbeResult inferred from the HTTP response.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected CaptivePortalProbeResult sendHttpProbe(URL url, int probeType) {
|
||||
@@ -800,7 +835,7 @@ public class NetworkMonitor extends StateMachine {
|
||||
}
|
||||
|
||||
private CaptivePortalProbeResult sendParallelHttpProbes(
|
||||
URL httpsUrl, URL httpUrl, URL fallbackUrl) {
|
||||
ProxyInfo proxy, URL httpsUrl, URL httpUrl, URL fallbackUrl) {
|
||||
// Number of probes to wait for. If a probe completes with a conclusive answer
|
||||
// it shortcuts the latch immediately by forcing the count to 0.
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
@@ -820,9 +855,10 @@ public class NetworkMonitor extends StateMachine {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mIsHttps) {
|
||||
mResult = sendHttpProbe(httpsUrl, ValidationProbeEvent.PROBE_HTTPS);
|
||||
mResult =
|
||||
sendDnsAndHttpProbes(proxy, httpsUrl, ValidationProbeEvent.PROBE_HTTPS);
|
||||
} else {
|
||||
mResult = sendHttpProbe(httpUrl, ValidationProbeEvent.PROBE_HTTP);
|
||||
mResult = sendDnsAndHttpProbes(proxy, httpUrl, ValidationProbeEvent.PROBE_HTTP);
|
||||
}
|
||||
if ((mIsHttps && mResult.isSuccessful()) || (!mIsHttps && mResult.isPortal())) {
|
||||
// Stop waiting immediately if https succeeds or if http finds a portal.
|
||||
@@ -973,6 +1009,22 @@ public class NetworkMonitor extends StateMachine {
|
||||
mMetricsLog.log(new NetworkEvent(mNetId, evtype));
|
||||
}
|
||||
|
||||
private int networkEventType(ValidationStage s, EvaluationResult r) {
|
||||
if (s.isFirstValidation) {
|
||||
if (r.isValidated) {
|
||||
return NetworkEvent.NETWORK_FIRST_VALIDATION_SUCCESS;
|
||||
} else {
|
||||
return NetworkEvent.NETWORK_FIRST_VALIDATION_PORTAL_FOUND;
|
||||
}
|
||||
} else {
|
||||
if (r.isValidated) {
|
||||
return NetworkEvent.NETWORK_REVALIDATION_SUCCESS;
|
||||
} else {
|
||||
return NetworkEvent.NETWORK_REVALIDATION_PORTAL_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeLogEvaluationResult(int evtype) {
|
||||
if (mEvaluationTimer.isRunning()) {
|
||||
mMetricsLog.log(new NetworkEvent(mNetId, evtype, mEvaluationTimer.stop()));
|
||||
@@ -981,6 +1033,8 @@ public class NetworkMonitor extends StateMachine {
|
||||
}
|
||||
|
||||
private void logValidationProbe(long durationMs, int probeType, int probeResult) {
|
||||
probeType =
|
||||
ValidationProbeEvent.makeProbeType(probeType, validationStage().isFirstValidation);
|
||||
mMetricsLog.log(new ValidationProbeEvent(mNetId, durationMs, probeType, probeResult));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
@@ -76,6 +78,7 @@ import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.net.LegacyVpnInfo;
|
||||
@@ -241,12 +244,14 @@ public class Vpn {
|
||||
/**
|
||||
* Update current state, dispaching event to listeners.
|
||||
*/
|
||||
private void updateState(DetailedState detailedState, String reason) {
|
||||
@VisibleForTesting
|
||||
protected void updateState(DetailedState detailedState, String reason) {
|
||||
if (LOGD) Log.d(TAG, "setting state=" + detailedState + ", reason=" + reason);
|
||||
mNetworkInfo.setDetailedState(detailedState, reason, null);
|
||||
if (mNetworkAgent != null) {
|
||||
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
|
||||
}
|
||||
updateAlwaysOnNotification(detailedState);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,7 +285,10 @@ public class Vpn {
|
||||
}
|
||||
|
||||
mLockdown = (mAlwaysOn && lockdown);
|
||||
if (!isCurrentPreparedPackage(packageName)) {
|
||||
if (isCurrentPreparedPackage(packageName)) {
|
||||
updateAlwaysOnNotification(mNetworkInfo.getDetailedState());
|
||||
} else {
|
||||
// Prepare this app. The notification will update as a side-effect of updateState().
|
||||
prepareInternal(packageName);
|
||||
}
|
||||
maybeRegisterPackageChangeReceiverLocked(packageName);
|
||||
@@ -682,22 +690,19 @@ public class Vpn {
|
||||
}
|
||||
}
|
||||
|
||||
private void agentDisconnect(NetworkInfo networkInfo, NetworkAgent networkAgent) {
|
||||
networkInfo.setIsAvailable(false);
|
||||
networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
|
||||
private void agentDisconnect(NetworkAgent networkAgent) {
|
||||
if (networkAgent != null) {
|
||||
NetworkInfo networkInfo = new NetworkInfo(mNetworkInfo);
|
||||
networkInfo.setIsAvailable(false);
|
||||
networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
|
||||
networkAgent.sendNetworkInfo(networkInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void agentDisconnect(NetworkAgent networkAgent) {
|
||||
NetworkInfo networkInfo = new NetworkInfo(mNetworkInfo);
|
||||
agentDisconnect(networkInfo, networkAgent);
|
||||
}
|
||||
|
||||
private void agentDisconnect() {
|
||||
if (mNetworkInfo.isConnected()) {
|
||||
agentDisconnect(mNetworkInfo, mNetworkAgent);
|
||||
mNetworkInfo.setIsAvailable(false);
|
||||
updateState(DetailedState.DISCONNECTED, "agentDisconnect");
|
||||
mNetworkAgent = null;
|
||||
}
|
||||
}
|
||||
@@ -1250,6 +1255,43 @@ public class Vpn {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAlwaysOnNotification(DetailedState networkState) {
|
||||
final boolean visible = (mAlwaysOn && networkState != DetailedState.CONNECTED);
|
||||
updateAlwaysOnNotificationInternal(visible);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void updateAlwaysOnNotificationInternal(boolean visible) {
|
||||
final UserHandle user = UserHandle.of(mUserHandle);
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final NotificationManager notificationManager = NotificationManager.from(mContext);
|
||||
if (!visible) {
|
||||
notificationManager.cancelAsUser(TAG, 0, user);
|
||||
return;
|
||||
}
|
||||
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
|
||||
final PendingIntent configIntent = PendingIntent.getActivityAsUser(
|
||||
mContext, /* request */ 0, intent,
|
||||
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
|
||||
null, user);
|
||||
final Notification.Builder builder = new Notification.Builder(mContext)
|
||||
.setDefaults(0)
|
||||
.setSmallIcon(R.drawable.vpn_connected)
|
||||
.setContentTitle(mContext.getString(R.string.vpn_lockdown_disconnected))
|
||||
.setContentText(mContext.getString(R.string.vpn_lockdown_config))
|
||||
.setContentIntent(configIntent)
|
||||
.setCategory(Notification.CATEGORY_SYSTEM)
|
||||
.setPriority(Notification.PRIORITY_LOW)
|
||||
.setVisibility(Notification.VISIBILITY_PUBLIC)
|
||||
.setOngoing(true)
|
||||
.setColor(mContext.getColor(R.color.system_notification_accent_color));
|
||||
notificationManager.notifyAsUser(TAG, 0, builder.build(), user);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
private native int jniCreate(int mtu);
|
||||
private native String jniGetName(int tun);
|
||||
private native int jniSetAddresses(String interfaze, String addresses);
|
||||
|
||||
@@ -91,6 +91,19 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
|
||||
}
|
||||
}
|
||||
|
||||
/** @return whether any {@link NetworkIdentity} in this set is considered metered. */
|
||||
public boolean isAnyMemberMetered() {
|
||||
if (isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (NetworkIdentity ident : this) {
|
||||
if (ident.getMetered()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @return whether any {@link NetworkIdentity} in this set is considered roaming. */
|
||||
public boolean isAnyMemberRoaming() {
|
||||
if (isEmpty()) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.android.server.net;
|
||||
|
||||
import static android.net.NetworkStats.IFACE_ALL;
|
||||
import static android.net.NetworkStats.METERED_NO;
|
||||
import static android.net.NetworkStats.METERED_YES;
|
||||
import static android.net.NetworkStats.ROAMING_NO;
|
||||
import static android.net.NetworkStats.ROAMING_YES;
|
||||
import static android.net.NetworkStats.SET_ALL;
|
||||
@@ -242,6 +244,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {
|
||||
entry.uid = key.uid;
|
||||
entry.set = key.set;
|
||||
entry.tag = key.tag;
|
||||
entry.metered = key.ident.isAnyMemberMetered() ? METERED_YES : METERED_NO;
|
||||
entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_YES : ROAMING_NO;
|
||||
entry.rxBytes = historyEntry.rxBytes;
|
||||
entry.rxPackets = historyEntry.rxPackets;
|
||||
|
||||
@@ -194,8 +194,10 @@ public class ApfFilter {
|
||||
{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||
|
||||
private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
|
||||
private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;
|
||||
private static final int ICMP6_ROUTER_SOLICITATION = 133;
|
||||
private static final int ICMP6_ROUTER_ADVERTISEMENT = 134;
|
||||
private static final int ICMP6_NEIGHBOR_SOLICITATION = 135;
|
||||
private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;
|
||||
|
||||
// NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
|
||||
private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 2;
|
||||
@@ -805,6 +807,8 @@ public class ApfFilter {
|
||||
// if it's multicast and we're dropping multicast:
|
||||
// drop
|
||||
// pass
|
||||
// if it's ICMPv6 RS to any:
|
||||
// drop
|
||||
// if it's ICMPv6 NA to ff02::1:
|
||||
// drop
|
||||
|
||||
@@ -829,10 +833,12 @@ public class ApfFilter {
|
||||
|
||||
// Add unsolicited multicast neighbor announcements filter
|
||||
String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
|
||||
// If not neighbor announcements, skip unsolicited multicast NA filter
|
||||
gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
|
||||
// Drop all router solicitations (b/32833400)
|
||||
gen.addJumpIfR0Equals(ICMP6_ROUTER_SOLICITATION, gen.DROP_LABEL);
|
||||
// If not neighbor announcements, skip filter.
|
||||
gen.addJumpIfR0NotEquals(ICMP6_NEIGHBOR_ANNOUNCEMENT, skipUnsolicitedMulticastNALabel);
|
||||
// If to ff02::1, drop
|
||||
// If to ff02::1, drop.
|
||||
// TODO: Drop only if they don't contain the address of on-link neighbours.
|
||||
gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
|
||||
gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
|
||||
@@ -852,6 +858,7 @@ public class ApfFilter {
|
||||
* <li>Pass all non-ICMPv6 IPv6 packets,
|
||||
* <li>Pass all non-IPv4 and non-IPv6 packets,
|
||||
* <li>Drop IPv6 ICMPv6 NAs to ff02::1.
|
||||
* <li>Drop IPv6 ICMPv6 RSs.
|
||||
* <li>Let execution continue off the end of the program for IPv6 ICMPv6 packets. This allows
|
||||
* insertion of RA filters here, or if there aren't any, just passes the packets.
|
||||
* </ul>
|
||||
|
||||
@@ -12,12 +12,12 @@ LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
easymocklib \
|
||||
frameworks-base-testutils \
|
||||
services.core \
|
||||
services.devicepolicy \
|
||||
services.net \
|
||||
services.usage \
|
||||
easymocklib \
|
||||
guava \
|
||||
android-support-test \
|
||||
mockito-target \
|
||||
|
||||
@@ -25,6 +25,7 @@ import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static android.net.NetworkStats.SET_DEFAULT;
|
||||
import static android.net.NetworkStats.METERED_NO;
|
||||
import static android.net.NetworkStats.ROAMING_NO;
|
||||
import static android.net.NetworkStats.TAG_NONE;
|
||||
import static android.net.NetworkTemplate.buildTemplateMobileAll;
|
||||
@@ -336,7 +337,7 @@ public class NetworkStatsObserversTest extends TestCase {
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = null;
|
||||
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
@@ -344,7 +345,7 @@ public class NetworkStatsObserversTest extends TestCase {
|
||||
|
||||
// Delta
|
||||
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
@@ -374,7 +375,7 @@ public class NetworkStatsObserversTest extends TestCase {
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = null;
|
||||
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
@@ -382,7 +383,7 @@ public class NetworkStatsObserversTest extends TestCase {
|
||||
|
||||
// Delta
|
||||
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
@@ -412,7 +413,7 @@ public class NetworkStatsObserversTest extends TestCase {
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = null;
|
||||
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
@@ -420,7 +421,7 @@ public class NetworkStatsObserversTest extends TestCase {
|
||||
|
||||
// Delta
|
||||
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
|
||||
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
@@ -450,16 +451,17 @@ public class NetworkStatsObserversTest extends TestCase {
|
||||
// Baseline
|
||||
NetworkStats xtSnapshot = null;
|
||||
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
|
||||
// Delta
|
||||
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
|
||||
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO,
|
||||
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
|
||||
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
|
||||
ROAMING_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES,
|
||||
2L, 0L);
|
||||
mStatsObservers.updateStats(
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@ package android.net;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -49,6 +50,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
|
||||
mLog = new ConnectivityMetricsLogger(mService);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogEvents() throws Exception {
|
||||
mLog.logEvent(1, FAKE_COMPONENT, FAKE_EVENT, FAKE_EV);
|
||||
mLog.logEvent(2, FAKE_COMPONENT, FAKE_EVENT, FAKE_EV);
|
||||
@@ -60,6 +62,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
|
||||
assertEventsEqual(expectedEvent(3), gotEvents.get(2));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogEventTriggerThrottling() throws Exception {
|
||||
when(mService.logEvent(any())).thenReturn(1234L);
|
||||
|
||||
@@ -70,6 +73,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
|
||||
assertEventsEqual(expectedEvent(1), gotEvents.get(0));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogEventFails() throws Exception {
|
||||
when(mService.logEvent(any())).thenReturn(-1L); // Error.
|
||||
|
||||
@@ -80,6 +84,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
|
||||
assertEventsEqual(expectedEvent(1), gotEvents.get(0));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogEventWhenThrottling() throws Exception {
|
||||
when(mService.logEvent(any())).thenReturn(Long.MAX_VALUE); // Throttled
|
||||
|
||||
@@ -92,6 +97,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
|
||||
assertEventsEqual(expectedEvent(1), gotEvents.get(0));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogEventRecoverFromThrottling() throws Exception {
|
||||
final long throttleTimeout = System.currentTimeMillis() + 10;
|
||||
when(mService.logEvent(any())).thenReturn(throttleTimeout, 0L);
|
||||
|
||||
@@ -33,7 +33,6 @@ import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import static android.system.OsConstants.*;
|
||||
|
||||
import com.android.frameworks.tests.net.R;
|
||||
@@ -155,7 +154,7 @@ public class ApfTest extends AndroidTestCase {
|
||||
* generating bytecode for that program and running it through the
|
||||
* interpreter to verify it functions correctly.
|
||||
*/
|
||||
@MediumTest
|
||||
@SmallTest
|
||||
public void testApfInstructions() throws IllegalInstructionException {
|
||||
// Empty program should pass because having the program counter reach the
|
||||
// location immediately after the program indicates the packet should be
|
||||
@@ -563,7 +562,7 @@ public class ApfTest extends AndroidTestCase {
|
||||
* Generate some BPF programs, translate them to APF, then run APF and BPF programs
|
||||
* over packet traces and verify both programs filter out the same packets.
|
||||
*/
|
||||
@MediumTest
|
||||
@SmallTest
|
||||
public void testApfAgainstBpf() throws Exception {
|
||||
String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
|
||||
"arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
|
||||
@@ -662,9 +661,13 @@ public class ApfTest extends AndroidTestCase {
|
||||
// The IPv6 all nodes address ff02::1
|
||||
private static final byte[] IPV6_ALL_NODES_ADDRESS =
|
||||
{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||
private static final byte[] IPV6_ALL_ROUTERS_ADDRESS =
|
||||
{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
|
||||
|
||||
private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
|
||||
private static final int ICMP6_ROUTER_SOLICITATION = 133;
|
||||
private static final int ICMP6_ROUTER_ADVERTISEMENT = 134;
|
||||
private static final int ICMP6_NEIGHBOR_SOLICITATION = 135;
|
||||
private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;
|
||||
|
||||
private static final int ICMP6_RA_HEADER_LEN = 16;
|
||||
@@ -721,7 +724,7 @@ public class ApfTest extends AndroidTestCase {
|
||||
private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2};
|
||||
private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0};
|
||||
|
||||
@MediumTest
|
||||
@SmallTest
|
||||
public void testApfFilterIPv4() throws Exception {
|
||||
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
|
||||
LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
|
||||
@@ -776,7 +779,7 @@ public class ApfTest extends AndroidTestCase {
|
||||
apfFilter.shutdown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@SmallTest
|
||||
public void testApfFilterIPv6() throws Exception {
|
||||
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
|
||||
ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
|
||||
@@ -799,10 +802,16 @@ public class ApfTest extends AndroidTestCase {
|
||||
put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_NODES_ADDRESS);
|
||||
assertDrop(program, packet.array());
|
||||
|
||||
// Verify ICMPv6 RS to any is dropped
|
||||
packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_SOLICITATION);
|
||||
assertDrop(program, packet.array());
|
||||
put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_ROUTERS_ADDRESS);
|
||||
assertDrop(program, packet.array());
|
||||
|
||||
apfFilter.shutdown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@SmallTest
|
||||
public void testApfFilterMulticast() throws Exception {
|
||||
final byte[] unicastIpv4Addr = {(byte)192,0,2,63};
|
||||
final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
|
||||
@@ -912,7 +921,7 @@ public class ApfTest extends AndroidTestCase {
|
||||
assertDrop(program, garpReply());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@SmallTest
|
||||
public void testApfFilterArp() throws Exception {
|
||||
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
|
||||
ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
|
||||
@@ -1031,7 +1040,7 @@ public class ApfTest extends AndroidTestCase {
|
||||
ipManagerCallback.assertNoProgramUpdate();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@SmallTest
|
||||
public void testApfFilterRa() throws Exception {
|
||||
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
|
||||
TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog);
|
||||
|
||||
@@ -473,6 +473,7 @@ public class DhcpPacketTest extends TestCase {
|
||||
assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testTruncatedOfferPackets() throws Exception {
|
||||
final byte[] packet = HexDump.hexStringToByteArray(
|
||||
// IP header.
|
||||
@@ -506,6 +507,7 @@ public class DhcpPacketTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testRandomPackets() throws Exception {
|
||||
final int maxRandomPacketSize = 512;
|
||||
final Random r = new Random();
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.net.netlink.NetlinkConstants;
|
||||
import android.net.netlink.NetlinkErrorMessage;
|
||||
import android.net.netlink.NetlinkMessage;
|
||||
import android.net.netlink.StructNlMsgErr;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Log;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -53,6 +54,7 @@ public class NetlinkErrorMessageTest extends TestCase {
|
||||
public static final byte[] NLM_ERROR_OK =
|
||||
HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false);
|
||||
|
||||
@SmallTest
|
||||
public void testParseNlmErrorOk() {
|
||||
final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK);
|
||||
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.net.netlink.NetlinkSocket;
|
||||
import android.net.netlink.RtNetlinkNeighborMessage;
|
||||
import android.net.netlink.StructNdMsg;
|
||||
import android.net.netlink.StructNlMsgHdr;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.NetlinkSocketAddress;
|
||||
import android.system.OsConstants;
|
||||
@@ -33,6 +34,7 @@ import junit.framework.TestCase;
|
||||
public class NetlinkSocketTest extends TestCase {
|
||||
private final String TAG = "NetlinkSocketTest";
|
||||
|
||||
@SmallTest
|
||||
public void testBasicWorkingGetNeighborsQuery() throws Exception {
|
||||
NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
|
||||
assertNotNull(s);
|
||||
@@ -91,6 +93,7 @@ public class NetlinkSocketTest extends TestCase {
|
||||
s.close();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testRepeatedCloseCallsAreQuiet() throws Exception {
|
||||
// Create a working NetlinkSocket.
|
||||
NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
|
||||
|
||||
@@ -21,12 +21,13 @@ import android.net.netlink.NetlinkMessage;
|
||||
import android.net.netlink.RtNetlinkNeighborMessage;
|
||||
import android.net.netlink.StructNdMsg;
|
||||
import android.net.netlink.StructNlMsgHdr;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.system.OsConstants;
|
||||
import android.util.Log;
|
||||
import libcore.util.HexEncoding;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -135,6 +136,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase {
|
||||
public static final byte[] RTM_GETNEIGH_RESPONSE =
|
||||
HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
|
||||
|
||||
@SmallTest
|
||||
public void testParseRtmDelNeigh() {
|
||||
final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
|
||||
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
|
||||
@@ -161,6 +163,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase {
|
||||
assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testParseRtmNewNeigh() {
|
||||
final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
|
||||
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
|
||||
@@ -187,6 +190,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase {
|
||||
assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testParseRtmGetNeighResponse() {
|
||||
final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
|
||||
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
|
||||
@@ -211,6 +215,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase {
|
||||
assertEquals(14, messageCount);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCreateRtmNewNeighMessage() {
|
||||
final int seqNo = 2635;
|
||||
final int ifIndex = 14;
|
||||
|
||||
@@ -70,7 +70,6 @@ import android.provider.Settings;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.FlakyTest;
|
||||
import android.test.mock.MockContentResolver;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Log;
|
||||
import android.util.LogPrinter;
|
||||
@@ -91,6 +90,7 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConnectivityService}.
|
||||
@@ -195,6 +195,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
// Tests that IdleableHandlerThread works as expected.
|
||||
@SmallTest
|
||||
public void testIdleableHandlerThread() {
|
||||
final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
|
||||
|
||||
@@ -219,6 +220,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@FlakyTest(tolerance = 3)
|
||||
public void testNotWaitingForIdleCausesRaceConditions() {
|
||||
// Bring up a network that we can use to send messages to ConnectivityService.
|
||||
@@ -622,7 +624,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
private class WrappedAvoidBadWifiTracker extends AvoidBadWifiTracker {
|
||||
public boolean configRestrictsAvoidBadWifi;
|
||||
public volatile boolean configRestrictsAvoidBadWifi;
|
||||
|
||||
public WrappedAvoidBadWifiTracker(Context c, Handler h, Runnable r) {
|
||||
super(c, h, r);
|
||||
@@ -839,7 +841,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
return cv;
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testLingering() throws Exception {
|
||||
verifyNoNetwork();
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
@@ -879,7 +881,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
verifyNoNetwork();
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
|
||||
// Test bringing up unvalidated WiFi
|
||||
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
|
||||
@@ -914,7 +916,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
verifyNoNetwork();
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
|
||||
// Test bringing up unvalidated cellular.
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
@@ -940,7 +942,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
verifyNoNetwork();
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testUnlingeringDoesNotValidate() throws Exception {
|
||||
// Test bringing up unvalidated WiFi.
|
||||
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
|
||||
@@ -968,7 +970,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
NET_CAPABILITY_VALIDATED));
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testCellularOutscoresWeakWifi() throws Exception {
|
||||
// Test bringing up validated cellular.
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
@@ -994,7 +996,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
verifyActiveNetwork(TRANSPORT_WIFI);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testReapingNetwork() throws Exception {
|
||||
// Test bringing up WiFi without NET_CAPABILITY_INTERNET.
|
||||
// Expect it to be torn down immediately because it satisfies no requests.
|
||||
@@ -1027,7 +1029,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
waitFor(cv);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testCellularFallback() throws Exception {
|
||||
// Test bringing up validated cellular.
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
@@ -1065,7 +1067,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
verifyActiveNetwork(TRANSPORT_WIFI);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testWiFiFallback() throws Exception {
|
||||
// Test bringing up unvalidated WiFi.
|
||||
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
|
||||
@@ -1192,7 +1194,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testStateChangeNetworkCallbacks() throws Exception {
|
||||
final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
|
||||
final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
|
||||
@@ -1575,7 +1577,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
handlerThread.quit();
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testNetworkFactoryRequests() throws Exception {
|
||||
tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
|
||||
tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
|
||||
@@ -1595,7 +1597,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
// Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testNoMutableNetworkRequests() throws Exception {
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
|
||||
NetworkRequest.Builder builder = new NetworkRequest.Builder();
|
||||
@@ -1620,7 +1622,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
} catch (IllegalArgumentException expected) {}
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testMMSonWiFi() throws Exception {
|
||||
// Test bringing up cellular without MMS NetworkRequest gets reaped
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
@@ -1655,7 +1657,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
verifyActiveNetwork(TRANSPORT_WIFI);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testMMSonCell() throws Exception {
|
||||
// Test bringing up cellular without MMS
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
@@ -1681,7 +1683,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
verifyActiveNetwork(TRANSPORT_CELLULAR);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testCaptivePortal() {
|
||||
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
|
||||
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
|
||||
@@ -1730,7 +1732,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testAvoidOrIgnoreCaptivePortals() {
|
||||
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
|
||||
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
|
||||
@@ -1801,7 +1803,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
execptionCalled);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testRegisterDefaultNetworkCallback() throws Exception {
|
||||
final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
|
||||
mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
|
||||
@@ -1862,7 +1864,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@SmallTest
|
||||
public void testRequestCallbackUpdates() throws Exception {
|
||||
// File a network request for mobile.
|
||||
final TestNetworkCallback cellNetworkCallback = new TestRequestUpdateCallback();
|
||||
@@ -1997,6 +1999,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
|
||||
@SmallTest
|
||||
public void testRequestBenchmark() throws Exception {
|
||||
// TODO: turn this unit test into a real benchmarking test.
|
||||
// Benchmarks connecting and switching performance in the presence of a large number of
|
||||
// NetworkRequests.
|
||||
// 1. File NUM_REQUESTS requests.
|
||||
@@ -2010,61 +2013,80 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS);
|
||||
final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS);
|
||||
|
||||
final int REGISTER_TIME_LIMIT_MS = 100;
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (int i = 0; i < NUM_REQUESTS; i++) {
|
||||
callbacks[i] = new NetworkCallback() {
|
||||
@Override public void onAvailable(Network n) { availableLatch.countDown(); }
|
||||
@Override public void onLosing(Network n, int t) { losingLatch.countDown(); }
|
||||
};
|
||||
mCm.registerNetworkCallback(request, callbacks[i]);
|
||||
}
|
||||
long timeTaken = System.currentTimeMillis() - startTime;
|
||||
String msg = String.format("Register %d callbacks: %dms, acceptable %dms",
|
||||
NUM_REQUESTS, timeTaken, REGISTER_TIME_LIMIT_MS);
|
||||
Log.d(TAG, msg);
|
||||
assertTrue(msg, timeTaken < REGISTER_TIME_LIMIT_MS);
|
||||
|
||||
final int CONNECT_TIME_LIMIT_MS = 30;
|
||||
final int REGISTER_TIME_LIMIT_MS = 180;
|
||||
assertTimeLimit("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> {
|
||||
for (NetworkCallback cb : callbacks) {
|
||||
mCm.registerNetworkCallback(request, cb);
|
||||
}
|
||||
});
|
||||
|
||||
final int CONNECT_TIME_LIMIT_MS = 40;
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
// Don't request that the network validate, because otherwise connect() will block until
|
||||
// the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired,
|
||||
// and we won't actually measure anything.
|
||||
mCellNetworkAgent.connect(false);
|
||||
startTime = System.currentTimeMillis();
|
||||
if (!availableLatch.await(CONNECT_TIME_LIMIT_MS, TimeUnit.MILLISECONDS)) {
|
||||
fail(String.format("Only dispatched %d/%d onAvailable callbacks in %dms",
|
||||
NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS,
|
||||
CONNECT_TIME_LIMIT_MS));
|
||||
}
|
||||
timeTaken = System.currentTimeMillis() - startTime;
|
||||
Log.d(TAG, String.format("Connect, %d callbacks: %dms, acceptable %dms",
|
||||
NUM_REQUESTS, timeTaken, CONNECT_TIME_LIMIT_MS));
|
||||
|
||||
final int SWITCH_TIME_LIMIT_MS = 30;
|
||||
long onAvailableDispatchingDuration = durationOf(() -> {
|
||||
if (!awaitLatch(availableLatch, CONNECT_TIME_LIMIT_MS)) {
|
||||
fail(String.format("Only dispatched %d/%d onAvailable callbacks in %dms",
|
||||
NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS,
|
||||
CONNECT_TIME_LIMIT_MS));
|
||||
}
|
||||
});
|
||||
Log.d(TAG, String.format("Connect, %d callbacks: %dms, acceptable %dms",
|
||||
NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS));
|
||||
|
||||
final int SWITCH_TIME_LIMIT_MS = 40;
|
||||
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
|
||||
// Give wifi a high enough score that we'll linger cell when wifi comes up.
|
||||
mWiFiNetworkAgent.adjustScore(40);
|
||||
mWiFiNetworkAgent.connect(false);
|
||||
startTime = System.currentTimeMillis();
|
||||
if (!losingLatch.await(SWITCH_TIME_LIMIT_MS, TimeUnit.MILLISECONDS)) {
|
||||
fail(String.format("Only dispatched %d/%d onLosing callbacks in %dms",
|
||||
NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, SWITCH_TIME_LIMIT_MS));
|
||||
}
|
||||
timeTaken = System.currentTimeMillis() - startTime;
|
||||
|
||||
long onLostDispatchingDuration = durationOf(() -> {
|
||||
if (!awaitLatch(losingLatch, SWITCH_TIME_LIMIT_MS)) {
|
||||
fail(String.format("Only dispatched %d/%d onLosing callbacks in %dms",
|
||||
NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, SWITCH_TIME_LIMIT_MS));
|
||||
}
|
||||
});
|
||||
Log.d(TAG, String.format("Linger, %d callbacks: %dms, acceptable %dms",
|
||||
NUM_REQUESTS, timeTaken, SWITCH_TIME_LIMIT_MS));
|
||||
NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS));
|
||||
|
||||
final int UNREGISTER_TIME_LIMIT_MS = 10;
|
||||
startTime = System.currentTimeMillis();
|
||||
for (int i = 0; i < NUM_REQUESTS; i++) {
|
||||
mCm.unregisterNetworkCallback(callbacks[i]);
|
||||
}
|
||||
timeTaken = System.currentTimeMillis() - startTime;
|
||||
msg = String.format("Unregister %d callbacks: %dms, acceptable %dms",
|
||||
NUM_REQUESTS, timeTaken, UNREGISTER_TIME_LIMIT_MS);
|
||||
assertTimeLimit("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> {
|
||||
for (NetworkCallback cb : callbacks) {
|
||||
mCm.unregisterNetworkCallback(cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private long durationOf(Runnable fn) {
|
||||
long startTime = SystemClock.elapsedRealtime();
|
||||
fn.run();
|
||||
return SystemClock.elapsedRealtime() - startTime;
|
||||
}
|
||||
|
||||
private void assertTimeLimit(String descr, long timeLimit, Runnable fn) {
|
||||
long timeTaken = durationOf(fn);
|
||||
String msg = String.format("%s: took %dms, limit was %dms", descr, timeTaken, timeLimit);
|
||||
Log.d(TAG, msg);
|
||||
assertTrue(msg, timeTaken < UNREGISTER_TIME_LIMIT_MS);
|
||||
assertTrue(msg, timeTaken <= timeLimit);
|
||||
}
|
||||
|
||||
private boolean awaitLatch(CountDownLatch l, long timeoutMs) {
|
||||
try {
|
||||
if (l.await(timeoutMs, TimeUnit.MILLISECONDS)) {
|
||||
return true;
|
||||
}
|
||||
} catch (InterruptedException e) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@@ -2145,7 +2167,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
tracker.reevaluate();
|
||||
mService.waitForIdle();
|
||||
String msg = String.format("config=false, setting=%s", values[i]);
|
||||
assertTrue(msg, mService.avoidBadWifi());
|
||||
assertEventuallyTrue(() -> mService.avoidBadWifi(), 50);
|
||||
assertFalse(msg, tracker.shouldNotifyWifiUnvalidated());
|
||||
}
|
||||
|
||||
@@ -2154,19 +2176,19 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
Settings.Global.putInt(cr, settingName, 0);
|
||||
tracker.reevaluate();
|
||||
mService.waitForIdle();
|
||||
assertFalse(mService.avoidBadWifi());
|
||||
assertEventuallyTrue(() -> !mService.avoidBadWifi(), 50);
|
||||
assertFalse(tracker.shouldNotifyWifiUnvalidated());
|
||||
|
||||
Settings.Global.putInt(cr, settingName, 1);
|
||||
tracker.reevaluate();
|
||||
mService.waitForIdle();
|
||||
assertTrue(mService.avoidBadWifi());
|
||||
assertEventuallyTrue(() -> mService.avoidBadWifi(), 50);
|
||||
assertFalse(tracker.shouldNotifyWifiUnvalidated());
|
||||
|
||||
Settings.Global.putString(cr, settingName, null);
|
||||
tracker.reevaluate();
|
||||
mService.waitForIdle();
|
||||
assertFalse(mService.avoidBadWifi());
|
||||
assertEventuallyTrue(() -> !mService.avoidBadWifi(), 50);
|
||||
assertTrue(tracker.shouldNotifyWifiUnvalidated());
|
||||
}
|
||||
|
||||
@@ -2383,6 +2405,17 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
networkCallback.assertNoCallback();
|
||||
}
|
||||
|
||||
public void assertEventuallyTrue(BooleanSupplier fn, long maxWaitingTimeMs) throws Exception {
|
||||
long start = SystemClock.elapsedRealtime();
|
||||
while (SystemClock.elapsedRealtime() <= start + maxWaitingTimeMs) {
|
||||
if (fn.getAsBoolean()) {
|
||||
return;
|
||||
}
|
||||
Thread.sleep(10);
|
||||
}
|
||||
assertTrue(fn.getAsBoolean());
|
||||
}
|
||||
|
||||
private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
|
||||
|
||||
public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
|
||||
@@ -2472,6 +2505,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
return mWiFiNetworkAgent.getNetwork();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testPacketKeepalives() throws Exception {
|
||||
InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
|
||||
InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.NetworkMisc;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.text.format.DateUtils;
|
||||
import com.android.internal.R;
|
||||
import com.android.server.ConnectivityService;
|
||||
@@ -70,6 +71,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testTransitions() {
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
NetworkAgentInfo nai1 = wifiNai(100);
|
||||
@@ -79,6 +81,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
assertFalse(mMonitor.isNotificationEnabled(nai2, nai1));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNotificationOnLinger() {
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
|
||||
@@ -89,6 +92,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNotification(from, to);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testToastOnLinger() {
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
|
||||
@@ -99,6 +103,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyToast(from, to);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNotificationClearedAfterDisconnect() {
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
|
||||
@@ -112,6 +117,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verify(mNotifier, times(1)).clearNotification(100);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNotificationClearedAfterSwitchingBack() {
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
|
||||
@@ -125,6 +131,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verify(mNotifier, times(1)).clearNotification(100);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testUniqueToast() {
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
|
||||
@@ -142,6 +149,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNoNotifications();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testMultipleNotifications() {
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
|
||||
@@ -160,6 +168,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNotification(wifi2, cell);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testRateLimiting() throws InterruptedException {
|
||||
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT);
|
||||
|
||||
@@ -185,6 +194,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNoNotifications();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testDailyLimiting() throws InterruptedException {
|
||||
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT);
|
||||
|
||||
@@ -211,6 +221,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNoNotifications();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testUniqueNotification() {
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
|
||||
@@ -227,6 +238,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNotification(from, to);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testIgnoreNeverValidatedNetworks() {
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
@@ -238,6 +250,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNoNotifications();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testIgnoreCurrentlyValidatedNetworks() {
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
@@ -249,6 +262,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNoNotifications();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNoNotificationType() {
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
|
||||
setNotificationSwitch();
|
||||
@@ -259,6 +273,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNoNotifications();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNoTransitionToNotify() {
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE);
|
||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||
@@ -269,6 +284,7 @@ public class LingerMonitorTest extends TestCase {
|
||||
verifyNoNotifications();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testDifferentTransitionToNotify() {
|
||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
|
||||
setNotificationSwitch(transition(CELLULAR, WIFI));
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.Context;
|
||||
import android.net.ConnectivityMetricsEvent;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import static android.net.ConnectivityMetricsEvent.Reference;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
@@ -67,12 +68,14 @@ public class MetricsLoggerServiceTest extends TestCase {
|
||||
mService.onStart();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testGetNoEvents() throws Exception {
|
||||
Reference r = new Reference(0);
|
||||
assertArrayEquals(NO_EVENTS, mService.mBinder.getEvents(r));
|
||||
assertEquals(0, r.getValue());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogAndGetEvents() throws Exception {
|
||||
mService.mBinder.logEvents(EVENTS);
|
||||
|
||||
@@ -85,6 +88,7 @@ public class MetricsLoggerServiceTest extends TestCase {
|
||||
assertEquals(N_EVENTS, r.getValue());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogOneByOne() throws Exception {
|
||||
for (ConnectivityMetricsEvent ev : EVENTS) {
|
||||
mService.mBinder.logEvent(ev);
|
||||
@@ -99,6 +103,7 @@ public class MetricsLoggerServiceTest extends TestCase {
|
||||
assertEquals(N_EVENTS, r.getValue());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testInterleavedLogAndGet() throws Exception {
|
||||
mService.mBinder.logEvents(Arrays.copyOfRange(EVENTS, 0, 3));
|
||||
|
||||
@@ -117,6 +122,7 @@ public class MetricsLoggerServiceTest extends TestCase {
|
||||
assertEquals(N_EVENTS, r.getValue());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testMultipleGetAll() throws Exception {
|
||||
mService.mBinder.logEvents(Arrays.copyOf(EVENTS, 3));
|
||||
|
||||
@@ -131,6 +137,7 @@ public class MetricsLoggerServiceTest extends TestCase {
|
||||
assertEquals(N_EVENTS, r2.getValue());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogAndDumpConcurrently() throws Exception {
|
||||
for (int i = 0; i < 50; i++) {
|
||||
mContext = null;
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.net.Network;
|
||||
import android.net.metrics.DnsEvent;
|
||||
import android.net.metrics.INetdEventListener;
|
||||
import android.net.metrics.IpConnectivityLog;
|
||||
import android.os.RemoteException;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Before;
|
||||
@@ -82,6 +84,7 @@ public class NetdEventListenerServiceTest extends TestCase {
|
||||
verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testOneBatch() throws Exception {
|
||||
log(105, LATENCIES);
|
||||
log(106, Arrays.copyOf(LATENCIES, BATCH_SIZE - 1)); // one lookup short of a batch event
|
||||
@@ -96,6 +99,7 @@ public class NetdEventListenerServiceTest extends TestCase {
|
||||
new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testSeveralBatches() throws Exception {
|
||||
log(105, LATENCIES);
|
||||
log(106, LATENCIES);
|
||||
@@ -109,6 +113,7 @@ public class NetdEventListenerServiceTest extends TestCase {
|
||||
new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testBatchAndNetworkLost() throws Exception {
|
||||
byte[] eventTypes = Arrays.copyOf(EVENT_TYPES, 20);
|
||||
byte[] returnCodes = Arrays.copyOf(RETURN_CODES, 20);
|
||||
@@ -125,6 +130,7 @@ public class NetdEventListenerServiceTest extends TestCase {
|
||||
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testConcurrentBatchesAndDumps() throws Exception {
|
||||
final long stop = System.currentTimeMillis() + 100;
|
||||
final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
|
||||
@@ -146,6 +152,7 @@ public class NetdEventListenerServiceTest extends TestCase {
|
||||
new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testConcurrentBatchesAndNetworkLoss() throws Exception {
|
||||
logAsync(105, LATENCIES);
|
||||
Thread.sleep(10L);
|
||||
@@ -157,9 +164,13 @@ public class NetdEventListenerServiceTest extends TestCase {
|
||||
}
|
||||
|
||||
void log(int netId, int[] latencies) {
|
||||
for (int l : latencies) {
|
||||
mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null, 0,
|
||||
0);
|
||||
try {
|
||||
for (int l : latencies) {
|
||||
mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null,
|
||||
0, 0);
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,11 @@ import static org.mockito.Mockito.*;
|
||||
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.net.NetworkInfo.DetailedState;
|
||||
import android.net.UidRange;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.Looper;
|
||||
@@ -43,6 +45,8 @@ import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@@ -88,14 +92,18 @@ public class VpnTest extends AndroidTestCase {
|
||||
@Mock private PackageManager mPackageManager;
|
||||
@Mock private INetworkManagementService mNetService;
|
||||
@Mock private AppOpsManager mAppOps;
|
||||
@Mock private NotificationManager mNotificationManager;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
setMockedPackages(mPackages);
|
||||
when(mContext.getPackageName()).thenReturn(Vpn.class.getPackage().getName());
|
||||
when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
|
||||
when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
|
||||
when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
|
||||
.thenReturn(mNotificationManager);
|
||||
doNothing().when(mNetService).registerObserver(any());
|
||||
}
|
||||
|
||||
@@ -103,7 +111,7 @@ public class VpnTest extends AndroidTestCase {
|
||||
public void testRestrictedProfilesAreAddedToVpn() {
|
||||
setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
|
||||
|
||||
final Vpn vpn = new MockVpn(primaryUser.id);
|
||||
final Vpn vpn = spyVpn(primaryUser.id);
|
||||
final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
|
||||
null, null);
|
||||
|
||||
@@ -117,7 +125,7 @@ public class VpnTest extends AndroidTestCase {
|
||||
public void testManagedProfilesAreNotAddedToVpn() {
|
||||
setMockedUsers(primaryUser, managedProfileA);
|
||||
|
||||
final Vpn vpn = new MockVpn(primaryUser.id);
|
||||
final Vpn vpn = spyVpn(primaryUser.id);
|
||||
final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
|
||||
null, null);
|
||||
|
||||
@@ -130,7 +138,7 @@ public class VpnTest extends AndroidTestCase {
|
||||
public void testAddUserToVpnOnlyAddsOneUser() {
|
||||
setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
|
||||
|
||||
final Vpn vpn = new MockVpn(primaryUser.id);
|
||||
final Vpn vpn = spyVpn(primaryUser.id);
|
||||
final Set<UidRange> ranges = new ArraySet<>();
|
||||
vpn.addUserToRanges(ranges, primaryUser.id, null, null);
|
||||
|
||||
@@ -141,7 +149,7 @@ public class VpnTest extends AndroidTestCase {
|
||||
|
||||
@SmallTest
|
||||
public void testUidWhiteAndBlacklist() throws Exception {
|
||||
final Vpn vpn = new MockVpn(primaryUser.id);
|
||||
final Vpn vpn = spyVpn(primaryUser.id);
|
||||
final UidRange user = UidRange.createForUser(primaryUser.id);
|
||||
final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
|
||||
|
||||
@@ -166,15 +174,15 @@ public class VpnTest extends AndroidTestCase {
|
||||
|
||||
@SmallTest
|
||||
public void testLockdownChangingPackage() throws Exception {
|
||||
final MockVpn vpn = new MockVpn(primaryUser.id);
|
||||
final Vpn vpn = spyVpn(primaryUser.id);
|
||||
final UidRange user = UidRange.createForUser(primaryUser.id);
|
||||
|
||||
// Default state.
|
||||
vpn.assertUnblocked(user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
|
||||
assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
|
||||
|
||||
// Set always-on without lockdown.
|
||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false));
|
||||
vpn.assertUnblocked(user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
|
||||
assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
|
||||
|
||||
// Set always-on with lockdown.
|
||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true));
|
||||
@@ -182,8 +190,8 @@ public class VpnTest extends AndroidTestCase {
|
||||
new UidRange(user.start, user.start + PKG_UIDS[1] - 1),
|
||||
new UidRange(user.start + PKG_UIDS[1] + 1, user.stop)
|
||||
}));
|
||||
vpn.assertBlocked(user.start + PKG_UIDS[0], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
|
||||
vpn.assertUnblocked(user.start + PKG_UIDS[1]);
|
||||
assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
|
||||
assertUnblocked(vpn, user.start + PKG_UIDS[1]);
|
||||
|
||||
// Switch to another app.
|
||||
assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true));
|
||||
@@ -195,13 +203,13 @@ public class VpnTest extends AndroidTestCase {
|
||||
new UidRange(user.start, user.start + PKG_UIDS[3] - 1),
|
||||
new UidRange(user.start + PKG_UIDS[3] + 1, user.stop)
|
||||
}));
|
||||
vpn.assertBlocked(user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
|
||||
vpn.assertUnblocked(user.start + PKG_UIDS[3]);
|
||||
assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
|
||||
assertUnblocked(vpn, user.start + PKG_UIDS[3]);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLockdownAddingAProfile() throws Exception {
|
||||
final MockVpn vpn = new MockVpn(primaryUser.id);
|
||||
final Vpn vpn = spyVpn(primaryUser.id);
|
||||
setMockedUsers(primaryUser);
|
||||
|
||||
// Make a copy of the restricted profile, as we're going to mark it deleted halfway through.
|
||||
@@ -220,7 +228,7 @@ public class VpnTest extends AndroidTestCase {
|
||||
}));
|
||||
|
||||
// Verify restricted user isn't affected at first.
|
||||
vpn.assertUnblocked(profile.start + PKG_UIDS[0]);
|
||||
assertUnblocked(vpn, profile.start + PKG_UIDS[0]);
|
||||
|
||||
// Add the restricted user.
|
||||
setMockedUsers(primaryUser, tempProfile);
|
||||
@@ -239,24 +247,53 @@ public class VpnTest extends AndroidTestCase {
|
||||
}));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNotificationShownForAlwaysOnApp() {
|
||||
final Vpn vpn = spyVpn(primaryUser.id);
|
||||
final InOrder order = inOrder(vpn);
|
||||
setMockedUsers(primaryUser);
|
||||
|
||||
// Don't show a notification for regular disconnected states.
|
||||
vpn.updateState(DetailedState.DISCONNECTED, TAG);
|
||||
order.verify(vpn).updateAlwaysOnNotificationInternal(false);
|
||||
|
||||
// Start showing a notification for disconnected once always-on.
|
||||
vpn.setAlwaysOnPackage(PKGS[0], false);
|
||||
order.verify(vpn).updateAlwaysOnNotificationInternal(true);
|
||||
|
||||
// Stop showing the notification once connected.
|
||||
vpn.updateState(DetailedState.CONNECTED, TAG);
|
||||
order.verify(vpn).updateAlwaysOnNotificationInternal(false);
|
||||
|
||||
// Show the notification if we disconnect again.
|
||||
vpn.updateState(DetailedState.DISCONNECTED, TAG);
|
||||
order.verify(vpn).updateAlwaysOnNotificationInternal(true);
|
||||
|
||||
// Notification should be cleared after unsetting always-on package.
|
||||
vpn.setAlwaysOnPackage(null, false);
|
||||
order.verify(vpn).updateAlwaysOnNotificationInternal(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* A subclass of {@link Vpn} with some of the fields pre-mocked.
|
||||
* Mock some methods of vpn object.
|
||||
*/
|
||||
private class MockVpn extends Vpn {
|
||||
public MockVpn(@UserIdInt int userId) {
|
||||
super(Looper.myLooper(), mContext, mNetService, userId);
|
||||
}
|
||||
private Vpn spyVpn(@UserIdInt int userId) {
|
||||
final Vpn vpn = spy(new Vpn(Looper.myLooper(), mContext, mNetService, userId));
|
||||
|
||||
public void assertBlocked(int... uids) {
|
||||
for (int uid : uids) {
|
||||
assertTrue("Uid " + uid + " should be blocked", isBlockingUid(uid));
|
||||
}
|
||||
}
|
||||
// Block calls to the NotificationManager or PendingIntent#getActivity.
|
||||
doNothing().when(vpn).updateAlwaysOnNotificationInternal(anyBoolean());
|
||||
return vpn;
|
||||
}
|
||||
|
||||
public void assertUnblocked(int... uids) {
|
||||
for (int uid : uids) {
|
||||
assertFalse("Uid " + uid + " should not be blocked", isBlockingUid(uid));
|
||||
}
|
||||
private static void assertBlocked(Vpn vpn, int... uids) {
|
||||
for (int uid : uids) {
|
||||
assertTrue("Uid " + uid + " should be blocked", vpn.isBlockingUid(uid));
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertUnblocked(Vpn vpn, int... uids) {
|
||||
for (int uid : uids) {
|
||||
assertFalse("Uid " + uid + " should not be blocked", vpn.isBlockingUid(uid));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user