Merge changes Ic98e3bcb,Idb0c55fc,Ia8649061,I5e7e5a87 into nyc-mr1-dev

am: c5447626d7

Change-Id: I2305c4019f56896d741caa509df41416368e5642
This commit is contained in:
Lorenzo Colitti
2016-06-08 06:39:18 +00:00
committed by android-build-merger
2 changed files with 92 additions and 14 deletions

View File

@@ -797,6 +797,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId()); return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
} }
// Used only for testing.
// TODO: Delete this and either:
// 1. Give Fake SettingsProvider the ability to send settings change notifications (requires
// changing ContentResolver to make registerContentObserver non-final).
// 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
// by subclassing SettingsObserver.
@VisibleForTesting
void updateMobileDataAlwaysOn() {
mHandler.sendEmptyMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON);
}
private void handleMobileDataAlwaysOn() { private void handleMobileDataAlwaysOn() {
final boolean enable = (Settings.Global.getInt( final boolean enable = (Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.MOBILE_DATA_ALWAYS_ON, 0) == 1); mContext.getContentResolver(), Settings.Global.MOBILE_DATA_ALWAYS_ON, 0) == 1);

View File

@@ -26,6 +26,7 @@ import static org.mockito.Mockito.mock;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.ContextWrapper; import android.content.ContextWrapper;
import android.content.Intent; import android.content.Intent;
@@ -61,12 +62,15 @@ import android.os.Messenger;
import android.os.MessageQueue.IdleHandler; import android.os.MessageQueue.IdleHandler;
import android.os.Process; import android.os.Process;
import android.os.SystemClock; import android.os.SystemClock;
import android.provider.Settings;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log; import android.util.Log;
import android.util.LogPrinter; import android.util.LogPrinter;
import com.android.internal.util.FakeSettingsProvider;
import com.android.internal.util.WakeupMessage; import com.android.internal.util.WakeupMessage;
import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor; import com.android.server.connectivity.NetworkMonitor;
@@ -118,27 +122,24 @@ public class ConnectivityServiceTest extends AndroidTestCase {
} }
private class MockContext extends BroadcastInterceptingContext { private class MockContext extends BroadcastInterceptingContext {
private final MockContentResolver mContentResolver;
MockContext(Context base) { MockContext(Context base) {
super(base); super(base);
mContentResolver = new MockContentResolver();
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
} }
@Override @Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { public Object getSystemService(String name) {
// PendingIntents sent by the AlarmManager are not intercepted by
// BroadcastInterceptingContext so we must really register the receiver.
// This shouldn't effect the real NetworkMonitors as the action contains a random token.
if (filter.getAction(0).startsWith("android.net.netmon.lingerExpired")) {
return getBaseContext().registerReceiver(receiver, filter);
} else {
return super.registerReceiver(receiver, filter);
}
}
@Override
public Object getSystemService (String name) {
if (name == Context.CONNECTIVITY_SERVICE) return mCm; if (name == Context.CONNECTIVITY_SERVICE) return mCm;
return super.getSystemService(name); return super.getSystemService(name);
} }
@Override
public ContentResolver getContentResolver() {
return mContentResolver;
}
} }
/** /**
@@ -641,7 +642,6 @@ public class ConnectivityServiceTest extends AndroidTestCase {
public void waitForIdle() { public void waitForIdle() {
waitForIdle(TIMEOUT_MS); waitForIdle(TIMEOUT_MS);
} }
} }
private interface Criteria { private interface Criteria {
@@ -1477,6 +1477,73 @@ public class ConnectivityServiceTest extends AndroidTestCase {
defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent); defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
} }
@SmallTest
public void testMobileDataAlwaysOn() throws Exception {
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
final NetworkRequest cellRequest = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_CELLULAR).build();
mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
final HandlerThread handlerThread = new HandlerThread("MobileDataAlwaysOnFactory");
handlerThread.start();
NetworkCapabilities filter = new NetworkCapabilities()
.addTransportType(TRANSPORT_CELLULAR)
.addCapability(NET_CAPABILITY_INTERNET);
final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
mServiceContext, "testFactory", filter);
testFactory.setScoreFilter(40);
// Register the factory and expect it to start looking for a network.
testFactory.expectAddRequests(1);
testFactory.register();
testFactory.waitForNetworkRequests(1);
assertTrue(testFactory.getMyStartRequested());
// Bring up wifi. The factory stops looking for a network.
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
testFactory.expectAddRequests(2); // Because the default request changes score twice.
mWiFiNetworkAgent.connect(true);
testFactory.waitForNetworkRequests(1);
assertFalse(testFactory.getMyStartRequested());
ContentResolver cr = mServiceContext.getContentResolver();
// Turn on mobile data always on. The factory starts looking again.
testFactory.expectAddRequests(1);
Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, 1);
mService.updateMobileDataAlwaysOn();
testFactory.waitForNetworkRequests(2);
assertTrue(testFactory.getMyStartRequested());
// Bring up cell data and check that the factory stops looking.
assertEquals(1, mCm.getAllNetworks().length);
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
testFactory.expectAddRequests(2); // Because the cell request changes score twice.
mCellNetworkAgent.connect(true);
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE);
testFactory.waitForNetworkRequests(2);
assertFalse(testFactory.getMyStartRequested()); // Because the cell network outscores us.
// Check that cell data stays up.
mService.waitForIdle();
verifyActiveNetwork(TRANSPORT_WIFI);
assertEquals(2, mCm.getAllNetworks().length);
// Turn off mobile data always on and expect the request to disappear...
testFactory.expectRemoveRequests(1);
Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, 0);
mService.updateMobileDataAlwaysOn();
testFactory.waitForNetworkRequests(1);
// ... and cell data to be torn down.
cellNetworkCallback.expectCallback(CallbackState.LOST);
assertEquals(1, mCm.getAllNetworks().length);
testFactory.unregister();
mCm.unregisterNetworkCallback(cellNetworkCallback);
handlerThread.quit();
}
private static class TestKeepaliveCallback extends PacketKeepaliveCallback { private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };