1 /*
2  * Copyright (C) 2019 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.internal.telephony;
18 
19 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyBoolean;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.Matchers.eq;
28 import static org.mockito.Mockito.clearInvocations;
29 import static org.mockito.Mockito.doReturn;
30 import static org.mockito.Mockito.never;
31 import static org.mockito.Mockito.verify;
32 
33 import android.content.Context;
34 import android.net.Network;
35 import android.net.NetworkCapabilities;
36 import android.net.NetworkRequest;
37 import android.net.TelephonyNetworkSpecifier;
38 import android.os.PersistableBundle;
39 import android.telephony.CarrierConfigManager;
40 import android.telephony.CellIdentityLte;
41 import android.telephony.NetworkRegistrationInfo;
42 import android.telephony.PhoneCapability;
43 import android.telephony.SubscriptionManager;
44 import android.telephony.TelephonyManager;
45 import android.test.suitebuilder.annotation.SmallTest;
46 import android.testing.AndroidTestingRunner;
47 import android.testing.TestableLooper;
48 
49 import org.junit.After;
50 import org.junit.Before;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 import org.mockito.Mock;
54 
55 @RunWith(AndroidTestingRunner.class)
56 @TestableLooper.RunWithLooper
57 public class CellularNetworkValidatorTest extends TelephonyTest {
58     private CellularNetworkValidator mValidatorUT;
59     private static final PhoneCapability CAPABILITY_WITH_VALIDATION_SUPPORTED =
60             new PhoneCapability(1, 1, null, true, new int[0]);
61     private static final PhoneCapability CAPABILITY_WITHOUT_VALIDATION_SUPPORTED =
62             new PhoneCapability(1, 1, null, false, new int[0]);
63     private final CellIdentityLte mCellIdentityLte1 = new CellIdentityLte(123, 456, 0, 0, 111);
64     private final CellIdentityLte mCellIdentityLte2 = new CellIdentityLte(321, 654, 0, 0, 222);
65     @Mock
66     CellularNetworkValidator.ValidationCallback mCallback;
67 
68     @Before
setUp()69     public void setUp() throws Exception {
70         super.setUp(getClass().getSimpleName());
71 
72         doReturn(CAPABILITY_WITH_VALIDATION_SUPPORTED).when(mPhoneConfigurationManager)
73                 .getCurrentPhoneCapability();
74         mValidatorUT = new CellularNetworkValidator(mContext);
75         doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
76         processAllMessages();
77         setCacheTtlInCarrierConfig(5000);
78     }
79 
80     @After
tearDown()81     public void tearDown() throws Exception {
82         mValidatorUT.stopValidation();
83         super.tearDown();
84     }
85 
86     /**
87      * Test that a single phone case results in our phone being active and the RIL called
88      */
89     @Test
90     @SmallTest
testValidationSupported()91     public void testValidationSupported() {
92         doReturn(CAPABILITY_WITH_VALIDATION_SUPPORTED).when(mPhoneConfigurationManager)
93                 .getCurrentPhoneCapability();
94         assertTrue(mValidatorUT.isValidationFeatureSupported());
95 
96         doReturn(CAPABILITY_WITHOUT_VALIDATION_SUPPORTED).when(mPhoneConfigurationManager)
97                 .getCurrentPhoneCapability();
98         assertFalse(mValidatorUT.isValidationFeatureSupported());
99     }
100 
101     /**
102      * Test that a single phone case results in our phone being active and the RIL called
103      */
104     @Test
105     @SmallTest
testValidateSuccess()106     public void testValidateSuccess() {
107         int subId = 1;
108         int timeout = 1000;
109         mValidatorUT.validate(subId, timeout, true, mCallback);
110         assertInValidation(subId);
111 
112         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
113                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
114         assertValidationResult(subId, true);
115     }
116 
117     @Test
118     @SmallTest
testValidateTimeout()119     public void testValidateTimeout() {
120         int subId = 1;
121         int timeout = 100;
122         mValidatorUT.validate(subId, timeout, true, mCallback);
123         assertInValidation(subId);
124 
125         // Wait for timeout
126         moveTimeForward(timeout);
127         processAllMessages();
128         assertValidationResult(subId, false);
129     }
130 
131     @Test
132     @SmallTest
testValidateFailure()133     public void testValidateFailure() {
134         int subId = 1;
135         int timeout = 100;
136         mValidatorUT.validate(subId, timeout, true, mCallback);
137         assertInValidation(subId);
138         mValidatorUT.mNetworkCallback.onUnavailable();
139         assertValidationResult(subId, false);
140     }
141 
142     @Test
143     @SmallTest
testNetworkAvailableNotValidated()144     public void testNetworkAvailableNotValidated() {
145         int subId = 1;
146         int timeout = 100;
147         mValidatorUT.validate(subId, timeout, true, mCallback);
148         assertInValidation(subId);
149 
150         mValidatorUT.mNetworkCallback.onAvailable(new Network(100));
151         assertInValidation(subId);
152 
153         // Wait for timeout
154         moveTimeForward(timeout);
155         processAllMessages();
156 
157         assertValidationResult(subId, false);
158     }
159 
160     @Test
161     @SmallTest
testSkipRecentlyValidatedNetwork()162     public void testSkipRecentlyValidatedNetwork() {
163         int subId = 1;
164         int timeout = 1000;
165         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
166                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
167                 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
168                 .setCellIdentity(mCellIdentityLte1)
169                 .build();
170         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
171                 anyInt(), anyInt());
172         testValidateSuccess();
173 
174         resetStates();
175         mValidatorUT.validate(subId, timeout, true, mCallback);
176         assertInValidation(subId);
177 
178         // As recently validated, onAvailable should trigger switch.
179         mValidatorUT.mNetworkCallback.onAvailable(new Network(100));
180         assertValidationResult(subId, true);
181     }
182 
183     @Test
184     @SmallTest
testDoNotSkipIfValidationFailed()185     public void testDoNotSkipIfValidationFailed() {
186         int subId = 1;
187         int timeout = 1000;
188         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
189                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
190                 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
191                 .setCellIdentity(mCellIdentityLte1)
192                 .build();
193         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
194                 anyInt(), anyInt());
195         testValidateFailure();
196 
197         resetStates();
198         mValidatorUT.validate(subId, timeout, true, mCallback);
199         assertInValidation(subId);
200         // Last time validation fialed, onAvailable should NOT trigger switch.
201         mValidatorUT.mNetworkCallback.onAvailable(new Network(100));
202         assertInValidation(subId);
203     }
204 
205     @Test
206     @SmallTest
testDoNotSkipIfCacheExpires()207     public void testDoNotSkipIfCacheExpires() {
208         int subId = 1;
209         int timeout = 1000;
210         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
211                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
212                 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
213                 .setCellIdentity(mCellIdentityLte1)
214                 .build();
215         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
216                 anyInt(), anyInt());
217         testValidateSuccess();
218 
219         // Mark mValidationCacheTtl to only 1 second.
220         setCacheTtlInCarrierConfig(1000);
221         waitForMs(1100);
222 
223         resetStates();
224         mValidatorUT.validate(subId, timeout, true, mCallback);
225         assertInValidation(subId);
226 
227         // Last time validation expired, onAvailable should NOT trigger switch.
228         mValidatorUT.mNetworkCallback.onAvailable(new Network(100));
229         assertInValidation(subId);
230     }
231 
232     @Test
233     @SmallTest
testNetworkCachingOfMultipleSub()234     public void testNetworkCachingOfMultipleSub() {
235         int timeout = 1000;
236         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
237                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
238                 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
239                 .setCellIdentity(mCellIdentityLte1)
240                 .build();
241         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
242                 anyInt(), anyInt());
243 
244         assertNetworkRecentlyValidated(1, false);
245         assertNetworkRecentlyValidated(2, false);
246         assertNetworkRecentlyValidated(3, false);
247         // Validate sub 1, 2, and 3.
248         mValidatorUT.validate(1, timeout, true, mCallback);
249         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
250                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
251         assertValidationResult(1, true);
252         assertNetworkRecentlyValidated(1, true);
253         assertNetworkRecentlyValidated(2, false);
254         assertNetworkRecentlyValidated(3, false);
255         mValidatorUT.validate(2, timeout, true, mCallback);
256         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
257                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
258         assertValidationResult(2, true);
259         mValidatorUT.validate(3, timeout, true, mCallback);
260         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
261                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
262         assertValidationResult(3, true);
263         assertNetworkRecentlyValidated(1, true);
264         assertNetworkRecentlyValidated(2, true);
265         assertNetworkRecentlyValidated(3, true);
266 
267         // When re-validating sub 3, onAvailable should trigger validation callback.
268         resetStates();
269         mValidatorUT.validate(3, timeout, true, mCallback);
270         mValidatorUT.mNetworkCallback.onAvailable(new Network(100));
271         assertValidationResult(3, true);
272         // Mark sub 2 validation failed. Should clear the network from cache.
273         resetStates();
274         mValidatorUT.validate(2, timeout, true, mCallback);
275         mValidatorUT.mNetworkCallback.onLost(new Network(100));
276         assertNetworkRecentlyValidated(2, false);
277 
278         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
279                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
280                 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
281                 .setCellIdentity(mCellIdentityLte1)
282                 .build();
283         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
284                 anyInt(), anyInt());
285     }
286 
287     @Test
288     @SmallTest
testNetworkCachingOfMultipleNetworks()289     public void testNetworkCachingOfMultipleNetworks() {
290         int timeout = 1000;
291         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
292                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
293                 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
294                 .setCellIdentity(mCellIdentityLte1)
295                 .build();
296         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
297                 anyInt(), anyInt());
298 
299         // Validate sub 1.
300         assertNetworkRecentlyValidated(1, false);
301         mValidatorUT.validate(1, timeout, true, mCallback);
302         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
303                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
304         assertNetworkRecentlyValidated(1, true);
305 
306         // Change reg state to a different network.
307         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
308                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
309                 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
310                 .setCellIdentity(mCellIdentityLte2)
311                 .build();
312         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
313                 anyInt(), anyInt());
314 
315         // Should NOT skip validation.
316         assertNetworkRecentlyValidated(1, false);
317     }
318 
319     @Test
320     @SmallTest
testNetworkCachingOverflow()321     public void testNetworkCachingOverflow() {
322         int timeout = 1000;
323         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
324                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
325                 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
326                 .setCellIdentity(mCellIdentityLte1)
327                 .build();
328         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
329                 anyInt(), anyInt());
330 
331         for (int subId = 8; subId <= 100; subId++) {
332             mValidatorUT.validate(subId, timeout, true, mCallback);
333             mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
334                     .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
335             assertNetworkRecentlyValidated(subId, true);
336         }
337 
338         // Last 10 subs are kept in cache.
339         for (int subId = 1; subId <= 90; subId++) {
340             assertNetworkRecentlyValidated(subId, false);
341         }
342         // Last 10 subs are kept in cache.
343         for (int subId = 91; subId <= 100; subId++) {
344             assertNetworkRecentlyValidated(subId, true);
345         }
346     }
347 
348     @Test
349     @SmallTest
testOnNetworkAvailable()350     public void testOnNetworkAvailable() {
351         int subId = 1;
352         int timeout = 1000;
353         mValidatorUT.validate(subId, timeout, true, mCallback);
354         Network network = new Network(100);
355         mValidatorUT.mNetworkCallback.onAvailable(network);
356 
357         assertInValidation(subId);
358         verify(mCallback).onNetworkAvailable(network, subId);
359     }
360 
361     @Test
362     @SmallTest
testReleaseRequestAfterValidation_shouldReleaseImmediately()363     public void testReleaseRequestAfterValidation_shouldReleaseImmediately() {
364         int subId = 1;
365         int timeout = 1000;
366         mValidatorUT.validate(subId, timeout, true, mCallback);
367         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
368                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
369         assertValidationResult(subId, true);
370     }
371 
372     @Test
373     @SmallTest
testDoNotReleaseRequestAfterValidation_shouldReleaseLater()374     public void testDoNotReleaseRequestAfterValidation_shouldReleaseLater() {
375         int subId = 1;
376         int timeout = 1000;
377         mValidatorUT.validate(subId, timeout, false, mCallback);
378         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
379                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
380         verify(mCallback).onValidationDone(true, subId);
381         assertInValidation(subId);
382         moveTimeForward(1000);
383         processAllMessages();
384         assertValidationResult(subId, true);
385     }
386 
387     @Test
388     @SmallTest
testDoNotReleaseRequestAfterValidation_validationFails_shouldReleaseImmediately()389     public void testDoNotReleaseRequestAfterValidation_validationFails_shouldReleaseImmediately() {
390         int subId = 1;
391         int timeout = 1000;
392         mValidatorUT.validate(subId, timeout, false, mCallback);
393         mValidatorUT.mNetworkCallback.onLost(new Network(100));
394         assertValidationResult(subId, false);
395     }
396 
397     @Test
398     @SmallTest
testDoNotReleaseRequestAfterValidation_timeout_shouldReleaseImmediately()399     public void testDoNotReleaseRequestAfterValidation_timeout_shouldReleaseImmediately() {
400         int subId = 1;
401         int timeout = 1000;
402         mValidatorUT.validate(subId, timeout, false, mCallback);
403         assertInValidation(subId);
404         moveTimeForward(timeout);
405         processAllMessages();
406         assertValidationResult(subId, false);
407     }
408 
409     @Test
410     @SmallTest
testDoNotReleaseRequestAfterValidation_BackToBackRequest()411     public void testDoNotReleaseRequestAfterValidation_BackToBackRequest() {
412         int subId1 = 1;
413         int timeout = 1000;
414         mValidatorUT.validate(subId1, timeout, false, mCallback);
415         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
416                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
417         verify(mCallback).onValidationDone(true, subId1);
418         assertInValidation(subId1);
419 
420         resetStates();
421         int subId2 = 2;
422         mValidatorUT.validate(subId2, timeout, false, mCallback);
423         assertInValidation(subId2);
424         mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
425                 .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
426         verify(mCallback).onValidationDone(true, subId2);
427         assertInValidation(subId2);
428         moveTimeForward(1000);
429         processAllMessages();
430         assertValidationResult(subId2, true);
431         // No callback should be triggered on subId1
432         verify(mCallback, never()).onValidationDone(anyBoolean(), eq(subId1));
433     }
434 
assertNetworkRecentlyValidated(int subId, boolean shouldBeRecentlyValidated)435     private void assertNetworkRecentlyValidated(int subId, boolean shouldBeRecentlyValidated) {
436         // Start validation and send network available callback.
437         resetStates();
438         mValidatorUT.validate(subId, 1000, true, mCallback);
439         mValidatorUT.mNetworkCallback.onAvailable(new Network(1000));
440 
441         if (shouldBeRecentlyValidated) {
442             assertValidationResult(subId, true);
443         } else {
444             assertInValidation(subId);
445         }
446 
447         mValidatorUT.stopValidation();
448         resetStates();
449     }
450 
assertValidationResult(int subId, boolean shouldPass)451     private void assertValidationResult(int subId, boolean shouldPass) {
452         // Verify that validation is over.
453         verify(mConnectivityManager).unregisterNetworkCallback(eq(mValidatorUT.mNetworkCallback));
454         assertFalse(mValidatorUT.mHandler.hasMessagesOrCallbacks());
455         assertFalse(mValidatorUT.isValidating());
456         assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
457                 mValidatorUT.getSubIdInValidation());
458 
459         // Verify result.
460         verify(mCallback).onValidationDone(shouldPass, subId);
461     }
462 
assertInValidation(int subId)463     private void assertInValidation(int subId) {
464         assertEquals(subId, mValidatorUT.getSubIdInValidation());
465         assertTrue(mValidatorUT.mHandler.hasMessagesOrCallbacks());
466         assertEquals(subId, mValidatorUT.getSubIdInValidation());
467         NetworkRequest expectedRequest = new NetworkRequest.Builder()
468                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
469                 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
470                 .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
471                         .setSubscriptionId(subId).build())
472                 .build();
473         verify(mConnectivityManager).requestNetwork(
474                 eq(expectedRequest), eq(mValidatorUT.mNetworkCallback), any());
475         assertTrue(mValidatorUT.isValidating());
476     }
477 
resetStates()478     private void resetStates() {
479         clearInvocations(mConnectivityManager);
480         clearInvocations(mCallback);
481     }
482 
setCacheTtlInCarrierConfig(long ttl)483     private void setCacheTtlInCarrierConfig(long ttl) {
484         // Mark to skip validation in 5 seconds.
485         CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
486                 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
487         PersistableBundle bundle = carrierConfigManager.getConfigForSubId(anyInt());
488         bundle.putLong(CarrierConfigManager.KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG, ttl);
489     }
490 }
491