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