• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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