1 /*
2  * Copyright 2020 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.google.android.iwlan.epdg;
18 
19 import static android.net.DnsResolver.TYPE_A;
20 import static android.net.DnsResolver.TYPE_AAAA;
21 
22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
23 
24 import static org.junit.Assert.assertArrayEquals;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertThrows;
28 import static org.junit.Assert.assertTrue;
29 import static org.mockito.Mockito.any;
30 import static org.mockito.Mockito.anyInt;
31 import static org.mockito.Mockito.anyString;
32 import static org.mockito.Mockito.doAnswer;
33 import static org.mockito.Mockito.doReturn;
34 import static org.mockito.Mockito.eq;
35 import static org.mockito.Mockito.mock;
36 import static org.mockito.Mockito.spy;
37 import static org.mockito.Mockito.when;
38 
39 import static java.util.stream.Collectors.toList;
40 
41 import android.content.Context;
42 import android.content.SharedPreferences;
43 import android.net.DnsResolver;
44 import android.net.InetAddresses;
45 import android.net.Network;
46 import android.os.Handler;
47 import android.os.Looper;
48 import android.telephony.CarrierConfigManager;
49 import android.telephony.CellIdentityGsm;
50 import android.telephony.CellIdentityLte;
51 import android.telephony.CellIdentityNr;
52 import android.telephony.CellIdentityWcdma;
53 import android.telephony.CellInfo;
54 import android.telephony.CellInfoGsm;
55 import android.telephony.CellInfoLte;
56 import android.telephony.CellInfoNr;
57 import android.telephony.CellInfoWcdma;
58 import android.telephony.DataFailCause;
59 import android.telephony.SubscriptionInfo;
60 import android.telephony.SubscriptionManager;
61 import android.telephony.TelephonyManager;
62 import android.util.Log;
63 
64 import com.google.android.iwlan.ErrorPolicyManager;
65 import com.google.android.iwlan.IwlanCarrierConfig;
66 import com.google.android.iwlan.IwlanError;
67 import com.google.android.iwlan.flags.FeatureFlags;
68 
69 import org.junit.After;
70 import org.junit.Before;
71 import org.junit.Test;
72 import org.mockito.Mock;
73 import org.mockito.MockitoAnnotations;
74 import org.mockito.MockitoSession;
75 import org.mockito.invocation.InvocationOnMock;
76 import org.mockito.stubbing.Answer;
77 
78 import java.net.InetAddress;
79 import java.net.UnknownHostException;
80 import java.util.ArrayList;
81 import java.util.Arrays;
82 import java.util.List;
83 import java.util.concurrent.CountDownLatch;
84 import java.util.concurrent.Executor;
85 import java.util.concurrent.RejectedExecutionException;
86 import java.util.concurrent.TimeUnit;
87 
88 public class EpdgSelectorTest {
89 
90     private static final String TAG = "EpdgSelectorTest";
91     private EpdgSelector mEpdgSelector;
92     public static final int DEFAULT_SLOT_INDEX = 0;
93 
94     private static final byte[] TEST_PCO_NO_DATA = {0x00};
95     private static final byte[] TEST_PCO_PLMN_DATA = {0x38, 0x01, 0x24, 0x00};
96     private static final byte[] TEST_PCO_IPV4_DATA = {0x38, 0x01, 0x24, 0x7F, 0x00, 0x00, 0x01};
97     private static final byte[] TEST_PCO_IPV6_DATA = {
98         0x38, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99         0x00, 0x00, 0x00, 0x01
100     };
101     private static final String TEST_IP_ADDRESS = "127.0.0.1";
102     private static final String TEST_IP_ADDRESS_1 = "127.0.0.2";
103     private static final String TEST_IP_ADDRESS_2 = "127.0.0.3";
104     private static final String TEST_IP_ADDRESS_3 = "127.0.0.4";
105     private static final String TEST_IP_ADDRESS_4 = "127.0.0.5";
106     private static final String TEST_IP_ADDRESS_5 = "127.0.0.6";
107     private static final String TEST_IP_ADDRESS_6 = "127.0.0.7";
108     private static final String TEST_IP_ADDRESS_7 = "127.0.0.8";
109     private static final String TEST_IPV6_ADDRESS = "0000:0000:0000:0000:0000:0000:0000:0001";
110 
111     private static final int TEST_PCO_ID_IPV6 = 0xFF01;
112     private static final int TEST_PCO_ID_IPV4 = 0xFF02;
113 
114     private final String testPcoString = "testPcoData";
115     private final byte[] pcoData = testPcoString.getBytes();
116     private final List<String> ehplmnList = new ArrayList<String>();
117 
118     @Mock private Context mMockContext;
119     @Mock private Network mMockNetwork;
120     @Mock private ErrorPolicyManager mMockErrorPolicyManager;
121     @Mock private SubscriptionManager mMockSubscriptionManager;
122     @Mock private SubscriptionInfo mMockSubscriptionInfo;
123     @Mock private TelephonyManager mMockTelephonyManager;
124     @Mock private SharedPreferences mMockSharedPreferences;
125     @Mock private CellInfoGsm mMockCellInfoGsm;
126     @Mock private CellIdentityGsm mMockCellIdentityGsm;
127     @Mock private CellInfoWcdma mMockCellInfoWcdma;
128     @Mock private CellIdentityWcdma mMockCellIdentityWcdma;
129     @Mock private CellInfoLte mMockCellInfoLte;
130     @Mock private CellIdentityLte mMockCellIdentityLte;
131     @Mock private CellInfoNr mMockCellInfoNr;
132     @Mock private CellIdentityNr mMockCellIdentityNr;
133     @Mock private DnsResolver mMockDnsResolver;
134     @Mock private FeatureFlags mfakeFeatureFlags;
135 
136     private FakeDns mFakeDns;
137     MockitoSession mStaticMockSession;
138 
139     @Before
setUp()140     public void setUp() throws Exception {
141         MockitoAnnotations.initMocks(this);
142         mStaticMockSession =
143                 mockitoSession()
144                         .mockStatic(DnsResolver.class)
145                         .mockStatic(ErrorPolicyManager.class)
146                         .startMocking();
147 
148         when(ErrorPolicyManager.getInstance(mMockContext, DEFAULT_SLOT_INDEX))
149                 .thenReturn(mMockErrorPolicyManager);
150         mEpdgSelector = spy(new EpdgSelector(mMockContext, DEFAULT_SLOT_INDEX, mfakeFeatureFlags));
151 
152         when(mMockContext.getSystemService(eq(SubscriptionManager.class)))
153                 .thenReturn(mMockSubscriptionManager);
154 
155         when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt()))
156                 .thenReturn(mMockSubscriptionInfo);
157 
158         when(mMockSubscriptionInfo.getMccString()).thenReturn("311");
159 
160         when(mMockSubscriptionInfo.getMncString()).thenReturn("120");
161 
162         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("311120");
163 
164         when(mMockContext.getSystemService(eq(TelephonyManager.class)))
165                 .thenReturn(mMockTelephonyManager);
166 
167         when(mMockTelephonyManager.createForSubscriptionId(anyInt()))
168                 .thenReturn(mMockTelephonyManager);
169 
170         ehplmnList.add("300120");
171         when(mMockTelephonyManager.getEquivalentHomePlmns()).thenReturn(ehplmnList);
172 
173         when(mMockTelephonyManager.getSimCountryIso()).thenReturn("ca");
174 
175         when(mMockContext.getSharedPreferences(anyString(), anyInt()))
176                 .thenReturn(mMockSharedPreferences);
177 
178         when(mMockSharedPreferences.getString(any(), any())).thenReturn("US");
179 
180         // Mock carrier configs with test bundle
181         IwlanCarrierConfig.putTestConfigInt(
182                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_IP_TYPE_PREFERENCE_INT,
183                 CarrierConfigManager.Iwlan.EPDG_ADDRESS_IPV4_PREFERRED);
184 
185         mFakeDns = new FakeDns();
186         mFakeDns.startMocking();
187     }
188 
189     @After
cleanUp()190     public void cleanUp() throws Exception {
191         mStaticMockSession.finishMocking();
192         IwlanCarrierConfig.resetTestConfig();
193         mFakeDns.clearAll();
194     }
195 
196     @Test
testStaticMethodPass()197     public void testStaticMethodPass() throws Exception {
198         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
199         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
200         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
201 
202         // Set DnsResolver query mock
203         final String testStaticAddress = "epdg.epc.mnc088.mcc888.pub.3gppnetwork.org";
204         mFakeDns.setAnswer(testStaticAddress, new String[] {TEST_IP_ADDRESS}, TYPE_A);
205 
206         // Set carrier config mock
207         IwlanCarrierConfig.putTestConfigIntArray(
208                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
209                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
210         IwlanCarrierConfig.putTestConfigString(
211                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
212 
213         ArrayList<InetAddress> testInetAddresses =
214                 getValidatedServerListWithDefaultParams(false /*isEmergency*/);
215 
216         InetAddress expectedAddress = InetAddress.getByName(TEST_IP_ADDRESS);
217 
218         assertEquals(1, testInetAddresses.size());
219         assertEquals(expectedAddress, testInetAddresses.get(0));
220     }
221 
222     @Test
testStaticMethodDirectIpAddress_noDnsResolution()223     public void testStaticMethodDirectIpAddress_noDnsResolution() throws Exception {
224         IwlanCarrierConfig.putTestConfigIntArray(
225                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
226                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
227         // Carrier config directly contains the ePDG IP address.
228         IwlanCarrierConfig.putTestConfigString(
229                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, TEST_IP_ADDRESS);
230 
231         ArrayList<InetAddress> testInetAddresses =
232                 getValidatedServerListWithDefaultParams(false /*isEmergency*/);
233 
234         assertEquals(1, testInetAddresses.size());
235         assertEquals(InetAddresses.parseNumericAddress(TEST_IP_ADDRESS), testInetAddresses.get(0));
236     }
237 
238     @Test
testRoamStaticMethodPass()239     public void testRoamStaticMethodPass() throws Exception {
240         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
241         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
242         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
243 
244         // Set DnsResolver query mock
245         final String testRoamStaticAddress = "epdg.epc.mnc088.mcc888.pub.3gppnetwork.org";
246         mFakeDns.setAnswer(testRoamStaticAddress, new String[] {TEST_IP_ADDRESS}, TYPE_A);
247 
248         // Set carrier config mock
249         IwlanCarrierConfig.putTestConfigIntArray(
250                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
251                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
252         IwlanCarrierConfig.putTestConfigString(
253                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_ROAMING_STRING,
254                 testRoamStaticAddress);
255 
256         ArrayList<InetAddress> testInetAddresses =
257                 getValidatedServerListWithDefaultParams(false /*isEmergency*/);
258 
259         InetAddress expectedAddress = InetAddress.getByName(TEST_IP_ADDRESS);
260 
261         assertEquals(1, testInetAddresses.size());
262         assertEquals(expectedAddress, testInetAddresses.get(0));
263     }
264 
265     @Test
testPlmnResolutionMethod()266     public void testPlmnResolutionMethod() throws Exception {
267         testPlmnResolutionMethod(false);
268     }
269 
270     @Test
testPlmnResolutionMethodForEmergency()271     public void testPlmnResolutionMethodForEmergency() throws Exception {
272         testPlmnResolutionMethod(true);
273     }
274 
275     @Test
testPlmnResolutionMethodWithNoPlmnInCarrierConfig()276     public void testPlmnResolutionMethodWithNoPlmnInCarrierConfig() throws Exception {
277         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
278         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
279         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
280 
281         // setUp() fills default values for mcc-mnc
282         String expectedFqdnFromImsi = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
283         String expectedFqdnFromEhplmn = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
284 
285         mFakeDns.setAnswer(expectedFqdnFromImsi, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
286         mFakeDns.setAnswer(expectedFqdnFromEhplmn, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
287 
288         ArrayList<InetAddress> testInetAddresses =
289                 getValidatedServerListWithDefaultParams(false /*isEmergency*/);
290 
291         assertEquals(2, testInetAddresses.size());
292         assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IP_ADDRESS_1)));
293         assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IP_ADDRESS_2)));
294     }
295 
testPlmnResolutionMethod(boolean isEmergency)296     private void testPlmnResolutionMethod(boolean isEmergency) throws Exception {
297         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
298         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
299         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
300 
301         String expectedFqdnFromImsi = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
302         String expectedFqdnFromRplmn = "epdg.epc.mnc121.mcc311.pub.3gppnetwork.org";
303         String expectedFqdnFromEhplmn = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
304         String excludedFqdnFromConfig = "epdg.epc.mnc480.mcc310.pub.3gppnetwork.org";
305 
306         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("311121");
307 
308         IwlanCarrierConfig.putTestConfigIntArray(
309                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
310                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
311         IwlanCarrierConfig.putTestConfigStringArray(
312                 CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY,
313                 new String[] {"310-480", "300-120", "311-120", "311-121"});
314 
315         mFakeDns.setAnswer(expectedFqdnFromImsi, new String[] {TEST_IP_ADDRESS}, TYPE_A);
316         mFakeDns.setAnswer(expectedFqdnFromEhplmn, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
317         mFakeDns.setAnswer(excludedFqdnFromConfig, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
318         mFakeDns.setAnswer("sos." + expectedFqdnFromImsi, new String[] {TEST_IP_ADDRESS_3}, TYPE_A);
319         mFakeDns.setAnswer(
320                 "sos." + expectedFqdnFromEhplmn, new String[] {TEST_IP_ADDRESS_4}, TYPE_A);
321         mFakeDns.setAnswer(
322                 "sos." + excludedFqdnFromConfig, new String[] {TEST_IP_ADDRESS_5}, TYPE_A);
323         mFakeDns.setAnswer(expectedFqdnFromRplmn, new String[] {TEST_IP_ADDRESS_6}, TYPE_A);
324         mFakeDns.setAnswer(
325                 "sos." + expectedFqdnFromRplmn, new String[] {TEST_IP_ADDRESS_7}, TYPE_A);
326 
327         ArrayList<InetAddress> testInetAddresses =
328                 getValidatedServerListWithDefaultParams(isEmergency);
329 
330         if (isEmergency) {
331             assertEquals(6, testInetAddresses.size());
332             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_7), testInetAddresses.get(0));
333             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_6), testInetAddresses.get(1));
334             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_3), testInetAddresses.get(2));
335             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(3));
336             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_4), testInetAddresses.get(4));
337             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(5));
338         } else {
339             assertEquals(3, testInetAddresses.size());
340             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_6), testInetAddresses.get(0));
341             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(1));
342             assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(2));
343         }
344     }
345 
346     @Test
testPlmnResolutionMethodWithDuplicatedImsiAndEhplmn()347     public void testPlmnResolutionMethodWithDuplicatedImsiAndEhplmn() throws Exception {
348         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
349         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
350         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
351 
352         String fqdnFromEhplmn1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
353         String fqdnFromEhplmn2AndImsi = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
354         String fqdnFromEhplmn3 = "epdg.epc.mnc122.mcc300.pub.3gppnetwork.org";
355         String fqdnFromEhplmn4 = "epdg.epc.mnc123.mcc300.pub.3gppnetwork.org";
356 
357         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("300121");
358         ehplmnList.add("300122");
359         ehplmnList.add("300123");
360 
361         IwlanCarrierConfig.putTestConfigIntArray(
362                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
363                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
364         IwlanCarrierConfig.putTestConfigIntArray(
365                 CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
366                 new int[] {
367                     CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN,
368                     CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL,
369                 });
370 
371         mFakeDns.setAnswer(fqdnFromEhplmn1, new String[] {TEST_IP_ADDRESS}, TYPE_A);
372         mFakeDns.setAnswer(fqdnFromEhplmn2AndImsi, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
373         mFakeDns.setAnswer(fqdnFromEhplmn3, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
374         mFakeDns.setAnswer(fqdnFromEhplmn4, new String[] {TEST_IP_ADDRESS_3}, TYPE_A);
375 
376         ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
377 
378         assertEquals(4, testInetAddresses.size());
379         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(0));
380         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(1));
381         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(2));
382         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_3), testInetAddresses.get(3));
383     }
384 
385     @Test
testPlmnResolutionMethodWithInvalidLengthPlmns()386     public void testPlmnResolutionMethodWithInvalidLengthPlmns() throws Exception {
387         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
388         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
389         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
390 
391         when(mMockSubscriptionInfo.getMccString()).thenReturn("31");
392         when(mMockSubscriptionInfo.getMncString()).thenReturn("12");
393 
394         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("300");
395         ehplmnList.add("3001");
396         ehplmnList.add("3");
397 
398         IwlanCarrierConfig.putTestConfigIntArray(
399                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
400                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
401         IwlanCarrierConfig.putTestConfigIntArray(
402                 CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
403                 new int[] {
404                     CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN,
405                     CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN,
406                     CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL,
407                 });
408 
409         ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
410 
411         assertEquals(0, testInetAddresses.size());
412     }
413 
414     @Test
testPlmnResolutionMethodWithInvalidCharacterPlmns()415     public void testPlmnResolutionMethodWithInvalidCharacterPlmns() throws Exception {
416         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
417         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
418         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
419 
420         when(mMockSubscriptionInfo.getMccString()).thenReturn("a b");
421         when(mMockSubscriptionInfo.getMncString()).thenReturn("!@#");
422 
423         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("a cde#");
424         ehplmnList.add("abcdef");
425         ehplmnList.add("1 23456");
426         ehplmnList.add("1 2345");
427 
428         IwlanCarrierConfig.putTestConfigIntArray(
429                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
430                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
431         IwlanCarrierConfig.putTestConfigIntArray(
432                 CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
433                 new int[] {
434                     CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN,
435                     CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN,
436                     CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL,
437                 });
438 
439         ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
440 
441         assertEquals(0, testInetAddresses.size());
442     }
443 
444     @Test
testPlmnResolutionMethodWithEmptyPlmns()445     public void testPlmnResolutionMethodWithEmptyPlmns() throws Exception {
446         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
447         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
448         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
449 
450         when(mMockSubscriptionInfo.getMccString()).thenReturn(null);
451         when(mMockSubscriptionInfo.getMncString()).thenReturn(null);
452 
453         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("");
454         ehplmnList.add("");
455 
456         IwlanCarrierConfig.putTestConfigIntArray(
457                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
458                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
459         IwlanCarrierConfig.putTestConfigIntArray(
460                 CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
461                 new int[] {
462                     CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN,
463                     CarrierConfigManager.Iwlan.EPDG_PLMN_HPLMN,
464                     CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_ALL,
465                 });
466 
467         ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
468 
469         assertEquals(0, testInetAddresses.size());
470     }
471 
472     @Test
testPlmnResolutionMethodWithFirstEhplmn()473     public void testPlmnResolutionMethodWithFirstEhplmn() throws Exception {
474         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
475         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
476         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
477 
478         String fqdnFromEhplmn1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
479         String fqdnFromEhplmn2 = "epdg.epc.mnc121.mcc300.pub.3gppnetwork.org";
480         String fqdnFromEhplmn3 = "epdg.epc.mnc122.mcc300.pub.3gppnetwork.org";
481         String fqdnFromEhplmn4 = "epdg.epc.mnc123.mcc300.pub.3gppnetwork.org";
482 
483         ehplmnList.add("300121");
484         ehplmnList.add("300122");
485         ehplmnList.add("300123");
486 
487         IwlanCarrierConfig.putTestConfigIntArray(
488                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
489                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
490         IwlanCarrierConfig.putTestConfigIntArray(
491                 CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
492                 new int[] {CarrierConfigManager.Iwlan.EPDG_PLMN_EHPLMN_FIRST});
493 
494         mFakeDns.setAnswer(fqdnFromEhplmn1, new String[] {TEST_IP_ADDRESS}, TYPE_A);
495         mFakeDns.setAnswer(fqdnFromEhplmn2, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
496         mFakeDns.setAnswer(fqdnFromEhplmn3, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
497         mFakeDns.setAnswer(fqdnFromEhplmn4, new String[] {TEST_IP_ADDRESS_3}, TYPE_A);
498 
499         ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
500 
501         assertEquals(1, testInetAddresses.size());
502         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(0));
503     }
504 
505     @Test
testPlmnResolutionMethodWithRplmn()506     public void testPlmnResolutionMethodWithRplmn() throws Exception {
507         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
508         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
509         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
510 
511         String fqdnFromRplmn = "epdg.epc.mnc122.mcc300.pub.3gppnetwork.org";
512         String fqdnFromEhplmn1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
513         String fqdnFromEhplmn2 = "epdg.epc.mnc121.mcc300.pub.3gppnetwork.org";
514 
515         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("300122");
516         ehplmnList.add("300121");
517 
518         IwlanCarrierConfig.putTestConfigStringArray(
519                 CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY,
520                 new String[] {"310-480", "300-122", "300-121"});
521 
522         IwlanCarrierConfig.putTestConfigIntArray(
523                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
524                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
525         IwlanCarrierConfig.putTestConfigIntArray(
526                 CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
527                 new int[] {CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN});
528 
529         mFakeDns.setAnswer(fqdnFromRplmn, new String[] {TEST_IP_ADDRESS}, TYPE_A);
530         mFakeDns.setAnswer(fqdnFromEhplmn1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
531         mFakeDns.setAnswer(fqdnFromEhplmn2, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
532 
533         ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
534 
535         assertEquals(1, testInetAddresses.size());
536         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(0));
537     }
538 
539     @Test
testCarrierConfigStaticAddressList()540     public void testCarrierConfigStaticAddressList() throws Exception {
541         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
542         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
543         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
544 
545         // Set DnsResolver query mock
546         final String addr1 = "epdg.epc.mnc480.mcc310.pub.3gppnetwork.org";
547         final String addr2 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
548         final String addr3 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
549         final String testStaticAddress = addr1 + "," + addr2 + "," + addr3;
550 
551         mFakeDns.setAnswer(addr1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
552         mFakeDns.setAnswer(addr2, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
553         mFakeDns.setAnswer(addr3, new String[] {TEST_IP_ADDRESS}, TYPE_A);
554 
555         // Set carrier config mock
556         IwlanCarrierConfig.putTestConfigIntArray(
557                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
558                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
559         IwlanCarrierConfig.putTestConfigString(
560                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
561 
562         ArrayList<InetAddress> testInetAddresses =
563                 getValidatedServerListWithDefaultParams(false /*isEmergency*/);
564 
565         assertEquals(3, testInetAddresses.size());
566         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(0));
567         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(1));
568         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(2));
569     }
570 
getValidatedServerListWithDefaultParams(boolean isEmergency)571     private ArrayList<InetAddress> getValidatedServerListWithDefaultParams(boolean isEmergency)
572             throws Exception {
573         return getValidatedServerListWithIpPreference(
574                 EpdgSelector.PROTO_FILTER_IPV4V6, EpdgSelector.IPV4_PREFERRED, isEmergency);
575     }
576 
getValidatedServerListWithIpPreference( @pdgSelector.ProtoFilter int filter, @EpdgSelector.EpdgAddressOrder int order, boolean isEmergency)577     private ArrayList<InetAddress> getValidatedServerListWithIpPreference(
578             @EpdgSelector.ProtoFilter int filter,
579             @EpdgSelector.EpdgAddressOrder int order,
580             boolean isEmergency)
581             throws Exception {
582         ArrayList<InetAddress> testInetAddresses = new ArrayList<InetAddress>();
583         final CountDownLatch latch = new CountDownLatch(1);
584         IwlanError ret =
585                 mEpdgSelector.getValidatedServerList(
586                         1234,
587                         filter,
588                         order,
589                         false /* isRoaming */,
590                         isEmergency,
591                         mMockNetwork,
592                         new EpdgSelector.EpdgSelectorCallback() {
593                             @Override
594                             public void onServerListChanged(
595                                     int transactionId, List<InetAddress> validIPList) {
596                                 assertEquals(1234, transactionId);
597 
598                                 for (InetAddress mInetAddress : validIPList) {
599                                     testInetAddresses.add(mInetAddress);
600                                 }
601                                 Log.d(TAG, "onServerListChanged received");
602                                 latch.countDown();
603                             }
604 
605                             @Override
606                             public void onError(int transactionId, IwlanError epdgSelectorError) {
607                                 Log.d(TAG, "onError received");
608                                 latch.countDown();
609                             }
610                         });
611 
612         assertEquals(IwlanError.NO_ERROR, ret.getErrorType());
613         latch.await(1, TimeUnit.SECONDS);
614         return testInetAddresses;
615     }
616 
617     @Test
testSetPcoData()618     public void testSetPcoData() throws Exception {
619         addTestPcoIdsToTestConfigBundle();
620 
621         boolean retIPv6 = mEpdgSelector.setPcoData(TEST_PCO_ID_IPV6, pcoData);
622         boolean retIPv4 = mEpdgSelector.setPcoData(TEST_PCO_ID_IPV4, pcoData);
623         boolean retIncorrect = mEpdgSelector.setPcoData(0xFF00, pcoData);
624 
625         assertTrue(retIPv6);
626         assertTrue(retIPv4);
627         assertFalse(retIncorrect);
628     }
629 
630     @Test
testPcoResolutionMethod()631     public void testPcoResolutionMethod() throws Exception {
632         IwlanCarrierConfig.putTestConfigIntArray(
633                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
634                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PCO});
635         addTestPcoIdsToTestConfigBundle();
636 
637         mEpdgSelector.clearPcoData();
638         assertTrue(mEpdgSelector.setPcoData(TEST_PCO_ID_IPV6, TEST_PCO_IPV6_DATA));
639         assertTrue(mEpdgSelector.setPcoData(TEST_PCO_ID_IPV4, TEST_PCO_IPV4_DATA));
640 
641         ArrayList<InetAddress> testInetAddresses =
642                 getValidatedServerListWithDefaultParams(false /* isEmergency */);
643 
644         assertEquals(2, testInetAddresses.size());
645         assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IP_ADDRESS)));
646         assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IPV6_ADDRESS)));
647     }
648 
649     @Test
testPcoResolutionMethodWithNoPcoData()650     public void testPcoResolutionMethodWithNoPcoData() throws Exception {
651         IwlanCarrierConfig.putTestConfigIntArray(
652                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
653                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PCO});
654         addTestPcoIdsToTestConfigBundle();
655 
656         mEpdgSelector.clearPcoData();
657         assertTrue(mEpdgSelector.setPcoData(TEST_PCO_ID_IPV6, TEST_PCO_NO_DATA));
658         assertTrue(mEpdgSelector.setPcoData(TEST_PCO_ID_IPV4, TEST_PCO_NO_DATA));
659 
660         ArrayList<InetAddress> testInetAddresses =
661                 getValidatedServerListWithDefaultParams(false /* isEmergency */);
662 
663         assertEquals(0, testInetAddresses.size());
664     }
665 
666     @Test
testPcoResolutionMethodWithOnlyPlmnData()667     public void testPcoResolutionMethodWithOnlyPlmnData() throws Exception {
668         IwlanCarrierConfig.putTestConfigIntArray(
669                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
670                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PCO});
671         addTestPcoIdsToTestConfigBundle();
672 
673         mEpdgSelector.clearPcoData();
674         assertTrue(mEpdgSelector.setPcoData(TEST_PCO_ID_IPV6, TEST_PCO_PLMN_DATA));
675         assertTrue(mEpdgSelector.setPcoData(TEST_PCO_ID_IPV4, TEST_PCO_PLMN_DATA));
676 
677         ArrayList<InetAddress> testInetAddresses =
678                 getValidatedServerListWithDefaultParams(false /* isEmergency */);
679 
680         assertEquals(0, testInetAddresses.size());
681     }
682 
addTestPcoIdsToTestConfigBundle()683     private void addTestPcoIdsToTestConfigBundle() {
684         IwlanCarrierConfig.putTestConfigInt(
685                 CarrierConfigManager.Iwlan.KEY_EPDG_PCO_ID_IPV6_INT, TEST_PCO_ID_IPV6);
686         IwlanCarrierConfig.putTestConfigInt(
687                 CarrierConfigManager.Iwlan.KEY_EPDG_PCO_ID_IPV4_INT, TEST_PCO_ID_IPV4);
688     }
689 
690     @Test
testCellularResolutionMethod()691     public void testCellularResolutionMethod() throws Exception {
692         testCellularResolutionMethod(false);
693     }
694 
695     @Test
testCellularResolutionMethodForEmergency()696     public void testCellularResolutionMethodForEmergency() throws Exception {
697         testCellularResolutionMethod(true);
698     }
699 
testCellularResolutionMethod(boolean isEmergency)700     private void testCellularResolutionMethod(boolean isEmergency) throws Exception {
701         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
702 
703         int testMcc = 311;
704         int testMnc = 120;
705         String testMccString = "311";
706         String testMncString = "120";
707         int testLac = 65484;
708         int testTac = 65484;
709         int testNrTac = 16764074;
710 
711         List<CellInfo> fakeCellInfoArray = new ArrayList<CellInfo>();
712 
713         IwlanCarrierConfig.putTestConfigIntArray(
714                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
715                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_CELLULAR_LOC});
716 
717         // Set cell info mock
718         fakeCellInfoArray.add(mMockCellInfoGsm);
719         when(mMockCellInfoGsm.isRegistered()).thenReturn(true);
720         when(mMockCellInfoGsm.getCellIdentity()).thenReturn(mMockCellIdentityGsm);
721         when(mMockCellIdentityGsm.getMcc()).thenReturn(testMcc);
722         when(mMockCellIdentityGsm.getMnc()).thenReturn(testMnc);
723         when(mMockCellIdentityGsm.getLac()).thenReturn(testLac);
724 
725         fakeCellInfoArray.add(mMockCellInfoWcdma);
726         when(mMockCellInfoWcdma.isRegistered()).thenReturn(true);
727         when(mMockCellInfoWcdma.getCellIdentity()).thenReturn(mMockCellIdentityWcdma);
728         when(mMockCellIdentityWcdma.getMcc()).thenReturn(testMcc);
729         when(mMockCellIdentityWcdma.getMnc()).thenReturn(testMnc);
730         when(mMockCellIdentityWcdma.getLac()).thenReturn(testLac);
731 
732         fakeCellInfoArray.add(mMockCellInfoLte);
733         when(mMockCellInfoLte.isRegistered()).thenReturn(true);
734         when(mMockCellInfoLte.getCellIdentity()).thenReturn(mMockCellIdentityLte);
735         when(mMockCellIdentityLte.getMcc()).thenReturn(testMcc);
736         when(mMockCellIdentityLte.getMnc()).thenReturn(testMnc);
737         when(mMockCellIdentityLte.getTac()).thenReturn(testTac);
738 
739         fakeCellInfoArray.add(mMockCellInfoNr);
740         when(mMockCellInfoNr.isRegistered()).thenReturn(true);
741         when(mMockCellInfoNr.getCellIdentity()).thenReturn(mMockCellIdentityNr);
742         when(mMockCellIdentityNr.getMccString()).thenReturn(testMccString);
743         when(mMockCellIdentityNr.getMncString()).thenReturn(testMncString);
744         when(mMockCellIdentityNr.getTac()).thenReturn(testNrTac);
745 
746         when(mMockTelephonyManager.getAllCellInfo()).thenReturn(fakeCellInfoArray);
747 
748         setAnswerForCellularMethod(isEmergency, 311, 120);
749         setAnswerForCellularMethod(isEmergency, 300, 120);
750 
751         ArrayList<InetAddress> testInetAddresses =
752                 getValidatedServerListWithDefaultParams(isEmergency);
753 
754         assertEquals(3, testInetAddresses.size());
755         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS), testInetAddresses.get(0));
756         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(1));
757         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(2));
758     }
759 
760     @Test
testTemporaryExcludedIpAddressWhenDisabledExcludeFailedIp()761     public void testTemporaryExcludedIpAddressWhenDisabledExcludeFailedIp() throws Exception {
762         doReturn(false).when(mfakeFeatureFlags).epdgSelectionExcludeFailedIpAddress();
763         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
764         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
765         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
766 
767         String fqdnFromRplmn = "epdg.epc.mnc122.mcc300.pub.3gppnetwork.org";
768         final String staticAddr = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
769 
770         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("300122");
771         IwlanCarrierConfig.putTestConfigStringArray(
772                 CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY, new String[] {"300-122"});
773 
774         IwlanCarrierConfig.putTestConfigIntArray(
775                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
776                 new int[] {
777                     CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN,
778                     CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC
779                 });
780         IwlanCarrierConfig.putTestConfigIntArray(
781                 CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
782                 new int[] {CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN});
783 
784         IwlanCarrierConfig.putTestConfigString(
785                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, staticAddr);
786 
787         mFakeDns.setAnswer(fqdnFromRplmn, new String[] {TEST_IP_ADDRESS}, TYPE_A);
788         mFakeDns.setAnswer(staticAddr, new String[] {TEST_IP_ADDRESS_1, TEST_IPV6_ADDRESS}, TYPE_A);
789 
790         ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
791         assertArrayEquals(
792                 List.of(
793                                 InetAddress.getByName(TEST_IP_ADDRESS),
794                                 InetAddress.getByName(TEST_IP_ADDRESS_1),
795                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
796                         .toArray(),
797                 testInetAddresses.toArray());
798 
799         mEpdgSelector.onEpdgConnectionFailed(InetAddress.getByName(TEST_IP_ADDRESS));
800         // Flag disabled should not affect the result
801         testInetAddresses = getValidatedServerListWithDefaultParams(false);
802         assertArrayEquals(
803                 List.of(
804                                 InetAddress.getByName(TEST_IP_ADDRESS),
805                                 InetAddress.getByName(TEST_IP_ADDRESS_1),
806                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
807                         .toArray(),
808                 testInetAddresses.toArray());
809 
810         mEpdgSelector.onEpdgConnectedSuccessfully();
811         // Flag disabled should not affect the result
812         testInetAddresses = getValidatedServerListWithDefaultParams(false);
813         assertArrayEquals(
814                 List.of(
815                                 InetAddress.getByName(TEST_IP_ADDRESS),
816                                 InetAddress.getByName(TEST_IP_ADDRESS_1),
817                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
818                         .toArray(),
819                 testInetAddresses.toArray());
820     }
821 
822     @Test
testTemporaryExcludedIpAddressWhenEnabledExcludeFailedIp()823     public void testTemporaryExcludedIpAddressWhenEnabledExcludeFailedIp() throws Exception {
824         doReturn(true).when(mfakeFeatureFlags).epdgSelectionExcludeFailedIpAddress();
825         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
826         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
827         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
828 
829         final String fqdnFromRplmn = "epdg.epc.mnc122.mcc300.pub.3gppnetwork.org";
830         final String staticAddr = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
831 
832         when(mMockTelephonyManager.getNetworkOperator()).thenReturn("300122");
833         IwlanCarrierConfig.putTestConfigStringArray(
834                 CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY, new String[] {"300-122"});
835 
836         IwlanCarrierConfig.putTestConfigIntArray(
837                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
838                 new int[] {
839                     CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN,
840                     CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC
841                 });
842         IwlanCarrierConfig.putTestConfigIntArray(
843                 CarrierConfigManager.Iwlan.KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
844                 new int[] {CarrierConfigManager.Iwlan.EPDG_PLMN_RPLMN});
845 
846         IwlanCarrierConfig.putTestConfigString(
847                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, staticAddr);
848 
849         mFakeDns.setAnswer(fqdnFromRplmn, new String[] {TEST_IP_ADDRESS}, TYPE_A);
850         mFakeDns.setAnswer(staticAddr, new String[] {TEST_IP_ADDRESS_1, TEST_IPV6_ADDRESS}, TYPE_A);
851 
852         ArrayList<InetAddress> testInetAddresses = getValidatedServerListWithDefaultParams(false);
853         assertArrayEquals(
854                 List.of(
855                                 InetAddress.getByName(TEST_IP_ADDRESS),
856                                 InetAddress.getByName(TEST_IP_ADDRESS_1),
857                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
858                         .toArray(),
859                 testInetAddresses.toArray());
860 
861         mEpdgSelector.onEpdgConnectionFailed(InetAddress.getByName(TEST_IP_ADDRESS));
862         testInetAddresses = getValidatedServerListWithDefaultParams(false);
863         assertArrayEquals(
864                 List.of(
865                                 InetAddress.getByName(TEST_IP_ADDRESS_1),
866                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
867                         .toArray(),
868                 testInetAddresses.toArray());
869 
870         // Reset temporary excluded ip addresses
871         mEpdgSelector.onEpdgConnectedSuccessfully();
872         testInetAddresses = getValidatedServerListWithDefaultParams(false);
873         assertArrayEquals(
874                 List.of(
875                                 InetAddress.getByName(TEST_IP_ADDRESS),
876                                 InetAddress.getByName(TEST_IP_ADDRESS_1),
877                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
878                         .toArray(),
879                 testInetAddresses.toArray());
880 
881         mEpdgSelector.onEpdgConnectionFailed(InetAddress.getByName(TEST_IP_ADDRESS));
882         testInetAddresses = getValidatedServerListWithDefaultParams(false);
883         assertArrayEquals(
884                 List.of(
885                                 InetAddress.getByName(TEST_IP_ADDRESS_1),
886                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
887                         .toArray(),
888                 testInetAddresses.toArray());
889 
890         mEpdgSelector.onEpdgConnectionFailed(InetAddress.getByName(TEST_IPV6_ADDRESS));
891         testInetAddresses = getValidatedServerListWithDefaultParams(false);
892         assertArrayEquals(
893                 List.of(InetAddress.getByName(TEST_IP_ADDRESS_1)).toArray(),
894                 testInetAddresses.toArray());
895 
896         mEpdgSelector.onEpdgConnectionFailed(InetAddress.getByName(TEST_IP_ADDRESS_1));
897         // All ip addresses removed, should reset excluded address
898         testInetAddresses = getValidatedServerListWithDefaultParams(false);
899         assertArrayEquals(
900                 List.of(
901                                 InetAddress.getByName(TEST_IP_ADDRESS),
902                                 InetAddress.getByName(TEST_IP_ADDRESS_1),
903                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
904                         .toArray(),
905                 testInetAddresses.toArray());
906 
907         mEpdgSelector.onEpdgConnectionFailed(InetAddress.getByName(TEST_IP_ADDRESS_1));
908         testInetAddresses = getValidatedServerListWithDefaultParams(false);
909         assertArrayEquals(
910                 List.of(
911                                 InetAddress.getByName(TEST_IP_ADDRESS),
912                                 InetAddress.getByName(TEST_IPV6_ADDRESS))
913                         .toArray(),
914                 testInetAddresses.toArray());
915 
916         // When the original result changed
917         mFakeDns.setAnswer(staticAddr, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
918         mFakeDns.setAnswer(fqdnFromRplmn, new String[] {TEST_IP_ADDRESS_3}, TYPE_A);
919         testInetAddresses = getValidatedServerListWithDefaultParams(false);
920         assertArrayEquals(
921                 List.of(InetAddress.getByName(TEST_IP_ADDRESS_3)).toArray(),
922                 testInetAddresses.toArray());
923 
924         mEpdgSelector.onEpdgConnectionFailed(InetAddress.getByName(TEST_IP_ADDRESS_3));
925         // It should also reset the excluded list once all ip addresses are excluded
926         testInetAddresses = getValidatedServerListWithDefaultParams(false);
927         assertArrayEquals(
928                 List.of(
929                                 InetAddress.getByName(TEST_IP_ADDRESS_3),
930                                 InetAddress.getByName(TEST_IP_ADDRESS_1))
931                         .toArray(),
932                 testInetAddresses.toArray());
933     }
934 
setAnswerForCellularMethod(boolean isEmergency, int mcc, int mnc)935     private void setAnswerForCellularMethod(boolean isEmergency, int mcc, int mnc)
936             throws Exception {
937         String expectedFqdn1 =
938                 (isEmergency)
939                         ? "lacffcc.sos.epdg.epc.mnc" + mnc + ".mcc" + mcc + ".pub.3gppnetwork.org"
940                         : "lacffcc.epdg.epc.mnc" + mnc + ".mcc" + mcc + ".pub.3gppnetwork.org";
941         String expectedFqdn2 =
942                 (isEmergency)
943                         ? "tac-lbcc.tac-hbff.tac.sos.epdg.epc.mnc"
944                                 + mnc
945                                 + ".mcc"
946                                 + mcc
947                                 + ".pub.3gppnetwork.org"
948                         : "tac-lbcc.tac-hbff.tac.epdg.epc.mnc"
949                                 + mnc
950                                 + ".mcc"
951                                 + mcc
952                                 + ".pub.3gppnetwork.org";
953         String expectedFqdn3 =
954                 (isEmergency)
955                         ? "tac-lbaa.tac-mbcc.tac-hbff.5gstac.sos.epdg.epc.mnc"
956                                 + mnc
957                                 + ".mcc"
958                                 + mcc
959                                 + ".pub.3gppnetwork.org"
960                         : "tac-lbaa.tac-mbcc.tac-hbff.5gstac.epdg.epc.mnc"
961                                 + mnc
962                                 + ".mcc"
963                                 + mcc
964                                 + ".pub.3gppnetwork.org";
965 
966         mFakeDns.setAnswer(expectedFqdn1, new String[] {TEST_IP_ADDRESS}, TYPE_A);
967         mFakeDns.setAnswer(expectedFqdn2, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
968         mFakeDns.setAnswer(expectedFqdn3, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
969     }
970 
971     @Test
testGetValidatedServerListIpv4Preferred()972     public void testGetValidatedServerListIpv4Preferred() throws Exception {
973         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
974         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
975         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
976 
977         final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
978         final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
979         final String testStaticAddress = addr1 + "," + addr2;
980 
981         mFakeDns.setAnswer(addr1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
982         mFakeDns.setAnswer(addr2, new String[] {TEST_IPV6_ADDRESS}, TYPE_AAAA);
983 
984         // Set carrier config mock
985         IwlanCarrierConfig.putTestConfigIntArray(
986                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
987                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
988         IwlanCarrierConfig.putTestConfigString(
989                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
990 
991         ArrayList<InetAddress> testInetAddresses =
992                 getValidatedServerListWithIpPreference(
993                         EpdgSelector.PROTO_FILTER_IPV4V6,
994                         EpdgSelector.IPV4_PREFERRED,
995                         false /*isEmergency*/);
996 
997         assertEquals(2, testInetAddresses.size());
998         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(0));
999         assertEquals(InetAddress.getByName(TEST_IPV6_ADDRESS), testInetAddresses.get(1));
1000     }
1001 
1002     @Test
testGetValidatedServerListIpv6Preferred()1003     public void testGetValidatedServerListIpv6Preferred() throws Exception {
1004         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
1005         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
1006         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
1007 
1008         final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
1009         final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
1010         final String testStaticAddress = addr1 + "," + addr2;
1011 
1012         mFakeDns.setAnswer(addr1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
1013         mFakeDns.setAnswer(addr2, new String[] {TEST_IPV6_ADDRESS}, TYPE_AAAA);
1014 
1015         // Set carrier config mock
1016         IwlanCarrierConfig.putTestConfigIntArray(
1017                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
1018                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
1019         IwlanCarrierConfig.putTestConfigString(
1020                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
1021 
1022         ArrayList<InetAddress> testInetAddresses =
1023                 getValidatedServerListWithIpPreference(
1024                         EpdgSelector.PROTO_FILTER_IPV4V6,
1025                         EpdgSelector.IPV6_PREFERRED,
1026                         false /*isEmergency*/);
1027 
1028         assertEquals(2, testInetAddresses.size());
1029         assertEquals(InetAddress.getByName(TEST_IPV6_ADDRESS), testInetAddresses.get(0));
1030         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(1));
1031     }
1032 
1033     @Test
testGetValidatedServerListIpv4Only()1034     public void testGetValidatedServerListIpv4Only() throws Exception {
1035         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
1036         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
1037         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
1038 
1039         final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
1040         final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
1041         final String testStaticAddress = addr1 + "," + addr2;
1042 
1043         mFakeDns.setAnswer(addr1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
1044         mFakeDns.setAnswer(addr2, new String[] {TEST_IPV6_ADDRESS}, TYPE_AAAA);
1045 
1046         // Set carrier config mock
1047         IwlanCarrierConfig.putTestConfigIntArray(
1048                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
1049                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
1050         IwlanCarrierConfig.putTestConfigString(
1051                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
1052 
1053         ArrayList<InetAddress> testInetAddresses =
1054                 getValidatedServerListWithIpPreference(
1055                         EpdgSelector.PROTO_FILTER_IPV4,
1056                         EpdgSelector.SYSTEM_PREFERRED,
1057                         false /*isEmergency*/);
1058 
1059         assertEquals(1, testInetAddresses.size());
1060         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(0));
1061     }
1062 
1063     @Test
testGetValidatedServerListIpv4OnlyCongestion()1064     public void testGetValidatedServerListIpv4OnlyCongestion() throws Exception {
1065         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
1066         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
1067         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
1068 
1069         when(mMockErrorPolicyManager.getMostRecentDataFailCause())
1070                 .thenReturn(DataFailCause.IWLAN_CONGESTION);
1071         when(mMockErrorPolicyManager.getCurrentFqdnIndex(anyInt())).thenReturn(0);
1072 
1073         String expectedFqdnFromHplmn = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
1074         String expectedFqdnFromEHplmn = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
1075         String expectedFqdnFromConfig = "epdg.epc.mnc480.mcc310.pub.3gppnetwork.org";
1076 
1077         IwlanCarrierConfig.putTestConfigIntArray(
1078                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
1079                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
1080         IwlanCarrierConfig.putTestConfigStringArray(
1081                 CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY,
1082                 new String[] {"310-480", "300-120", "311-120"});
1083 
1084         mFakeDns.setAnswer(expectedFqdnFromHplmn, new String[] {TEST_IPV6_ADDRESS}, TYPE_AAAA);
1085         mFakeDns.setAnswer(expectedFqdnFromEHplmn, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
1086         mFakeDns.setAnswer(expectedFqdnFromConfig, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
1087 
1088         ArrayList<InetAddress> testInetAddresses =
1089                 getValidatedServerListWithIpPreference(
1090                         EpdgSelector.PROTO_FILTER_IPV4,
1091                         EpdgSelector.SYSTEM_PREFERRED,
1092                         false /*isEmergency*/);
1093 
1094         assertEquals(1, testInetAddresses.size());
1095         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(0));
1096     }
1097 
1098     @Test
testGetValidatedServerListIpv6Only()1099     public void testGetValidatedServerListIpv6Only() throws Exception {
1100         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
1101         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
1102         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
1103 
1104         final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
1105         final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
1106         final String testStaticAddress = addr1 + "," + addr2;
1107 
1108         mFakeDns.setAnswer(addr1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
1109         mFakeDns.setAnswer(addr2, new String[] {TEST_IPV6_ADDRESS}, TYPE_AAAA);
1110 
1111         // Set carrier config mock
1112         IwlanCarrierConfig.putTestConfigIntArray(
1113                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
1114                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
1115         IwlanCarrierConfig.putTestConfigString(
1116                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
1117 
1118         ArrayList<InetAddress> testInetAddresses =
1119                 getValidatedServerListWithIpPreference(
1120                         EpdgSelector.PROTO_FILTER_IPV6,
1121                         EpdgSelector.SYSTEM_PREFERRED,
1122                         false /*isEmergency*/);
1123 
1124         assertEquals(1, testInetAddresses.size());
1125         assertEquals(InetAddress.getByName(TEST_IPV6_ADDRESS), testInetAddresses.get(0));
1126     }
1127 
1128     @Test
testGetValidatedServerListSystemPreferred()1129     public void testGetValidatedServerListSystemPreferred() throws Exception {
1130         when(DnsResolver.getInstance()).thenReturn(mMockDnsResolver);
1131         doReturn(true).when(mEpdgSelector).hasIpv4Address(mMockNetwork);
1132         doReturn(true).when(mEpdgSelector).hasIpv6Address(mMockNetwork);
1133 
1134         final String addr1 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
1135         final String addr2 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
1136         final String addr3 = "epdg.epc.mnc120.mcc312.pub.3gppnetwork.org";
1137         final String testStaticAddress = addr1 + "," + addr2 + "," + addr3;
1138 
1139         mFakeDns.setAnswer(addr1, new String[] {TEST_IP_ADDRESS_1}, TYPE_A);
1140         mFakeDns.setAnswer(addr2, new String[] {TEST_IPV6_ADDRESS}, TYPE_AAAA);
1141         mFakeDns.setAnswer(addr3, new String[] {TEST_IP_ADDRESS_2}, TYPE_A);
1142 
1143         // Set carrier config mock
1144         IwlanCarrierConfig.putTestConfigIntArray(
1145                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
1146                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
1147         IwlanCarrierConfig.putTestConfigString(
1148                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
1149 
1150         ArrayList<InetAddress> testInetAddresses =
1151                 getValidatedServerListWithIpPreference(
1152                         EpdgSelector.PROTO_FILTER_IPV4V6,
1153                         EpdgSelector.SYSTEM_PREFERRED,
1154                         false /*isEmergency*/);
1155 
1156         assertEquals(3, testInetAddresses.size());
1157         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_1), testInetAddresses.get(0));
1158         assertEquals(InetAddress.getByName(TEST_IPV6_ADDRESS), testInetAddresses.get(1));
1159         assertEquals(InetAddress.getByName(TEST_IP_ADDRESS_2), testInetAddresses.get(2));
1160     }
1161 
1162     /**
1163      * Fakes DNS responses.
1164      *
1165      * <p>Allows test methods to configure the IP addresses that will be resolved by
1166      * Network#getAllByName and by DnsResolver#query.
1167      */
1168     class FakeDns {
1169         /** Data class to record the Dns entry. */
1170         class DnsEntry {
1171             final String mHostname;
1172             final int mType;
1173             final List<InetAddress> mAddresses;
1174 
DnsEntry(String host, int type, List<InetAddress> addr)1175             DnsEntry(String host, int type, List<InetAddress> addr) {
1176                 mHostname = host;
1177                 mType = type;
1178                 mAddresses = addr;
1179             }
1180             // Full match or partial match that target host contains the entry hostname to support
1181             // random private dns probe hostname.
matches(String hostname, int type)1182             private boolean matches(String hostname, int type) {
1183                 return hostname.equals(mHostname) && type == mType;
1184             }
1185         }
1186 
1187         private final List<DnsEntry> mAnswers = new ArrayList<>();
1188 
1189         /** Clears all DNS entries. */
clearAll()1190         private synchronized void clearAll() {
1191             mAnswers.clear();
1192         }
1193 
1194         /** Returns the answer for a given name and type. */
getAnswer(String hostname, int type)1195         private synchronized List<InetAddress> getAnswer(String hostname, int type) {
1196             return mAnswers.stream()
1197                     .filter(e -> e.matches(hostname, type))
1198                     .map(answer -> answer.mAddresses)
1199                     .findFirst()
1200                     .orElse(List.of());
1201         }
1202 
1203         /** Sets the answer for a given name and type. */
setAnswer(String hostname, String[] answer, int type)1204         private synchronized void setAnswer(String hostname, String[] answer, int type)
1205                 throws UnknownHostException {
1206             DnsEntry record = new DnsEntry(hostname, type, generateAnswer(answer));
1207             // Remove the existing one.
1208             mAnswers.removeIf(entry -> entry.matches(hostname, type));
1209             // Add or replace a new record.
1210             mAnswers.add(record);
1211         }
1212 
generateAnswer(String[] answer)1213         private List<InetAddress> generateAnswer(String[] answer) {
1214             if (answer == null) return new ArrayList<>();
1215             return Arrays.stream(answer)
1216                     .map(addr -> InetAddresses.parseNumericAddress(addr))
1217                     .collect(toList());
1218         }
1219 
1220         // Regardless of the type, depends on what the responses contained in the network.
queryIpv4(String hostname)1221         private List<InetAddress> queryIpv4(String hostname) {
1222             return getAnswer(hostname, TYPE_A);
1223         }
1224 
1225         // Regardless of the type, depends on what the responses contained in the network.
queryIpv6(String hostname)1226         private List<InetAddress> queryIpv6(String hostname) {
1227             return getAnswer(hostname, TYPE_AAAA);
1228         }
1229 
1230         // Regardless of the type, depends on what the responses contained in the network.
queryAllTypes(String hostname)1231         private List<InetAddress> queryAllTypes(String hostname) {
1232             List<InetAddress> answer = new ArrayList<>();
1233             answer.addAll(queryIpv4(hostname));
1234             answer.addAll(queryIpv6(hostname));
1235             return answer;
1236         }
1237 
addAllIfNotNull(List<InetAddress> list, List<InetAddress> c)1238         private void addAllIfNotNull(List<InetAddress> list, List<InetAddress> c) {
1239             if (c != null) {
1240                 list.addAll(c);
1241             }
1242         }
1243 
1244         /** Starts mocking DNS queries. */
startMocking()1245         private void startMocking() throws UnknownHostException {
1246             // 5-arg DnsResolver.query()
1247             doAnswer(
1248                             invocation -> {
1249                                 return mockQuery(
1250                                         invocation,
1251                                         1 /* posHostname */,
1252                                         -1 /* posType */,
1253                                         3 /* posExecutor */,
1254                                         5 /* posCallback */);
1255                             })
1256                     .when(mMockDnsResolver)
1257                     .query(any(), anyString(), anyInt(), any(), any(), any());
1258 
1259             // 6-arg DnsResolver.query() with explicit query type (IPv4 or v6).
1260             doAnswer(
1261                             invocation -> {
1262                                 return mockQuery(
1263                                         invocation,
1264                                         1 /* posHostname */,
1265                                         2 /* posType */,
1266                                         4 /* posExecutor */,
1267                                         6 /* posCallback */);
1268                             })
1269                     .when(mMockDnsResolver)
1270                     .query(any(), anyString(), anyInt(), anyInt(), any(), any(), any());
1271         }
1272 
1273         // Mocking queries on DnsResolver#query.
mockQuery( InvocationOnMock invocation, int posHostname, int posType, int posExecutor, int posCallback)1274         private Answer mockQuery(
1275                 InvocationOnMock invocation,
1276                 int posHostname,
1277                 int posType,
1278                 int posExecutor,
1279                 int posCallback) {
1280             String hostname = invocation.getArgument(posHostname);
1281             Executor executor = invocation.getArgument(posExecutor);
1282             DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(posCallback);
1283             List<InetAddress> answer;
1284 
1285             switch (posType) {
1286                 case TYPE_A:
1287                     answer = queryIpv4(hostname);
1288                     break;
1289                 case TYPE_AAAA:
1290                     answer = queryIpv6(hostname);
1291                     break;
1292                 default:
1293                     answer = queryAllTypes(hostname);
1294             }
1295 
1296             if (answer != null && answer.size() > 0) {
1297                 new Handler(Looper.getMainLooper())
1298                         .post(
1299                                 () -> {
1300                                     executor.execute(() -> callback.onAnswer(answer, 0));
1301                                 });
1302             }
1303             // If no answers, do nothing. sendDnsProbeWithTimeout will time out and throw UHE.
1304             return null;
1305         }
1306     }
1307 
1308     @SuppressWarnings("FutureReturnValueIgnored")
1309     @Test
testMultipleBackToBackSetupDataCallRequest()1310     public void testMultipleBackToBackSetupDataCallRequest() throws Exception {
1311         when(mfakeFeatureFlags.preventEpdgSelectionThreadsExhausted()).thenReturn(true);
1312         EpdgSelector epdgSelector =
1313                 new EpdgSelector(mMockContext, DEFAULT_SLOT_INDEX, mfakeFeatureFlags);
1314         Runnable runnable = mock(Runnable.class);
1315         // Prefetch
1316         epdgSelector.trySubmitEpdgSelectionExecutor(runnable, true, false);
1317         // First set up data call
1318         epdgSelector.trySubmitEpdgSelectionExecutor(runnable, false, false);
1319         // Second set up data call
1320         epdgSelector.trySubmitEpdgSelectionExecutor(runnable, false, false);
1321     }
1322 
1323     @SuppressWarnings("FutureReturnValueIgnored")
1324     @Test
testBackToBackSetupDataCallRequest()1325     public void testBackToBackSetupDataCallRequest() throws Exception {
1326         when(mfakeFeatureFlags.preventEpdgSelectionThreadsExhausted()).thenReturn(false);
1327         EpdgSelector epdgSelector =
1328                 new EpdgSelector(mMockContext, DEFAULT_SLOT_INDEX, mfakeFeatureFlags);
1329         Runnable runnable = mock(Runnable.class);
1330         // Prefetch
1331         epdgSelector.trySubmitEpdgSelectionExecutor(runnable, true, false);
1332         // First set up data call
1333         epdgSelector.trySubmitEpdgSelectionExecutor(runnable, false, false);
1334         // Second set up data call request exhausts the thread pool
1335         assertThrows(
1336                 RejectedExecutionException.class,
1337                 () -> epdgSelector.trySubmitEpdgSelectionExecutor(runnable, false, false));
1338     }
1339 }
1340