1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; 20 import static android.net.ConnectivityManager.TYPE_MOBILE; 21 import static android.net.ConnectivityManager.TYPE_WIFI; 22 import static android.net.ConnectivityManager.getNetworkTypeName; 23 import static android.net.NetworkStateTracker.EVENT_STATE_CHANGED; 24 import static com.google.testing.littlemock.LittleMock.anyInt; 25 import static com.google.testing.littlemock.LittleMock.createCaptor; 26 import static com.google.testing.littlemock.LittleMock.doNothing; 27 import static com.google.testing.littlemock.LittleMock.doReturn; 28 import static com.google.testing.littlemock.LittleMock.doThrow; 29 import static com.google.testing.littlemock.LittleMock.eq; 30 import static com.google.testing.littlemock.LittleMock.isA; 31 import static com.google.testing.littlemock.LittleMock.mock; 32 import static com.google.testing.littlemock.LittleMock.reset; 33 import static com.google.testing.littlemock.LittleMock.verify; 34 35 import android.content.Context; 36 import android.net.INetworkPolicyManager; 37 import android.net.INetworkStatsService; 38 import android.net.LinkProperties; 39 import android.net.NetworkConfig; 40 import android.net.NetworkInfo; 41 import android.net.NetworkInfo.DetailedState; 42 import android.net.NetworkStateTracker; 43 import android.net.RouteInfo; 44 import android.os.Handler; 45 import android.os.INetworkManagementService; 46 import android.test.AndroidTestCase; 47 import android.test.suitebuilder.annotation.LargeTest; 48 import android.util.Log; 49 import android.util.LogPrinter; 50 51 import com.google.testing.littlemock.ArgumentCaptor; 52 53 import java.net.InetAddress; 54 import java.util.concurrent.Future; 55 56 /** 57 * Tests for {@link ConnectivityService}. 58 */ 59 @LargeTest 60 public class ConnectivityServiceTest extends AndroidTestCase { 61 private static final String TAG = "ConnectivityServiceTest"; 62 63 private static final String MOBILE_IFACE = "rmnet3"; 64 private static final String WIFI_IFACE = "wlan6"; 65 66 private static final RouteInfo MOBILE_ROUTE_V4 = RouteInfo.makeHostRoute(parse("10.0.0.33")); 67 private static final RouteInfo MOBILE_ROUTE_V6 = RouteInfo.makeHostRoute(parse("fd00::33")); 68 69 private static final RouteInfo WIFI_ROUTE_V4 = RouteInfo.makeHostRoute( 70 parse("192.168.0.66"), parse("192.168.0.1")); 71 private static final RouteInfo WIFI_ROUTE_V6 = RouteInfo.makeHostRoute( 72 parse("fd00::66"), parse("fd00::")); 73 74 private INetworkManagementService mNetManager; 75 private INetworkStatsService mStatsService; 76 private INetworkPolicyManager mPolicyService; 77 private ConnectivityService.NetworkFactory mNetFactory; 78 79 private BroadcastInterceptingContext mServiceContext; 80 private ConnectivityService mService; 81 82 private MockNetwork mMobile; 83 private MockNetwork mWifi; 84 85 private Handler mTrackerHandler; 86 87 private static class MockNetwork { 88 public NetworkStateTracker tracker; 89 public NetworkInfo info; 90 public LinkProperties link; 91 MockNetwork(int type)92 public MockNetwork(int type) { 93 tracker = mock(NetworkStateTracker.class); 94 info = new NetworkInfo(type, -1, getNetworkTypeName(type), null); 95 link = new LinkProperties(); 96 } 97 doReturnDefaults()98 public void doReturnDefaults() { 99 // TODO: eventually CS should make defensive copies 100 doReturn(new NetworkInfo(info)).when(tracker).getNetworkInfo(); 101 doReturn(new LinkProperties(link)).when(tracker).getLinkProperties(); 102 103 // fallback to default TCP buffers 104 doReturn("").when(tracker).getTcpBufferSizesPropName(); 105 } 106 } 107 108 @Override setUp()109 public void setUp() throws Exception { 110 super.setUp(); 111 112 mServiceContext = new BroadcastInterceptingContext(getContext()); 113 114 mNetManager = mock(INetworkManagementService.class); 115 mStatsService = mock(INetworkStatsService.class); 116 mPolicyService = mock(INetworkPolicyManager.class); 117 mNetFactory = mock(ConnectivityService.NetworkFactory.class); 118 119 mMobile = new MockNetwork(TYPE_MOBILE); 120 mWifi = new MockNetwork(TYPE_WIFI); 121 122 // omit most network trackers 123 doThrow(new IllegalArgumentException("Not supported in test environment")) 124 .when(mNetFactory).createTracker(anyInt(), isA(NetworkConfig.class)); 125 126 doReturn(mMobile.tracker) 127 .when(mNetFactory).createTracker(eq(TYPE_MOBILE), isA(NetworkConfig.class)); 128 doReturn(mWifi.tracker) 129 .when(mNetFactory).createTracker(eq(TYPE_WIFI), isA(NetworkConfig.class)); 130 131 final ArgumentCaptor<Handler> trackerHandler = createCaptor(); 132 doNothing().when(mMobile.tracker) 133 .startMonitoring(isA(Context.class), trackerHandler.capture()); 134 135 mService = new ConnectivityService( 136 mServiceContext, mNetManager, mStatsService, mPolicyService, mNetFactory); 137 mService.systemReady(); 138 139 mTrackerHandler = trackerHandler.getValue(); 140 mTrackerHandler.getLooper().setMessageLogging(new LogPrinter(Log.INFO, TAG)); 141 } 142 143 @Override tearDown()144 public void tearDown() throws Exception { 145 super.tearDown(); 146 } 147 testMobileConnectedAddedRoutes()148 public void testMobileConnectedAddedRoutes() throws Exception { 149 Future<?> nextConnBroadcast; 150 151 // bring up mobile network 152 mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null); 153 mMobile.link.setInterfaceName(MOBILE_IFACE); 154 mMobile.link.addRoute(MOBILE_ROUTE_V4); 155 mMobile.link.addRoute(MOBILE_ROUTE_V6); 156 mMobile.doReturnDefaults(); 157 158 nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE); 159 mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); 160 nextConnBroadcast.get(); 161 162 // verify that both routes were added and DNS was flushed 163 verify(mNetManager).addRoute(eq(MOBILE_IFACE), eq(MOBILE_ROUTE_V4)); 164 verify(mNetManager).addRoute(eq(MOBILE_IFACE), eq(MOBILE_ROUTE_V6)); 165 verify(mNetManager).flushInterfaceDnsCache(MOBILE_IFACE); 166 167 } 168 testMobileWifiHandoff()169 public void testMobileWifiHandoff() throws Exception { 170 Future<?> nextConnBroadcast; 171 172 // bring up mobile network 173 mMobile.info.setDetailedState(DetailedState.CONNECTED, null, null); 174 mMobile.link.setInterfaceName(MOBILE_IFACE); 175 mMobile.link.addRoute(MOBILE_ROUTE_V4); 176 mMobile.link.addRoute(MOBILE_ROUTE_V6); 177 mMobile.doReturnDefaults(); 178 179 nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE); 180 mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); 181 nextConnBroadcast.get(); 182 183 reset(mNetManager); 184 185 // now bring up wifi network 186 mWifi.info.setDetailedState(DetailedState.CONNECTED, null, null); 187 mWifi.link.setInterfaceName(WIFI_IFACE); 188 mWifi.link.addRoute(WIFI_ROUTE_V4); 189 mWifi.link.addRoute(WIFI_ROUTE_V6); 190 mWifi.doReturnDefaults(); 191 192 // expect that mobile will be torn down 193 doReturn(true).when(mMobile.tracker).teardown(); 194 195 nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE); 196 mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget(); 197 nextConnBroadcast.get(); 198 199 // verify that wifi routes added, and teardown requested 200 verify(mNetManager).addRoute(eq(WIFI_IFACE), eq(WIFI_ROUTE_V4)); 201 verify(mNetManager).addRoute(eq(WIFI_IFACE), eq(WIFI_ROUTE_V6)); 202 verify(mNetManager).flushInterfaceDnsCache(WIFI_IFACE); 203 verify(mMobile.tracker).teardown(); 204 205 reset(mNetManager, mMobile.tracker); 206 207 // tear down mobile network, as requested 208 mMobile.info.setDetailedState(DetailedState.DISCONNECTED, null, null); 209 mMobile.link.clear(); 210 mMobile.doReturnDefaults(); 211 212 nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION_IMMEDIATE); 213 mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); 214 nextConnBroadcast.get(); 215 216 verify(mNetManager).removeRoute(eq(MOBILE_IFACE), eq(MOBILE_ROUTE_V4)); 217 verify(mNetManager).removeRoute(eq(MOBILE_IFACE), eq(MOBILE_ROUTE_V6)); 218 219 } 220 parse(String addr)221 private static InetAddress parse(String addr) { 222 return InetAddress.parseNumericAddress(addr); 223 } 224 } 225