Merge commit 'a19056c35d16ddb5a6c1d3343729701b8939f1e1' into nyc-mr1-dev-plus-aosp

* commit 'a19056c35d16ddb5a6c1d3343729701b8939f1e1': (35 commits)
  NetworkMonitor: send one DNS probe per web probe
  NetworkMonitor metrics: add first validation information
  APF: also drop any ICMPv6 RSs
  ConnectivityServiceTest: fix testAvoidBadWifiSettings
  Fix ConnectivityServiceTest testRequestBenchmark
  Switch over to new "time.android.com" NTP pool.
  Define API for metering network stats buckets.
  Refactored NetworkStatsServiceTest to use Mockito instead of EasyMock.
  Use @Ignore to explicitly disable a @Test method.
  Fixed NetworkStatsServiceTest and converted it to JUnit4.
  VPN network stat accounting changes.
  ConnectivityThread: use lazy holder idiom
  ConnectivityManager: use ConnectivityThread looper
  ConnectivityManager: a simpler CallbackHandler
  Indicate the NsdServiceInfo attributes are only filled in for a resolved service.
  Add a null check for the OnStartTetheringCallback.
  TokenBucket for rate-limiting and throttling
  IpConnectivityMetrics reads buffer size in settings
  CaptivePortalLogin: set mixed content policy to compatibility.
  Add IP conn metrics to dumpsys and bug reports
  ...
This commit is contained in:
The Android Automerger
2017-01-27 06:39:05 +00:00
12 changed files with 447 additions and 385 deletions

View File

@@ -2086,6 +2086,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) {
@@ -2096,6 +2098,7 @@ public class ConnectivityManager {
}
}
};
try {
mService.startTethering(type, wrappedCallback, showProvisioningUi);
} catch (RemoteException e) {
@@ -2599,7 +2602,8 @@ public class ConnectivityManager {
/**
* Called if no network is found in the given timeout time. If no timeout is given,
* this will not be called.
* this will not be called. The associated {@link NetworkRequest} will have already
* been removed and released, as if {@link #unregisterNetworkCallback} had been called.
* @hide
*/
public void onUnavailable() {}
@@ -2663,6 +2667,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 */
@@ -2672,25 +2677,38 @@ public class ConnectivityManager {
/** @hide */
public static final int CALLBACK_RESUMED = BASE + 12;
/** @hide */
public static String getCallbackName(int whichCallback) {
switch (whichCallback) {
case CALLBACK_PRECHECK: return "CALLBACK_PRECHECK";
case CALLBACK_AVAILABLE: return "CALLBACK_AVAILABLE";
case CALLBACK_LOSING: return "CALLBACK_LOSING";
case CALLBACK_LOST: return "CALLBACK_LOST";
case CALLBACK_UNAVAIL: return "CALLBACK_UNAVAIL";
case CALLBACK_CAP_CHANGED: return "CALLBACK_CAP_CHANGED";
case CALLBACK_IP_CHANGED: return "CALLBACK_IP_CHANGED";
case CALLBACK_RELEASED: return "CALLBACK_RELEASED";
case CALLBACK_EXIT: return "CALLBACK_EXIT";
case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
case CALLBACK_SUSPENDED: return "CALLBACK_SUSPENDED";
case CALLBACK_RESUMED: return "CALLBACK_RESUMED";
default:
return Integer.toString(whichCallback);
}
}
private class CallbackHandler extends Handler {
private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
private final AtomicInteger mRefCount;
private static final String TAG = "ConnectivityManager.CallbackHandler";
private final ConnectivityManager mCm;
private static final boolean DBG = false;
CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
AtomicInteger refCount, ConnectivityManager cm) {
CallbackHandler(Looper looper) {
super(looper);
mCallbackMap = callbackMap;
mRefCount = refCount;
mCm = cm;
}
@Override
public void handleMessage(Message message) {
NetworkRequest request = (NetworkRequest) getObject(message, NetworkRequest.class);
Network network = (Network) getObject(message, Network.class);
NetworkRequest request = getObject(message, NetworkRequest.class);
Network network = getObject(message, Network.class);
if (DBG) {
Log.d(TAG, whatToString(message.what) + " for network " + network);
}
@@ -2733,9 +2751,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;
@@ -2743,9 +2759,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;
@@ -2765,24 +2779,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: {
@@ -2792,14 +2798,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");
@@ -2808,63 +2814,56 @@ public class ConnectivityManager {
}
}
private void incCallbackHandlerRefCount() {
synchronized(sCallbackRefCount) {
if (sCallbackRefCount.incrementAndGet() == 1) {
// TODO: switch this to ConnectivityThread
HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
callbackThread.start();
sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
sNetworkCallback, sCallbackRefCount, this);
private CallbackHandler getHandler() {
synchronized (sCallbacks) {
if (sCallbackHandler == null) {
sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper());
}
return sCallbackHandler;
}
}
private void decCallbackHandlerRefCount() {
synchronized(sCallbackRefCount) {
if (sCallbackRefCount.decrementAndGet() == 0) {
sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
sCallbackHandler = null;
}
}
}
static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback =
new HashMap<NetworkRequest, NetworkCallback>();
static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
static CallbackHandler sCallbackHandler = null;
static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
static CallbackHandler sCallbackHandler;
private final static int LISTEN = 1;
private final static int REQUEST = 2;
private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
NetworkCallback networkCallback, int timeoutSec, int action,
int legacyType) {
if (networkCallback == null) {
NetworkCallback callback, int timeoutMs, int action, int legacyType) {
return sendRequestForNetwork(need, callback, getHandler(), timeoutMs, action, legacyType);
}
private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
NetworkCallback callback, Handler handler, int timeoutMs, int action, int legacyType) {
if (callback == null) {
throw new IllegalArgumentException("null NetworkCallback");
}
if (need == null && action != REQUEST) {
throw new IllegalArgumentException("null NetworkCapabilities");
}
// TODO: throw an exception if callback.networkRequest is not null.
// http://b/20701525
final NetworkRequest request;
try {
incCallbackHandlerRefCount();
synchronized(sNetworkCallback) {
synchronized(sCallbacks) {
Messenger messenger = new Messenger(handler);
Binder binder = new Binder();
if (action == LISTEN) {
networkCallback.networkRequest = mService.listenForNetwork(need,
new Messenger(sCallbackHandler), new Binder());
request = mService.listenForNetwork(need, messenger, binder);
} else {
networkCallback.networkRequest = mService.requestNetwork(need,
new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
request = mService.requestNetwork(
need, messenger, timeoutMs, binder, legacyType);
}
if (networkCallback.networkRequest != null) {
sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
if (request != null) {
sCallbacks.put(request, callback);
}
callback.networkRequest = request;
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
if (networkCallback.networkRequest == null) decCallbackHandlerRefCount();
return networkCallback.networkRequest;
return request;
}
/**

View File

@@ -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();
}
}

View File

@@ -1804,11 +1804,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
final String iface = newLp.getInterfaceName();
final int mtu = newLp.getMtu();
if (oldLp == null && mtu == 0) {
// Silently ignore unset MTU value.
return;
}
if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
if (VDBG) log("identical MTU - not setting");
return;
}
if (LinkProperties.isValidMtu(mtu, newLp.hasGlobalIPv6Address()) == false) {
if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface);
return;
@@ -2602,14 +2605,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
"request NetworkCapabilities", ConnectivityManager.CALLBACK_CAP_CHANGED);
}
private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
if (mNetworkRequests.get(nri.request) != null && mNetworkForRequestId.get(
nri.request.requestId) == null) {
handleRemoveNetworkRequest(nri, ConnectivityManager.CALLBACK_UNAVAIL);
}
}
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
final NetworkRequestInfo nri = getNriForAppRequest(
request, callingUid, "release NetworkRequest");
if (nri == null) return;
if (nri != null) {
handleRemoveNetworkRequest(nri, ConnectivityManager.CALLBACK_RELEASED);
}
}
if (VDBG || (DBG && nri.request.isRequest())) log("releasing " + request);
private void handleRemoveNetworkRequest(final NetworkRequestInfo nri, final int whichCallback) {
final String logCallbackType = ConnectivityManager.getCallbackName(whichCallback);
if (VDBG || (DBG && nri.request.isRequest())) {
log("releasing " + nri.request + " (" + logCallbackType + ")");
}
nri.unlinkDeathRecipient();
mNetworkRequests.remove(request);
mNetworkRequests.remove(nri.request);
synchronized (mUidToNetworkRequestCount) {
int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
if (requests < 1) {
@@ -2703,7 +2720,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
}
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED, 0);
callCallbackForRequest(nri, null, whichCallback, 0);
}
@Override
@@ -2940,6 +2957,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
handleRegisterNetworkRequestWithIntent(msg);
break;
}
case EVENT_TIMEOUT_NETWORK_REQUEST: {
NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
handleTimedOutNetworkRequest(nri);
break;
}
case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
break;
@@ -5297,6 +5319,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// notify only this one new request of the current state
protected void notifyNetworkCallback(NetworkAgentInfo nai, NetworkRequestInfo nri) {
int notifyType = ConnectivityManager.CALLBACK_AVAILABLE;
mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
if (nri.mPendingIntent == null) {
callCallbackForRequest(nri, nai, notifyType, 0);
} else {

View File

@@ -24,6 +24,7 @@ import android.os.Binder;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import com.android.server.net.BaseNetworkObserver;
import com.android.internal.util.test.BroadcastInterceptingContext;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

View File

@@ -40,21 +40,21 @@ import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
import static org.easymock.EasyMock.anyInt;
import static org.easymock.EasyMock.anyLong;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.isA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import android.app.AlarmManager;
import android.app.IAlarmListener;
import android.app.IAlarmManager;
import android.app.PendingIntent;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
import android.content.Intent;
@@ -63,6 +63,7 @@ import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkStatsSession;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkState;
@@ -80,23 +81,28 @@ import android.os.MessageQueue;
import android.os.MessageQueue.IdleHandler;
import android.os.Message;
import android.os.PowerManager;
import android.os.WorkSource;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.TrustedTime;
import com.android.internal.net.VpnInfo;
import com.android.server.BroadcastInterceptingContext;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.server.net.NetworkStatsService;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
import libcore.io.IoUtils;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.File;
import java.util.ArrayList;
@@ -106,11 +112,11 @@ import java.util.List;
/**
* Tests for {@link NetworkStatsService}.
*
* TODO: This test is really brittle, largely due to overly-strict use of Easymock.
* Rewrite w/ Mockito.
* TODO: This test used to be really brittle because it used Easymock - it uses Mockito now, but
* still uses the Easymock structure, which could be simplified.
*/
@LargeTest
public class NetworkStatsServiceTest extends AndroidTestCase {
@RunWith(AndroidJUnit4.class)
public class NetworkStatsServiceTest {
private static final String TAG = "NetworkStatsServiceTest";
private static final String TEST_IFACE = "test0";
@@ -137,10 +143,12 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private BroadcastInterceptingContext mServiceContext;
private File mStatsDir;
private INetworkManagementService mNetManager;
private TrustedTime mTime;
private NetworkStatsSettings mSettings;
private IConnectivityManager mConnManager;
private @Mock INetworkManagementService mNetManager;
private @Mock TrustedTime mTime;
private @Mock NetworkStatsSettings mSettings;
private @Mock IConnectivityManager mConnManager;
private @Mock IBinder mBinder;
private @Mock AlarmManager mAlarmManager;
private IdleableHandlerThread mHandlerThread;
private Handler mHandler;
@@ -148,32 +156,24 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private INetworkStatsSession mSession;
private INetworkManagementEventObserver mNetworkObserver;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
final Context context = InstrumentationRegistry.getContext();
mServiceContext = new BroadcastInterceptingContext(getContext());
mStatsDir = getContext().getFilesDir();
mServiceContext = new BroadcastInterceptingContext(context);
mStatsDir = context.getFilesDir();
if (mStatsDir.exists()) {
IoUtils.deleteContents(mStatsDir);
}
mNetManager = createMock(INetworkManagementService.class);
// TODO: Mock AlarmManager when migrating this test to Mockito.
AlarmManager alarmManager = (AlarmManager) mServiceContext
.getSystemService(Context.ALARM_SERVICE);
mTime = createMock(TrustedTime.class);
mSettings = createMock(NetworkStatsSettings.class);
mConnManager = createMock(IConnectivityManager.class);
PowerManager powerManager = (PowerManager) mServiceContext.getSystemService(
Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock =
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mService = new NetworkStatsService(
mServiceContext, mNetManager, alarmManager, wakeLock, mTime,
mServiceContext, mNetManager, mAlarmManager, wakeLock, mTime,
TelephonyManager.getDefault(), mSettings, new NetworkStatsObservers(),
mStatsDir, getBaseDir(mStatsDir));
mHandlerThread = new IdleableHandlerThread("HandlerThread");
@@ -190,22 +190,20 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsUidDetail(buildEmptyStats());
expectSystemReady();
// catch INetworkManagementEventObserver during systemReady()
final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
INetworkManagementEventObserver>();
mNetManager.registerObserver(capture(networkObserver));
expectLastCall().atLeastOnce();
replay();
mService.systemReady();
mSession = mService.openSession();
verifyAndReset();
assertNotNull("openSession() failed", mSession);
// catch INetworkManagementEventObserver during systemReady()
ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
verify(mNetManager).registerObserver(networkObserver.capture());
mNetworkObserver = networkObserver.getValue();
}
@Override
@After
public void tearDown() throws Exception {
IoUtils.deleteContents(mStatsDir);
@@ -219,10 +217,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mSession.close();
mService = null;
super.tearDown();
}
@Test
public void testNetworkStatsWifi() throws Exception {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
@@ -231,15 +228,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
// modify some number on wifi, and trigger poll event
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -248,14 +243,11 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// verify service recorded history
assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
verifyAndReset();
// and bump forward again, with counters going higher. this is
// important, since polling should correctly subtract last snapshot.
@@ -265,17 +257,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// verify service recorded history
assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
verifyAndReset();
}
@Test
public void testStatsRebootPersist() throws Exception {
assertStatsFilesExist(false);
@@ -286,15 +275,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
// modify some number on wifi, and trigger poll event
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -308,14 +295,11 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
expectNetworkStatsPoll();
mService.setUidForeground(UID_RED, false);
mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
mService.setUidForeground(UID_RED, true);
mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
replay();
forcePollAndWaitForIdle();
// verify service recorded history
@@ -325,16 +309,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L,
6);
assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
verifyAndReset();
// graceful shutdown system, which should trigger persist of stats, and
// clear any values in memory.
expectCurrentTime();
expectDefaultSettings();
replay();
mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
verifyAndReset();
assertStatsFilesExist(true);
// boot through serviceReady() again
@@ -343,17 +324,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsUidDetail(buildEmptyStats());
expectSystemReady();
// catch INetworkManagementEventObserver during systemReady()
final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
INetworkManagementEventObserver>();
mNetManager.registerObserver(capture(networkObserver));
expectLastCall().atLeastOnce();
replay();
mService.systemReady();
mNetworkObserver = networkObserver.getValue();
// after systemReady(), we should have historical stats loaded again
assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
@@ -361,12 +333,12 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L,
6);
assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
verifyAndReset();
}
// TODO: simulate reboot to test bucket resize
@Suppress
@Test
@Ignore
public void testStatsBucketResize() throws Exception {
NetworkStatsHistory history = null;
@@ -379,12 +351,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
verifyAndReset();
// modify some number on wifi, and trigger poll event
incrementCurrentTime(2 * HOUR_IN_MILLIS);
@@ -393,9 +363,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// verify service recorded history
@@ -403,7 +370,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
assertEquals(2, history.size());
verifyAndReset();
// now change bucket duration setting and trigger another poll with
// exact same values, which should resize existing buckets.
@@ -411,9 +378,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// verify identical stats, but spread across 4 buckets now
@@ -421,10 +385,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
assertEquals(4, history.size());
verifyAndReset();
}
@Test
public void testUidStatsAcrossNetworks() throws Exception {
// pretend first mobile network comes online
expectCurrentTime();
@@ -432,12 +396,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildMobile3gState(IMSI_1));
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
verifyAndReset();
// create some traffic on first network
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -449,11 +411,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xF00D, 10);
replay();
forcePollAndWaitForIdle();
// verify service recorded history
@@ -461,7 +420,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
verifyAndReset();
// now switch networks; this also tests that we're okay with interfaces
// disappearing, to verify we don't count backwards.
@@ -475,13 +434,11 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
forcePollAndWaitForIdle();
verifyAndReset();
// create traffic on second network
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -494,11 +451,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
expectNetworkStatsPoll();
mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
replay();
forcePollAndWaitForIdle();
// verify original history still intact
@@ -511,10 +465,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
verifyAndReset();
}
@Test
public void testUidRemovedIsMoved() throws Exception {
// pretend that network comes online
expectCurrentTime();
@@ -522,12 +476,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
verifyAndReset();
// create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -540,11 +492,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
.addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
replay();
forcePollAndWaitForIdle();
// verify service recorded history
@@ -552,7 +501,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
verifyAndReset();
// now pretend two UIDs are uninstalled, which should migrate stats to
// special "removed" bucket.
@@ -565,9 +514,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
.addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
expectNetworkStatsPoll();
replay();
final Intent intent = new Intent(ACTION_UID_REMOVED);
intent.putExtra(EXTRA_UID, UID_BLUE);
mServiceContext.sendBroadcast(intent);
@@ -581,10 +527,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 10);
verifyAndReset();
}
@Test
public void testUid3g4gCombinedByTemplate() throws Exception {
// pretend that network comes online
expectCurrentTime();
@@ -592,12 +538,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildMobile3gState(IMSI_1));
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
verifyAndReset();
// create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -607,16 +551,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xF00D, 5);
replay();
forcePollAndWaitForIdle();
// verify service recorded history
assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5);
verifyAndReset();
// now switch over to 4g network
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -627,13 +568,11 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
forcePollAndWaitForIdle();
verifyAndReset();
// create traffic on second network
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -645,19 +584,15 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
.addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
replay();
forcePollAndWaitForIdle();
// verify that ALL_MOBILE template combines both
assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);
verifyAndReset();
}
@Test
public void testSummaryForAllUid() throws Exception {
// pretend that network comes online
expectCurrentTime();
@@ -665,12 +600,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
verifyAndReset();
// create some traffic for two apps
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -681,17 +614,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
replay();
forcePollAndWaitForIdle();
// verify service recorded history
assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1);
assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0);
verifyAndReset();
// now create more traffic in next hour, but only for one app
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -702,9 +632,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// first verify entire history present
@@ -725,10 +652,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertEquals(1, stats.size());
assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
512L, 4L, 0);
verifyAndReset();
}
@Test
public void testForegroundBackground() throws Exception {
// pretend that network comes online
expectCurrentTime();
@@ -736,12 +662,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
verifyAndReset();
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -751,16 +675,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
expectNetworkStatsPoll();
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
replay();
forcePollAndWaitForIdle();
// verify service recorded history
assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
verifyAndReset();
// now switch to foreground
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -772,12 +693,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
expectNetworkStatsPoll();
mService.setUidForeground(UID_RED, true);
mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
replay();
forcePollAndWaitForIdle();
// test that we combined correctly
@@ -795,10 +713,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
32L, 2L, 1);
assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, ROAMING_NO, 1L, 1L, 1L,
1L, 1);
verifyAndReset();
}
@Test
public void testRoaming() throws Exception {
// pretend that network comes online
expectCurrentTime();
@@ -806,12 +723,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildMobile3gState(IMSI_1, true /* isRoaming */));
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
verifyAndReset();
// Create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -826,9 +741,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
128L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L,
1L, 0L));
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// verify service recorded history
@@ -842,10 +754,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
128L, 2L, 0);
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_YES, 64L, 1L, 64L,
1L, 0);
verifyAndReset();
}
@Test
public void testTethering() throws Exception {
// pretend first mobile network comes online
expectCurrentTime();
@@ -853,12 +764,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildMobile3gState(IMSI_1));
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
verifyAndReset();
// create some tethering traffic
incrementCurrentTime(HOUR_IN_MILLIS);
@@ -874,19 +783,16 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
.addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L);
expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// verify service recorded history
assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
verifyAndReset();
}
@Test
public void testRegisterUsageCallback() throws Exception {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
@@ -895,16 +801,12 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
expectBandwidthControlCheck();
replay();
mService.forceUpdateIfaces();
// verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
String callingPackage = "the.calling.package";
long thresholdInBytes = 1L; // very small; should be overriden by framework
DataUsageRequest inputRequest = new DataUsageRequest(
@@ -915,23 +817,18 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
LatchedHandler latchedHandler = new LatchedHandler(Looper.getMainLooper(), cv);
Messenger messenger = new Messenger(latchedHandler);
// Allow binder to connect
IBinder mockBinder = createMock(IBinder.class);
mockBinder.linkToDeath((IBinder.DeathRecipient) anyObject(), anyInt());
EasyMock.replay(mockBinder);
// Force poll
expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
replay();
// Register and verify request and that binder was called
DataUsageRequest request =
mService.registerUsageCallback(callingPackage, inputRequest,
messenger, mockBinder);
messenger, mBinder);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateWifi, request.template));
long minThresholdInBytes = 2 * 1024 * 1024; // 2 MB
@@ -941,11 +838,11 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mHandler.sendMessage(mHandler.obtainMessage(-1));
mHandlerThread.waitForIdle(WAIT_TIMEOUT);
verifyAndReset();
// Make sure that the caller binder gets connected
EasyMock.verify(mockBinder);
EasyMock.reset(mockBinder);
verify(mBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
// modify some number on wifi, and trigger poll event
// not enough traffic to call data usage callback
@@ -955,13 +852,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// verify service recorded history
verifyAndReset();
assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
// make sure callback has not being called
@@ -975,14 +868,11 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
expectNetworkStatsUidDetail(buildEmptyStats());
expectNetworkStatsPoll();
replay();
forcePollAndWaitForIdle();
// verify service recorded history
assertNetworkTotal(sTemplateWifi, 4096000L, 4L, 8192000L, 8L, 0);
verifyAndReset();
// Wait for the caller to ack receipt of CALLBACK_LIMIT_REACHED
assertTrue(cv.block(WAIT_TIMEOUT));
@@ -990,9 +880,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
cv.close();
// Allow binder to disconnect
expect(mockBinder.unlinkToDeath((IBinder.DeathRecipient) anyObject(), anyInt()))
.andReturn(true);
EasyMock.replay(mockBinder);
when(mBinder.unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt())).thenReturn(true);
// Unregister request
mService.unregisterUsageRequest(request);
@@ -1002,9 +890,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertEquals(NetworkStatsManager.CALLBACK_RELEASED, latchedHandler.mLastMessageType);
// Make sure that the caller binder gets disconnected
EasyMock.verify(mockBinder);
verify(mBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
}
@Test
public void testUnregisterUsageCallback_unknown_noop() throws Exception {
String callingPackage = "the.calling.package";
long thresholdInBytes = 10 * 1024 * 1024; // 10 MB
@@ -1061,33 +950,30 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private void expectSystemReady() throws Exception {
mNetManager.setGlobalAlert(anyLong());
expectLastCall().atLeastOnce();
expectNetworkStatsSummary(buildEmptyStats());
expectBandwidthControlCheck();
}
private void expectNetworkState(NetworkState... state) throws Exception {
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
when(mConnManager.getAllNetworkState()).thenReturn(state);
final LinkProperties linkProp = state.length > 0 ? state[0].linkProperties : null;
expect(mConnManager.getActiveLinkProperties()).andReturn(linkProp).atLeastOnce();
when(mConnManager.getActiveLinkProperties()).thenReturn(linkProp);
}
private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
expect(mConnManager.getAllVpnInfo()).andReturn(new VpnInfo[0]).atLeastOnce();
when(mConnManager.getAllVpnInfo()).thenReturn(new VpnInfo[0]);
expectNetworkStatsSummaryDev(summary);
expectNetworkStatsSummaryXt(summary);
}
private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
expect(mNetManager.getNetworkStatsSummaryDev()).andReturn(summary).atLeastOnce();
when(mNetManager.getNetworkStatsSummaryDev()).thenReturn(summary);
}
private void expectNetworkStatsSummaryXt(NetworkStats summary) throws Exception {
expect(mNetManager.getNetworkStatsSummaryXt()).andReturn(summary).atLeastOnce();
when(mNetManager.getNetworkStatsSummaryXt()).thenReturn(summary);
}
private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
@@ -1097,11 +983,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private void expectNetworkStatsUidDetail(
NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats)
throws Exception {
expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
when(mNetManager.getNetworkStatsUidDetail(UID_ALL)).thenReturn(detail);
// also include tethering details, since they are folded into UID
expect(mNetManager.getNetworkStatsTethering())
.andReturn(tetherStats).atLeastOnce();
when(mNetManager.getNetworkStatsTethering()).thenReturn(tetherStats);
}
private void expectDefaultSettings() throws Exception {
@@ -1110,38 +995,33 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
throws Exception {
expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes();
when(mSettings.getPollInterval()).thenReturn(HOUR_IN_MILLIS);
when(mSettings.getTimeCacheMaxAge()).thenReturn(DAY_IN_MILLIS);
when(mSettings.getSampleEnabled()).thenReturn(true);
final Config config = new Config(bucketDuration, deleteAge, deleteAge);
expect(mSettings.getDevConfig()).andReturn(config).anyTimes();
expect(mSettings.getXtConfig()).andReturn(config).anyTimes();
expect(mSettings.getUidConfig()).andReturn(config).anyTimes();
expect(mSettings.getUidTagConfig()).andReturn(config).anyTimes();
when(mSettings.getDevConfig()).thenReturn(config);
when(mSettings.getXtConfig()).thenReturn(config);
when(mSettings.getUidConfig()).thenReturn(config);
when(mSettings.getUidTagConfig()).thenReturn(config);
expect(mSettings.getGlobalAlertBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
expect(mSettings.getDevPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
expect(mSettings.getXtPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
expect(mSettings.getUidPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
expect(mSettings.getUidTagPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
when(mSettings.getGlobalAlertBytes(anyLong())).thenReturn(MB_IN_BYTES);
when(mSettings.getDevPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
when(mSettings.getXtPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
when(mSettings.getUidPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
when(mSettings.getUidTagPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
}
private void expectCurrentTime() throws Exception {
expect(mTime.forceRefresh()).andReturn(false).anyTimes();
expect(mTime.hasCache()).andReturn(true).anyTimes();
expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
}
private void expectNetworkStatsPoll() throws Exception {
mNetManager.setGlobalAlert(anyLong());
expectLastCall().anyTimes();
when(mTime.forceRefresh()).thenReturn(false);
when(mTime.hasCache()).thenReturn(true);
when(mTime.currentTimeMillis()).thenReturn(currentTimeMillis());
when(mTime.getCacheAge()).thenReturn(0L);
when(mTime.getCacheCertainty()).thenReturn(0L);
}
private void expectBandwidthControlCheck() throws Exception {
expect(mNetManager.isBandwidthControlEnabled()).andReturn(true).atLeastOnce();
when(mNetManager.isBandwidthControlEnabled()).thenReturn(true);
}
private void assertStatsFilesExist(boolean exist) {
@@ -1204,7 +1084,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
return new NetworkState(info, prop, null, null, null, TEST_SSID);
final NetworkCapabilities capabilities = new NetworkCapabilities();
return new NetworkState(info, prop, capabilities, null, null, TEST_SSID);
}
private static NetworkState buildMobile3gState(String subscriberId) {
@@ -1218,7 +1099,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
info.setRoaming(isRoaming);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
return new NetworkState(info, prop, null, null, subscriberId, null);
final NetworkCapabilities capabilities = new NetworkCapabilities();
return new NetworkState(info, prop, capabilities, null, subscriberId, null);
}
private static NetworkState buildMobile4gState(String iface) {
@@ -1226,7 +1108,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(iface);
return new NetworkState(info, prop, null, null, null, null);
final NetworkCapabilities capabilities = new NetworkCapabilities();
return new NetworkState(info, prop, capabilities, null, null, null);
}
private NetworkStats buildEmptyStats() {
@@ -1249,15 +1132,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mElapsedRealtime += duration;
}
private void replay() {
EasyMock.replay(mNetManager, mTime, mSettings, mConnManager);
}
private void verifyAndReset() {
EasyMock.verify(mNetManager, mTime, mSettings, mConnManager);
EasyMock.reset(mNetManager, mTime, mSettings, mConnManager);
}
private void forcePollAndWaitForIdle() {
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// Send dummy message to make sure that any previous message has been handled

View File

@@ -68,14 +68,16 @@ import android.os.Process;
import android.os.SystemClock;
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;
import com.android.internal.util.FakeSettingsProvider;
import com.android.internal.util.WakeupMessage;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
@@ -89,6 +91,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}.
@@ -215,8 +218,20 @@ public class ConnectivityServiceTest extends AndroidTestCase {
mService.waitForIdle();
assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
}
}
@FlakyTest(tolerance = 3)
public void testNotWaitingForIdleCausesRaceConditions() {
// Bring up a network that we can use to send messages to ConnectivityService.
ConditionVariable cv = waitForConnectivityBroadcasts(1);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
waitFor(cv);
Network n = mWiFiNetworkAgent.getNetwork();
assertNotNull(n);
// Ensure that not calling waitForIdle causes a race condition.
final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
for (int i = 0; i < attempts; i++) {
mWiFiNetworkAgent.setSignalStrength(i);
if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
@@ -608,7 +623,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);
@@ -713,10 +728,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
static private void waitFor(Criteria criteria) {
int delays = 0;
while (!criteria.get()) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
sleepFor(50);
if (++delays == 10) fail();
}
}
@@ -1086,7 +1098,8 @@ public class ConnectivityServiceTest extends AndroidTestCase {
NETWORK_CAPABILITIES,
LINK_PROPERTIES,
LOSING,
LOST
LOST,
UNAVAILABLE
}
private static class CallbackInfo {
@@ -1134,6 +1147,11 @@ public class ConnectivityServiceTest extends AndroidTestCase {
setLastCallback(CallbackState.AVAILABLE, network, null);
}
@Override
public void onUnavailable() {
setLastCallback(CallbackState.UNAVAILABLE, null, null);
}
@Override
public void onLosing(Network network, int maxMsToLive) {
setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
@@ -1995,6 +2013,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.
@@ -2008,61 +2027,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
@@ -2143,7 +2181,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());
}
@@ -2152,19 +2190,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());
}
@@ -2291,6 +2329,107 @@ public class ConnectivityServiceTest extends AndroidTestCase {
mCm.unregisterNetworkCallback(defaultCallback);
}
/**
* Validate that a satisfied network request does not trigger onUnavailable() once the
* time-out period expires.
*/
@SmallTest
public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
mCm.requestNetwork(nr, networkCallback, 10);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
// pass timeout and validate that UNAVAILABLE is not called
sleepFor(15);
networkCallback.assertNoCallback();
}
/**
* Validate that a satisfied network request followed by a disconnected (lost) network does
* not trigger onUnavailable() once the time-out period expires.
*/
@SmallTest
public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
mCm.requestNetwork(nr, networkCallback, 500);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
sleepFor(20);
mWiFiNetworkAgent.disconnect();
networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
// pass timeout and validate that UNAVAILABLE is not called
sleepFor(600);
networkCallback.assertNoCallback();
}
/**
* Validate that when a time-out is specified for a network request the onUnavailable()
* callback is called when time-out expires. Then validate that if network request is
* (somehow) satisfied - the callback isn't called later.
*/
@SmallTest
public void testTimedoutNetworkRequest() {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
mCm.requestNetwork(nr, networkCallback, 10);
// pass timeout and validate that UNAVAILABLE is called
networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
// create a network satisfying request - validate that request not triggered
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
networkCallback.assertNoCallback();
}
/**
* Validate that when a network request is unregistered (cancelled) the time-out for that
* request doesn't trigger the onUnavailable() callback.
*/
@SmallTest
public void testTimedoutAfterUnregisteredNetworkRequest() {
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
mCm.requestNetwork(nr, networkCallback, 10);
// remove request
mCm.unregisterNetworkCallback(networkCallback);
// pass timeout and validate that no callbacks
// Note: doesn't validate that nothing called from CS since even if called the CM already
// unregisters the callback and won't pass it through!
sleepFor(15);
networkCallback.assertNoCallback();
// create a network satisfying request - validate that request not triggered
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
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 };
@@ -2695,4 +2834,13 @@ public class ConnectivityServiceTest extends AndroidTestCase {
mCm.unregisterNetworkCallback(pendingIntent);
}
}
/* test utilities */
static private void sleepFor(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
}
}
}

View File

@@ -71,7 +71,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" transport_types: 3",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -93,7 +94,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" state_transition: \"SomeState\"",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -114,7 +116,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" state_transition: \"\"",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -160,7 +163,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" return_codes: 178",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -181,7 +185,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" latency_ms: 5678",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -200,7 +205,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"wlan0\"",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -223,7 +229,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" >",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -248,7 +255,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" probe_result: 204",
" probe_type: 1",
" >",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -274,7 +282,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" program_length: 2048",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -305,7 +314,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" zero_lifetime_ras: 1",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}
@@ -332,7 +342,8 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" router_lifetime: 2000",
" >",
" time_ms: 1",
">");
">",
"version: 2");
verifySerialization(want, ev);
}

View File

@@ -57,7 +57,7 @@ public class IpConnectivityMetricsTest extends TestCase {
public void setUp() {
MockitoAnnotations.initMocks(this);
mService = new IpConnectivityMetrics(mCtx);
mService = new IpConnectivityMetrics(mCtx, (ctx) -> 2000);
}
public void testLoggingEvents() throws Exception {
@@ -204,7 +204,8 @@ public class IpConnectivityMetricsTest extends TestCase {
" router_lifetime: 2000",
" >",
" time_ms: 700",
">");
">",
"version: 2");
verifySerialization(want, getdump("flush"));
}