1 package org.robolectric.shadows;
2 
3 import static android.os.Build.VERSION_CODES.LOLLIPOP;
4 import static android.os.Build.VERSION_CODES.M;
5 import static org.assertj.core.api.Assertions.assertThat;
6 import static org.junit.Assert.assertEquals;
7 import static org.junit.Assert.assertTrue;
8 import static org.mockito.Mockito.spy;
9 import static org.mockito.Mockito.times;
10 import static org.mockito.Mockito.verify;
11 import static org.robolectric.Shadows.shadowOf;
12 
13 import android.content.Context;
14 import android.net.ConnectivityManager;
15 import android.net.Network;
16 import android.net.NetworkInfo;
17 import android.net.NetworkRequest;
18 import android.telephony.TelephonyManager;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.robolectric.RobolectricTestRunner;
23 import org.robolectric.RuntimeEnvironment;
24 import org.robolectric.annotation.Config;
25 
26 @RunWith(RobolectricTestRunner.class)
27 public class ShadowConnectivityManagerTest {
28   private ConnectivityManager connectivityManager;
29   private ShadowNetworkInfo shadowOfActiveNetworkInfo;
30   private ShadowConnectivityManager shadowConnectivityManager;
31 
32   @Before
setUp()33   public void setUp() throws Exception {
34     connectivityManager =
35         (ConnectivityManager)
36             RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE);
37     shadowConnectivityManager = shadowOf(connectivityManager);
38     shadowOfActiveNetworkInfo = shadowOf(connectivityManager.getActiveNetworkInfo());
39   }
40 
41   @Test
getActiveNetworkInfo_shouldInitializeItself()42   public void getActiveNetworkInfo_shouldInitializeItself() {
43     assertThat(connectivityManager.getActiveNetworkInfo()).isNotNull();
44   }
45 
46   @Test
getActiveNetworkInfo_shouldReturnTrueCorrectly()47   public void getActiveNetworkInfo_shouldReturnTrueCorrectly() {
48     shadowOfActiveNetworkInfo.setConnectionStatus(true);
49     assertThat(connectivityManager.getActiveNetworkInfo().isConnectedOrConnecting()).isTrue();
50     assertTrue(connectivityManager.getActiveNetworkInfo().isConnected());
51 
52     shadowOfActiveNetworkInfo.setConnectionStatus(false);
53     assertThat(connectivityManager.getActiveNetworkInfo().isConnectedOrConnecting()).isFalse();
54     assertThat(connectivityManager.getActiveNetworkInfo().isConnected()).isFalse();
55   }
56 
57   @Test
getNetworkInfo_shouldReturnDefaultNetworks()58   public void getNetworkInfo_shouldReturnDefaultNetworks() throws Exception {
59     NetworkInfo wifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
60     assertThat(wifi.getDetailedState()).isEqualTo(NetworkInfo.DetailedState.DISCONNECTED);
61 
62     NetworkInfo mobile = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
63     assertThat(mobile.getDetailedState()).isEqualTo(NetworkInfo.DetailedState.CONNECTED);
64   }
65 
66   @Test @Config(minSdk = LOLLIPOP)
getNetworkInfo_shouldReturnSomeForAllNetworks()67   public void getNetworkInfo_shouldReturnSomeForAllNetworks() throws Exception {
68     Network[] allNetworks = connectivityManager.getAllNetworks();
69     for (Network network: allNetworks) {
70       NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
71       assertThat(networkInfo).isNotNull();
72     }
73   }
74 
75   @Test @Config(minSdk = LOLLIPOP)
getNetworkInfo_shouldReturnAddedNetwork()76   public void getNetworkInfo_shouldReturnAddedNetwork() throws Exception {
77     Network vpnNetwork = ShadowNetwork.newInstance(123);
78     NetworkInfo vpnNetworkInfo = ShadowNetworkInfo.newInstance(NetworkInfo.DetailedState.CONNECTED,
79         ConnectivityManager.TYPE_VPN, 0, true, true);
80     shadowConnectivityManager.addNetwork(vpnNetwork, vpnNetworkInfo);
81 
82     NetworkInfo returnedNetworkInfo = connectivityManager.getNetworkInfo(vpnNetwork);
83     assertThat(returnedNetworkInfo).isSameAs(vpnNetworkInfo);
84   }
85 
86   @Test @Config(minSdk = LOLLIPOP)
getNetworkInfo_shouldNotReturnRemovedNetwork()87   public void getNetworkInfo_shouldNotReturnRemovedNetwork() throws Exception {
88     Network wifiNetwork = ShadowNetwork.newInstance(ShadowConnectivityManager.NET_ID_WIFI);
89     shadowConnectivityManager.removeNetwork(wifiNetwork);
90 
91     NetworkInfo returnedNetworkInfo = connectivityManager.getNetworkInfo(wifiNetwork);
92     assertThat(returnedNetworkInfo).isNull();
93   }
94 
95   @Test
setConnectionType_shouldReturnTypeCorrectly()96   public void setConnectionType_shouldReturnTypeCorrectly() {
97     shadowOfActiveNetworkInfo.setConnectionType(ConnectivityManager.TYPE_MOBILE);
98     assertThat(ConnectivityManager.TYPE_MOBILE).isEqualTo(shadowOfActiveNetworkInfo.getType());
99 
100     shadowOfActiveNetworkInfo.setConnectionType(ConnectivityManager.TYPE_WIFI);
101     assertThat(ConnectivityManager.TYPE_WIFI).isEqualTo(shadowOfActiveNetworkInfo.getType());
102   }
103 
104   @Test
shouldGetAndSetBackgroundDataSetting()105   public void shouldGetAndSetBackgroundDataSetting() throws Exception {
106     assertThat(connectivityManager.getBackgroundDataSetting()).isFalse();
107     shadowConnectivityManager.setBackgroundDataSetting(true);
108     assertThat(connectivityManager.getBackgroundDataSetting()).isTrue();
109   }
110 
111   @Test
setActiveNetworkInfo_shouldSetActiveNetworkInfo()112   public void setActiveNetworkInfo_shouldSetActiveNetworkInfo() throws Exception {
113     shadowConnectivityManager.setActiveNetworkInfo(null);
114     assertThat(connectivityManager.getActiveNetworkInfo()).isNull();
115     shadowConnectivityManager.setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null,
116         ConnectivityManager.TYPE_MOBILE_HIPRI, TelephonyManager.NETWORK_TYPE_EDGE, true, false));
117 
118     NetworkInfo info = connectivityManager.getActiveNetworkInfo();
119 
120     assertThat(ConnectivityManager.TYPE_MOBILE_HIPRI).isEqualTo(info.getType());
121     assertThat(TelephonyManager.NETWORK_TYPE_EDGE).isEqualTo(info.getSubtype());
122     assertThat(info.isAvailable()).isTrue();
123     assertThat(info.isConnected()).isFalse();
124   }
125 
126   @Test
127   @Config(minSdk = M)
getActiveNetwork_shouldInitializeItself()128   public void getActiveNetwork_shouldInitializeItself() {
129     assertThat(connectivityManager.getActiveNetwork()).isNotNull();
130   }
131 
132   @Test
133   @Config(minSdk = M)
getActiveNetwork_nullIfNetworkNotActive()134   public void getActiveNetwork_nullIfNetworkNotActive() {
135     shadowConnectivityManager.setDefaultNetworkActive(false);
136     assertThat(connectivityManager.getActiveNetwork()).isNull();
137   }
138 
139   @Test
140   @Config(minSdk = M)
setActiveNetworkInfo_shouldSetActiveNetwork()141   public void setActiveNetworkInfo_shouldSetActiveNetwork() throws Exception {
142     shadowConnectivityManager.setActiveNetworkInfo(null);
143     assertThat(connectivityManager.getActiveNetworkInfo()).isNull();
144     shadowConnectivityManager.setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null,
145         ConnectivityManager.TYPE_MOBILE_HIPRI, TelephonyManager.NETWORK_TYPE_EDGE, true, false));
146 
147     NetworkInfo info = connectivityManager.getActiveNetworkInfo();
148 
149     assertThat(ConnectivityManager.TYPE_MOBILE_HIPRI).isEqualTo(info.getType());
150     assertThat(TelephonyManager.NETWORK_TYPE_EDGE).isEqualTo(info.getSubtype());
151     assertThat(info.isAvailable()).isTrue();
152     assertThat(info.isConnected()).isFalse();
153     assertThat(shadowOf(connectivityManager.getActiveNetwork()).getNetId()).isEqualTo(info.getType());
154   }
155 
156   @Test
getAllNetworkInfo_shouldReturnAllNetworkInterfaces()157   public void getAllNetworkInfo_shouldReturnAllNetworkInterfaces() throws Exception {
158     NetworkInfo[] infos = connectivityManager.getAllNetworkInfo();
159     assertThat(infos).hasSize(2);
160     assertThat(infos).contains(connectivityManager.getActiveNetworkInfo());
161 
162     shadowConnectivityManager.setActiveNetworkInfo(null);
163     assertThat(connectivityManager.getAllNetworkInfo()).isEmpty();
164   }
165 
166   @Test
167   @Config(minSdk = LOLLIPOP)
getAllNetworkInfo_nullIfNetworkNotActive()168   public void getAllNetworkInfo_nullIfNetworkNotActive() {
169     shadowConnectivityManager.setDefaultNetworkActive(false);
170     assertThat(connectivityManager.getAllNetworkInfo()).isNull();
171   }
172 
173   @Test @Config(minSdk = LOLLIPOP)
getAllNetworks_shouldReturnAllNetworks()174   public void getAllNetworks_shouldReturnAllNetworks() throws Exception {
175     Network[] networks = connectivityManager.getAllNetworks();
176     assertThat(networks).hasSize(2);
177   }
178 
179   @Test @Config(minSdk = LOLLIPOP)
getAllNetworks_shouldReturnNoNetworksWhenCleared()180   public void getAllNetworks_shouldReturnNoNetworksWhenCleared() throws Exception {
181     shadowConnectivityManager.clearAllNetworks();
182     Network[] networks = connectivityManager.getAllNetworks();
183     assertThat(networks).isEmpty();
184   }
185 
186   @Test @Config(minSdk = LOLLIPOP)
getAllNetworks_shouldReturnAddedNetworks()187   public void getAllNetworks_shouldReturnAddedNetworks() throws Exception {
188     // Let's start clear.
189     shadowConnectivityManager.clearAllNetworks();
190 
191     // Add a "VPN network".
192     Network vpnNetwork = ShadowNetwork.newInstance(123);
193     NetworkInfo vpnNetworkInfo = ShadowNetworkInfo.newInstance(NetworkInfo.DetailedState.CONNECTED,
194         ConnectivityManager.TYPE_VPN, 0, true, true);
195     shadowConnectivityManager.addNetwork(vpnNetwork, vpnNetworkInfo);
196 
197     Network[] networks = connectivityManager.getAllNetworks();
198     assertThat(networks).hasSize(1);
199 
200     Network returnedNetwork = networks[0];
201     assertThat(returnedNetwork).isSameAs(vpnNetwork);
202 
203     NetworkInfo returnedNetworkInfo = connectivityManager.getNetworkInfo(returnedNetwork);
204     assertThat(returnedNetworkInfo).isSameAs(vpnNetworkInfo);
205   }
206 
207   @Test @Config(minSdk = LOLLIPOP)
getAllNetworks_shouldNotReturnRemovedNetworks()208   public void getAllNetworks_shouldNotReturnRemovedNetworks() throws Exception {
209     Network wifiNetwork = ShadowNetwork.newInstance(ShadowConnectivityManager.NET_ID_WIFI);
210     shadowConnectivityManager.removeNetwork(wifiNetwork);
211 
212     Network[] networks = connectivityManager.getAllNetworks();
213     assertThat(networks).hasSize(1);
214 
215     Network returnedNetwork = networks[0];
216     ShadowNetwork shadowReturnedNetwork = shadowOf(returnedNetwork);
217     assertThat(shadowReturnedNetwork.getNetId()).isNotEqualTo(ShadowConnectivityManager.NET_ID_WIFI);
218   }
219 
220   @Test
getNetworkPreference_shouldGetDefaultValue()221   public void getNetworkPreference_shouldGetDefaultValue() throws Exception {
222     assertThat(connectivityManager.getNetworkPreference()).isEqualTo(ConnectivityManager.DEFAULT_NETWORK_PREFERENCE);
223   }
224 
225   @Test
setNetworkPreference_shouldSetDefaultValue()226   public void setNetworkPreference_shouldSetDefaultValue() throws Exception {
227     connectivityManager.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);
228     assertThat(connectivityManager.getNetworkPreference()).isEqualTo(connectivityManager.getNetworkPreference());
229     connectivityManager.setNetworkPreference(ConnectivityManager.TYPE_WIFI);
230     assertThat(connectivityManager.getNetworkPreference()).isEqualTo(ConnectivityManager.TYPE_WIFI);
231   }
232 
233   @Test @Config(minSdk = LOLLIPOP)
getNetworkCallbacks_shouldHaveEmptyDefault()234   public void getNetworkCallbacks_shouldHaveEmptyDefault() throws Exception {
235     assertEquals(0, shadowConnectivityManager.getNetworkCallbacks().size());
236   }
237 
createSimpleCallback()238   private static ConnectivityManager.NetworkCallback createSimpleCallback() {
239     return new ConnectivityManager.NetworkCallback() {
240       @Override
241       public void onAvailable(Network network) {}
242       @Override
243       public void onLost(Network network) {}
244     };
245   }
246 
247   @Test @Config(minSdk = LOLLIPOP)
registerCallback_shouldAddCallback()248   public void registerCallback_shouldAddCallback() throws Exception {
249     NetworkRequest.Builder builder = new NetworkRequest.Builder();
250     ConnectivityManager.NetworkCallback callback = createSimpleCallback();
251     connectivityManager.registerNetworkCallback(builder.build(), callback);
252     assertEquals(1, shadowConnectivityManager.getNetworkCallbacks().size());
253   }
254 
255   @Test @Config(minSdk = LOLLIPOP)
unregisterCallback_shouldRemoveCallbacks()256   public void unregisterCallback_shouldRemoveCallbacks() throws Exception {
257     NetworkRequest.Builder builder = new NetworkRequest.Builder();
258     // Add two different callbacks.
259     ConnectivityManager.NetworkCallback callback1 = createSimpleCallback();
260     ConnectivityManager.NetworkCallback callback2 = createSimpleCallback();
261     connectivityManager.registerNetworkCallback(builder.build(), callback1);
262     connectivityManager.registerNetworkCallback(builder.build(), callback2);
263     // Remove one at the time.
264     assertEquals(2, shadowConnectivityManager.getNetworkCallbacks().size());
265     connectivityManager.unregisterNetworkCallback(callback2);
266     assertEquals(1, shadowConnectivityManager.getNetworkCallbacks().size());
267     connectivityManager.unregisterNetworkCallback(callback1);
268     assertEquals(0, shadowConnectivityManager.getNetworkCallbacks().size());
269   }
270 
271   @Test(expected=IllegalArgumentException.class) @Config(minSdk = LOLLIPOP)
unregisterCallback_shouldNotAllowNullCallback()272   public void unregisterCallback_shouldNotAllowNullCallback() throws Exception {
273     // Verify that exception is thrown.
274     connectivityManager.unregisterNetworkCallback((ConnectivityManager.NetworkCallback) null);
275   }
276 
277   @Test
isActiveNetworkMetered_defaultsToTrue()278   public void isActiveNetworkMetered_defaultsToTrue() {
279     assertThat(connectivityManager.isActiveNetworkMetered()).isTrue();
280   }
281 
282   @Test
isActiveNetworkMetered_mobileIsMetered()283   public void isActiveNetworkMetered_mobileIsMetered() {
284     shadowConnectivityManager.setActiveNetworkInfo(
285         connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE));
286     assertThat(connectivityManager.isActiveNetworkMetered()).isTrue();
287   }
288 
289   @Test
isActiveNetworkMetered_nonMobileIsUnmetered()290   public void isActiveNetworkMetered_nonMobileIsUnmetered() {
291     shadowConnectivityManager.setActiveNetworkInfo(
292         connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI));
293     assertThat(connectivityManager.isActiveNetworkMetered()).isFalse();
294   }
295 
296   @Test
isActiveNetworkMetered_noActiveNetwork()297   public void isActiveNetworkMetered_noActiveNetwork() {
298     shadowConnectivityManager.setActiveNetworkInfo(null);
299     assertThat(connectivityManager.isActiveNetworkMetered()).isFalse();
300   }
301 
302   @Test
isActiveNetworkMetered_noDefaultNetworkActive()303   public void isActiveNetworkMetered_noDefaultNetworkActive() {
304     shadowConnectivityManager.setDefaultNetworkActive(false);
305     assertThat(connectivityManager.isActiveNetworkMetered()).isFalse();
306   }
307 
308   @Test
309   @Config(minSdk = M)
bindProcessToNetwork_should()310   public void bindProcessToNetwork_should() {
311     Network network = ShadowNetwork.newInstance(789);
312     connectivityManager.bindProcessToNetwork(network);
313     assertThat(connectivityManager.getBoundNetworkForProcess()).isSameAs(network);
314   }
315 
316   @Test
317   @Config(minSdk = LOLLIPOP)
isDefaultNetworkActive_defaultActive()318   public void isDefaultNetworkActive_defaultActive() {
319     assertThat(shadowConnectivityManager.isDefaultNetworkActive()).isTrue();
320   }
321 
322   @Test
323   @Config(minSdk = LOLLIPOP)
isDefaultNetworkActive_notActive()324   public void isDefaultNetworkActive_notActive() {
325     shadowConnectivityManager.setDefaultNetworkActive(false);
326     assertThat(shadowConnectivityManager.isDefaultNetworkActive()).isFalse();
327   }
328 
createSimpleOnNetworkActiveListener()329   private static ConnectivityManager.OnNetworkActiveListener createSimpleOnNetworkActiveListener() {
330     return new ConnectivityManager.OnNetworkActiveListener() {
331       @Override
332       public void onNetworkActive() {}
333     };
334   }
335 
336   @Test
337   @Config(minSdk = LOLLIPOP)
addDefaultNetworkActiveListener_shouldAddListener()338   public void addDefaultNetworkActiveListener_shouldAddListener() throws Exception {
339     ConnectivityManager.OnNetworkActiveListener listener1 =
340         spy(createSimpleOnNetworkActiveListener());
341     ConnectivityManager.OnNetworkActiveListener listener2 =
342         spy(createSimpleOnNetworkActiveListener());
343     connectivityManager.addDefaultNetworkActiveListener(listener1);
344     connectivityManager.addDefaultNetworkActiveListener(listener2);
345 
346     shadowConnectivityManager.setDefaultNetworkActive(true);
347 
348     verify(listener1).onNetworkActive();
349     verify(listener2).onNetworkActive();
350   }
351 
352   @Test
353   @Config(minSdk = LOLLIPOP)
removeDefaultNetworkActiveListener_shouldRemoveListeners()354   public void removeDefaultNetworkActiveListener_shouldRemoveListeners() throws Exception {
355     // Add two different callbacks.
356     ConnectivityManager.OnNetworkActiveListener listener1 =
357         spy(createSimpleOnNetworkActiveListener());
358     ConnectivityManager.OnNetworkActiveListener listener2 =
359         spy(createSimpleOnNetworkActiveListener());
360     connectivityManager.addDefaultNetworkActiveListener(listener1);
361     connectivityManager.addDefaultNetworkActiveListener(listener2);
362 
363     shadowConnectivityManager.setDefaultNetworkActive(true);
364 
365     verify(listener1).onNetworkActive();
366     verify(listener2).onNetworkActive();
367     // Remove one at the time.
368     connectivityManager.removeDefaultNetworkActiveListener(listener2);
369 
370     shadowConnectivityManager.setDefaultNetworkActive(true);
371 
372     verify(listener1, times(2)).onNetworkActive();
373     verify(listener2).onNetworkActive();
374 
375     connectivityManager.removeDefaultNetworkActiveListener(listener1);
376 
377     shadowConnectivityManager.setDefaultNetworkActive(true);
378 
379     verify(listener1, times(2)).onNetworkActive();
380     verify(listener2).onNetworkActive();
381   }
382 
383   @Test(expected = IllegalArgumentException.class)
384   @Config(minSdk = LOLLIPOP)
removeDefaultNetworkActiveListener_shouldNotAllowNullListener()385   public void removeDefaultNetworkActiveListener_shouldNotAllowNullListener() throws Exception {
386     // Verify that exception is thrown.
387     connectivityManager.removeDefaultNetworkActiveListener(null);
388   }
389 }
390 
391