• 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;
18 
19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertThrows;
24 import static org.junit.Assert.assertTrue;
25 import static org.mockito.Mockito.anyInt;
26 import static org.mockito.Mockito.doReturn;
27 import static org.mockito.Mockito.eq;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.spy;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 
33 import android.content.ContentResolver;
34 import android.content.Context;
35 import android.content.res.AssetManager;
36 import android.net.ipsec.ike.exceptions.IkeProtocolException;
37 import android.os.test.TestLooper;
38 import android.telephony.CarrierConfigManager;
39 import android.telephony.DataFailCause;
40 import android.telephony.SubscriptionInfo;
41 import android.telephony.SubscriptionManager;
42 import android.telephony.TelephonyManager;
43 import android.telephony.data.DataService;
44 
45 import com.google.auto.value.AutoValue;
46 
47 import org.json.JSONArray;
48 import org.junit.After;
49 import org.junit.Before;
50 import org.junit.Test;
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
53 import org.mockito.MockitoSession;
54 import org.mockito.quality.Strictness;
55 
56 import java.time.Duration;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.Optional;
60 
61 public class ErrorPolicyManagerTest {
62     @AutoValue
63     abstract static class ErrorPolicyString {
errorType()64         abstract String errorType();
65 
errorDetails()66         abstract List<String> errorDetails();
67 
retryArray()68         abstract List<String> retryArray();
69 
unthrottlingEvents()70         abstract List<String> unthrottlingEvents();
71 
numAttemptsPerFqdn()72         abstract Optional<String> numAttemptsPerFqdn();
73 
handoverAttemptCount()74         abstract Optional<String> handoverAttemptCount();
75 
builder()76         static Builder builder() {
77             return new AutoValue_ErrorPolicyManagerTest_ErrorPolicyString.Builder();
78         }
79 
80         @AutoValue.Builder
81         abstract static class Builder {
setErrorType(String errorType)82             abstract Builder setErrorType(String errorType);
83 
setErrorDetails(List<String> errorDetails)84             abstract Builder setErrorDetails(List<String> errorDetails);
85 
setRetryArray(List<String> retryArray)86             abstract Builder setRetryArray(List<String> retryArray);
87 
setUnthrottlingEvents(List<String> unthrottlingEvents)88             abstract Builder setUnthrottlingEvents(List<String> unthrottlingEvents);
89 
setNumAttemptsPerFqdn(String numAttemptsPerFqdn)90             abstract Builder setNumAttemptsPerFqdn(String numAttemptsPerFqdn);
91 
setHandoverAttemptCount(String handoverAttemptCount)92             abstract Builder setHandoverAttemptCount(String handoverAttemptCount);
93 
build()94             abstract ErrorPolicyString build();
95         }
96 
getErrorPolicyInString()97         String getErrorPolicyInString() {
98             StringBuilder errorPolicy =
99                     new StringBuilder(
100                             "\"ErrorType\": \""
101                                     + errorType()
102                                     + "\","
103                                     + "\"ErrorDetails\": [\""
104                                     + String.join("\", \"", errorDetails())
105                                     + "\"],"
106                                     + "\"RetryArray\": [\""
107                                     + String.join("\", \"", retryArray())
108                                     + "\"],"
109                                     + "\"UnthrottlingEvents\": [\""
110                                     + String.join("\", \"", unthrottlingEvents())
111                                     + "\"]");
112 
113             numAttemptsPerFqdn()
114                     .ifPresent(
115                             numAttemptsPerFqdn ->
116                                     errorPolicy
117                                             .append(",\"NumAttemptsPerFqdn\": \"")
118                                             .append(numAttemptsPerFqdn)
119                                             .append("\""));
120             handoverAttemptCount()
121                     .ifPresent(
122                             handoverAttemptCount ->
123                                     errorPolicy
124                                             .append(",\"HandoverAttemptCount\": \"")
125                                             .append(handoverAttemptCount)
126                                             .append("\""));
127             return errorPolicy.toString();
128         }
129     }
130 
131     private static final String TAG = "ErrorPolicyManagerTest";
132 
133     // @Rule public final MockitoRule mockito = MockitoJUnit.rule();
134 
135     private ErrorPolicyManager mErrorPolicyManager;
136     private static final int DEFAULT_SLOT_INDEX = 0;
137     private static final int DEFAULT_SUBID = 0;
138     private static final int TEST_CARRIER_ID = 1;
139 
140     private final TestLooper mTestLooper = new TestLooper();
141     private long mMockedClockTime = 0;
142     private int mCarrierId = TEST_CARRIER_ID;
143 
144     @Mock private Context mMockContext;
145     @Mock CarrierConfigManager mMockCarrierConfigManager;
146     @Mock SubscriptionManager mMockSubscriptionManager;
147     @Mock TelephonyManager mMockTelephonyManager;
148     @Mock SubscriptionInfo mMockSubscriptionInfo;
149     @Mock DataService.DataServiceProvider mMockDataServiceProvider;
150     @Mock private ContentResolver mMockContentResolver;
151     MockitoSession mStaticMockSession;
152 
153     @Before
setUp()154     public void setUp() throws Exception {
155         MockitoAnnotations.initMocks(this);
156         mStaticMockSession =
157                 mockitoSession()
158                         .mockStatic(IwlanDataService.class)
159                         .spyStatic(IwlanHelper.class)
160                         .strictness(Strictness.LENIENT)
161                         .startMocking();
162         when(IwlanDataService.getDataServiceProvider(anyInt()))
163                 .thenReturn(mMockDataServiceProvider);
164         when(IwlanHelper.elapsedRealtime()).thenAnswer(i -> mMockedClockTime);
165         doReturn(mMockSubscriptionManager)
166                 .when(mMockContext)
167                 .getSystemService(eq(SubscriptionManager.class));
168         doReturn(mMockTelephonyManager).when(mMockContext).getSystemService(TelephonyManager.class);
169         doReturn(mMockTelephonyManager)
170                 .when(mMockTelephonyManager)
171                 .createForSubscriptionId(anyInt());
172         when(mMockTelephonyManager.getSimCarrierId()).thenAnswer(i -> mCarrierId);
173         SubscriptionInfo mockSubInfo = mock(SubscriptionInfo.class);
174         doReturn(mockSubInfo)
175                 .when(mMockSubscriptionManager)
176                 .getActiveSubscriptionInfoForSimSlotIndex(DEFAULT_SLOT_INDEX);
177         doReturn(DEFAULT_SUBID).when(mockSubInfo).getSubscriptionId();
178         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
179         ErrorPolicyManager.resetAllInstances();
180         mErrorPolicyManager = spy(ErrorPolicyManager.getInstance(mMockContext, DEFAULT_SLOT_INDEX));
181         doReturn(mTestLooper.getLooper()).when(mErrorPolicyManager).getLooper();
182         mErrorPolicyManager.initHandler();
183     }
184 
185     @After
cleanUp()186     public void cleanUp() throws Exception {
187         mStaticMockSession.finishMocking();
188         mErrorPolicyManager.releaseInstance();
189         IwlanCarrierConfig.resetTestConfig();
190     }
191 
buildIwlanIkeProtocolError(int errorCode, byte[] errorData)192     private static IwlanError buildIwlanIkeProtocolError(int errorCode, byte[] errorData) {
193         final IkeProtocolException exception = mock(IkeProtocolException.class);
194         when(exception.getErrorType()).thenReturn(errorCode);
195         when(exception.getErrorData()).thenReturn(errorData);
196         return new IwlanError(exception);
197     }
198 
buildIwlanIkeProtocolError(int errorCode)199     private static IwlanError buildIwlanIkeProtocolError(int errorCode) {
200         return buildIwlanIkeProtocolError(errorCode, new byte[0]);
201     }
202 
buildIwlanIkeAuthFailedError()203     private static IwlanError buildIwlanIkeAuthFailedError() {
204         return buildIwlanIkeProtocolError(IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED);
205     }
206 
buildIwlanIkeChildSaNotFoundError()207     private static IwlanError buildIwlanIkeChildSaNotFoundError() {
208         return buildIwlanIkeProtocolError(IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND);
209     }
210 
buildIwlanIkeInternalAddressFailure()211     private static IwlanError buildIwlanIkeInternalAddressFailure() {
212         return buildIwlanIkeProtocolError(IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE);
213     }
214 
215     @Test
testValidCarrierConfig()216     public void testValidCarrierConfig() throws Exception {
217         String apn = "ims";
218         String config =
219                 "[{"
220                         + "\"ApnName\": \""
221                         + apn
222                         + "\","
223                         + "\"ErrorTypes\": [{"
224                         + ErrorPolicyString.builder()
225                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
226                                 .setErrorDetails(List.of("24", "34", "9000-9050"))
227                                 .setRetryArray(List.of("4", "8", "16"))
228                                 .setUnthrottlingEvents(
229                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
230                                 .build()
231                                 .getErrorPolicyInString()
232                         + "}, {"
233                         + ErrorPolicyString.builder()
234                                 .setErrorType("GENERIC_ERROR_TYPE")
235                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
236                                 .setRetryArray(List.of("0"))
237                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
238                                 .build()
239                                 .getErrorPolicyInString()
240                         + "}]"
241                         + "}]";
242 
243         IwlanCarrierConfig.putTestConfigString(
244                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
245         mErrorPolicyManager
246                 .mHandler
247                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
248                 .sendToTarget();
249         mTestLooper.dispatchAll();
250 
251         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
252         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
253         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
254         assertEquals(4, time);
255         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
256         assertEquals(8, time);
257         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
258         assertEquals(16, time);
259         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
260         assertEquals(86400, time);
261 
262         // Validate the range error detail.
263         iwlanError = buildIwlanIkeProtocolError(9030, new byte[] {0x00, 0x01});
264         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
265         assertEquals(4, time);
266         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
267         assertEquals(8, time);
268         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
269         assertEquals(16, time);
270         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
271         assertEquals(86400, time);
272 
273         // GENERIC_PROTOCOL_ERROR_TYPE - SERVER_SELECTION_FAILED and retryArray = 0
274         iwlanError = new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
275         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
276         assertEquals(0, time);
277         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
278         assertEquals(86400, time);
279         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
280         assertEquals(86400, time);
281 
282         // Fallback case IKE_INIT_TIMEOUT and retryArray is 1, 2, 2, 10, 20
283         // Should start at RetryIndex 0
284         iwlanError = new IwlanError(IwlanError.IKE_INIT_TIMEOUT);
285         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
286         assertEquals(1, time);
287         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
288         assertEquals(2, time);
289         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
290         assertEquals(2, time);
291         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
292         assertEquals(10, time);
293 
294         // Fallback case GENERIC_PROTOCOL_ERROR_TYPE(44) and retryArray is 5, 10, -1 as in
295         // DEFAULT_CONFIG
296         iwlanError = buildIwlanIkeChildSaNotFoundError();
297         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
298         assertEquals(5, time);
299         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
300         assertEquals(10, time);
301         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
302         assertEquals(10, time);
303         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
304         assertEquals(20, time);
305     }
306 
307     @Test
testShouldKeepRetryIndexForDifferentErrorCause()308     public void testShouldKeepRetryIndexForDifferentErrorCause() {
309         String apn = "ims";
310         String config =
311                 "[{"
312                         + "\"ApnName\": \""
313                         + apn
314                         + "\","
315                         + "\"ErrorTypes\": [{"
316                         + ErrorPolicyString.builder()
317                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
318                                 .setErrorDetails(List.of("24", "34", "9000-9050"))
319                                 .setRetryArray(List.of("4", "8", "16"))
320                                 .setUnthrottlingEvents(
321                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
322                                 .build()
323                                 .getErrorPolicyInString()
324                         + "}, {"
325                         + ErrorPolicyString.builder()
326                                 .setErrorType("GENERIC_ERROR_TYPE")
327                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
328                                 .setRetryArray(List.of("0"))
329                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
330                                 .build()
331                                 .getErrorPolicyInString()
332                         + "}]"
333                         + "}]";
334         IwlanCarrierConfig.putTestConfigString(
335                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
336         mErrorPolicyManager
337                 .mHandler
338                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
339                 .sendToTarget();
340         mTestLooper.dispatchAll();
341 
342         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
343         IwlanError authFailedIwlanError = buildIwlanIkeAuthFailedError();
344         IwlanError customProtocolIwlanError = buildIwlanIkeProtocolError(9030);
345         IwlanError serverSelectionIwlanError =
346                 new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
347 
348         long time = mErrorPolicyManager.reportIwlanError(apn, authFailedIwlanError);
349         assertEquals(4, time);
350 
351         // Different protocol error should have its own Index (i.e. not shared with auth error)
352         time = mErrorPolicyManager.reportIwlanError(apn, customProtocolIwlanError);
353         assertEquals(4, time);
354         time = mErrorPolicyManager.reportIwlanError(apn, customProtocolIwlanError);
355         assertEquals(8, time);
356         time = mErrorPolicyManager.reportIwlanError(apn, customProtocolIwlanError);
357         assertEquals(16, time);
358 
359         // Different IwlanError type should have its own index
360         time = mErrorPolicyManager.reportIwlanError(apn, serverSelectionIwlanError);
361         assertEquals(0, time);
362         time = mErrorPolicyManager.reportIwlanError(apn, serverSelectionIwlanError);
363         assertEquals(86400, time);
364 
365         // Retry index should not be cleared, should start from last same cause index (auth error)
366         time = mErrorPolicyManager.reportIwlanError(apn, authFailedIwlanError);
367         assertEquals(8, time);
368         time = mErrorPolicyManager.reportIwlanError(apn, authFailedIwlanError);
369         assertEquals(16, time);
370 
371         time = mErrorPolicyManager.reportIwlanError(apn, serverSelectionIwlanError);
372         assertEquals(86400, time);
373 
374         // if no error, it should clear the retry index
375         time = mErrorPolicyManager.reportIwlanError(apn, new IwlanError(IwlanError.NO_ERROR));
376         assertEquals(-1, time);
377 
378         // if backoff time is specified, should use the specified time instead
379         time = mErrorPolicyManager.reportIwlanError(apn, authFailedIwlanError);
380         assertEquals(4, time);
381         time = mErrorPolicyManager.reportIwlanError(apn, authFailedIwlanError, 5);
382         assertEquals(5, time);
383     }
384 
385     @Test
testDefaultPolicyFallback()386     public void testDefaultPolicyFallback() throws Exception {
387         String apn = "ims";
388         String config =
389                 "[{"
390                         + "\"ApnName\": \""
391                         + apn
392                         + "\","
393                         + "\"ErrorTypes\": [{"
394                         + ErrorPolicyString.builder()
395                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
396                                 .setErrorDetails(List.of("WRONG_ERROR_DETAIL"))
397                                 .setRetryArray(List.of("4", "8", "16"))
398                                 .setUnthrottlingEvents(
399                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
400                                 .build()
401                                 .getErrorPolicyInString()
402                         + "}]"
403                         + "}]";
404 
405         IwlanCarrierConfig.putTestConfigString(
406                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
407         mErrorPolicyManager
408                 .mHandler
409                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
410                 .sendToTarget();
411         mTestLooper.dispatchAll();
412 
413         // Fallback to default Iwlan error policy for IKE_PROTOCOL_ERROR_TYPE(24) because of failed
414         // parsing (or lack of explicit carrier-defined policy).
415         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
416         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
417         assertEquals(5, time);
418         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
419         assertEquals(10, time);
420         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
421         assertEquals(10, time);
422         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
423         assertEquals(20, time);
424         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
425         assertEquals(40, time);
426         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
427         assertEquals(80, time);
428 
429         iwlanError = buildIwlanIkeProtocolError(9002);
430         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
431         assertEquals(5, time);
432         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
433         assertEquals(10, time);
434         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
435         assertEquals(10, time);
436         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
437         assertEquals(20, time);
438         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
439         assertEquals(40, time);
440         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
441         assertEquals(80, time);
442 
443         iwlanError = buildIwlanIkeInternalAddressFailure();
444         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
445         assertEquals(0, time);
446         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
447         assertEquals(0, time);
448         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
449         assertEquals(0, time);
450         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
451         assertEquals(10, time);
452     }
453 
454     @Test
testChoosingFallbackPolicy()455     public void testChoosingFallbackPolicy() throws Exception {
456         String apn = "ims";
457         String config =
458                 "[{"
459                         + "\"ApnName\": \""
460                         + apn
461                         + "\","
462                         + "\"ErrorTypes\": [{"
463                         + ErrorPolicyString.builder()
464                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
465                                 .setErrorDetails(List.of("24", "34"))
466                                 .setRetryArray(List.of("4", "8", "16"))
467                                 .setUnthrottlingEvents(
468                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
469                                 .build()
470                                 .getErrorPolicyInString()
471                         + "}, {"
472                         + ErrorPolicyString.builder()
473                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
474                                 .setErrorDetails(List.of("*"))
475                                 .setRetryArray(List.of("0"))
476                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
477                                 .build()
478                                 .getErrorPolicyInString()
479                         + "}]"
480                         + "}]";
481         IwlanCarrierConfig.putTestConfigString(
482                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
483         mErrorPolicyManager
484                 .mHandler
485                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
486                 .sendToTarget();
487         mTestLooper.dispatchAll();
488 
489         mErrorPolicyManager.logErrorPolicies();
490 
491         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4, 8, 16
492         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
493         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
494         assertEquals(4, time);
495         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
496         assertEquals(8, time);
497         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
498         assertEquals(16, time);
499         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
500         assertEquals(86400, time);
501 
502         // IKE_PROTOCOL_ERROR_TYPE(44) and retryArray = 0 as it will fallback to
503         // IKE_PROTOCOL_ERROR_TYPE generic fallback first.
504         iwlanError = buildIwlanIkeChildSaNotFoundError();
505         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
506         assertEquals(0, time);
507         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
508         assertEquals(86400, time);
509     }
510 
511     @Test
testNullCarrierConfig()512     public void testNullCarrierConfig() throws Exception {
513         String apn = "ims";
514         String config =
515                 "[{"
516                         + "\"ApnName\": \""
517                         + apn
518                         + "\","
519                         + "\"ErrorTypes\": [{"
520                         + ErrorPolicyString.builder()
521                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
522                                 .setErrorDetails(List.of("24"))
523                                 .setRetryArray(List.of("100"))
524                                 .setUnthrottlingEvents(
525                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
526                                 .build()
527                                 .getErrorPolicyInString()
528                         + "}]"
529                         + "}]";
530 
531         IwlanCarrierConfig.putTestConfigString(
532                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
533         mCarrierId = 1;
534         mErrorPolicyManager
535                 .mHandler
536                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
537                 .sendToTarget();
538         mTestLooper.dispatchAll();
539 
540         // IKE_PROTOCOL_ERROR_TYPE(24) and retry time = 100.
541         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
542         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
543         assertEquals(100, time);
544 
545         IwlanCarrierConfig.putTestConfigString(
546                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, null);
547         mCarrierId = 2;
548         mErrorPolicyManager
549                 .mHandler
550                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
551                 .sendToTarget();
552         mTestLooper.dispatchAll();
553 
554         // IKE_PROTOCOL_ERROR_TYPE(24). Fall back to default error policy, retry time = 5.
555         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
556         assertEquals(5, time);
557     }
558 
559     @Test
testGetLastError()560     public void testGetLastError() {
561         String apn1 = "ims";
562         String apn2 = "mms";
563         String config =
564                 "[{"
565                         + "\"ApnName\": \""
566                         + apn1
567                         + "\","
568                         + "\"ErrorTypes\": [{"
569                         + ErrorPolicyString.builder()
570                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
571                                 .setErrorDetails(List.of("*"))
572                                 .setRetryArray(List.of("4", "8", "16"))
573                                 .setUnthrottlingEvents(
574                                         List.of("APM_DISABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
575                                 .build()
576                                 .getErrorPolicyInString()
577                         + "}]"
578                         + "}]";
579 
580         IwlanCarrierConfig.putTestConfigString(
581                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
582         mErrorPolicyManager
583                 .mHandler
584                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
585                 .sendToTarget();
586         mTestLooper.dispatchAll();
587 
588         IwlanError iwlanAuthError = buildIwlanIkeAuthFailedError();
589         mErrorPolicyManager.reportIwlanError(apn1, iwlanAuthError);
590 
591         assertEquals(iwlanAuthError, mErrorPolicyManager.getLastError(apn1));
592         assertEquals(new IwlanError(IwlanError.NO_ERROR), mErrorPolicyManager.getLastError(apn2));
593 
594         mErrorPolicyManager.reportIwlanError(apn2, iwlanAuthError);
595         assertEquals(iwlanAuthError, mErrorPolicyManager.getLastError(apn1));
596         assertEquals(iwlanAuthError, mErrorPolicyManager.getLastError(apn2));
597 
598         IwlanError iwlanInternalAddressFailure = buildIwlanIkeInternalAddressFailure();
599         mErrorPolicyManager.reportIwlanError(apn1, iwlanInternalAddressFailure);
600         assertEquals(iwlanInternalAddressFailure, mErrorPolicyManager.getLastError(apn1));
601         assertEquals(iwlanAuthError, mErrorPolicyManager.getLastError(apn2));
602 
603         // After APM enable, apn2 should have no last error and apn1 should keep last error
604         // Because apn1 protocol error config have no APM_ENABLE_EVENT in unthrottling events
605         mErrorPolicyManager
606                 .mHandler
607                 .obtainMessage(IwlanEventListener.APM_ENABLE_EVENT)
608                 .sendToTarget();
609         mTestLooper.dispatchAll();
610 
611         assertEquals(iwlanInternalAddressFailure, mErrorPolicyManager.getLastError(apn1));
612         assertEquals(new IwlanError(IwlanError.NO_ERROR), mErrorPolicyManager.getLastError(apn2));
613 
614         // After CarrierConfigChanged, all last error should be cleared
615         IwlanCarrierConfig.putTestConfigString(
616                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
617         mCarrierId = 2;
618         mErrorPolicyManager
619                 .mHandler
620                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
621                 .sendToTarget();
622         mTestLooper.dispatchAll();
623 
624         assertEquals(new IwlanError(IwlanError.NO_ERROR), mErrorPolicyManager.getLastError(apn1));
625         assertEquals(new IwlanError(IwlanError.NO_ERROR), mErrorPolicyManager.getLastError(apn2));
626     }
627 
628     @Test
testCanBringUpTunnel()629     public void testCanBringUpTunnel() throws Exception {
630         String apn = "ims";
631         String config =
632                 "[{"
633                         + "\"ApnName\": \""
634                         + apn
635                         + "\","
636                         + "\"ErrorTypes\": [{"
637                         + ErrorPolicyString.builder()
638                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
639                                 .setErrorDetails(List.of("24", "34"))
640                                 .setRetryArray(List.of("4", "8", "16"))
641                                 .setUnthrottlingEvents(
642                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
643                                 .build()
644                                 .getErrorPolicyInString()
645                         + "}, {"
646                         + ErrorPolicyString.builder()
647                                 .setErrorType("GENERIC_ERROR_TYPE")
648                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
649                                 .setRetryArray(List.of("0"))
650                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
651                                 .build()
652                                 .getErrorPolicyInString()
653                         + "}]"
654                         + "}]";
655         IwlanCarrierConfig.putTestConfigString(
656                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
657         mErrorPolicyManager
658                 .mHandler
659                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
660                 .sendToTarget();
661         mTestLooper.dispatchAll();
662 
663         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
664         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
665         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
666         assertEquals(4, time);
667 
668         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
669         assertFalse(bringUpTunnel);
670 
671         advanceClockByTimeMs(4000);
672 
673         bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
674         assertTrue(bringUpTunnel);
675 
676         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
677         assertEquals(8, time);
678 
679         bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
680         assertFalse(bringUpTunnel);
681     }
682 
683     @Test
testNoErrorScenario()684     public void testNoErrorScenario() throws Exception {
685         String apn = "ims";
686         String config =
687                 "[{"
688                         + "\"ApnName\": \""
689                         + apn
690                         + "\","
691                         + "\"ErrorTypes\": [{"
692                         + ErrorPolicyString.builder()
693                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
694                                 .setErrorDetails(List.of("24", "34"))
695                                 .setRetryArray(List.of("4", "8", "16"))
696                                 .setUnthrottlingEvents(
697                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
698                                 .build()
699                                 .getErrorPolicyInString()
700                         + "}, {"
701                         + ErrorPolicyString.builder()
702                                 .setErrorType("GENERIC_ERROR_TYPE")
703                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
704                                 .setRetryArray(List.of("0"))
705                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
706                                 .build()
707                                 .getErrorPolicyInString()
708                         + "}]"
709                         + "}]";
710         IwlanCarrierConfig.putTestConfigString(
711                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
712         mErrorPolicyManager
713                 .mHandler
714                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
715                 .sendToTarget();
716         mTestLooper.dispatchAll();
717 
718         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
719         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
720         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
721         assertEquals(4, time);
722 
723         // report no error
724         iwlanError = new IwlanError(IwlanError.NO_ERROR);
725         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
726         assertEquals(-1, time);
727 
728         // Check whether the error is cleared after NO_ERROR is reported
729         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
730         assertTrue(bringUpTunnel);
731     }
732 
733     @Test
testWifiDisableUnthrottle()734     public void testWifiDisableUnthrottle() throws Exception {
735         String apn = "ims";
736         String config =
737                 "[{"
738                         + "\"ApnName\": \""
739                         + apn
740                         + "\","
741                         + "\"ErrorTypes\": [{"
742                         + ErrorPolicyString.builder()
743                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
744                                 .setErrorDetails(List.of("24", "34"))
745                                 .setRetryArray(List.of("6", "12", "24"))
746                                 .setUnthrottlingEvents(
747                                         List.of("APM_ENABLE_EVENT", "WIFI_DISABLE_EVENT"))
748                                 .build()
749                                 .getErrorPolicyInString()
750                         + "}, {"
751                         + ErrorPolicyString.builder()
752                                 .setErrorType("GENERIC_ERROR_TYPE")
753                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
754                                 .setRetryArray(List.of("0"))
755                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
756                                 .build()
757                                 .getErrorPolicyInString()
758                         + "}]"
759                         + "}]";
760         IwlanCarrierConfig.putTestConfigString(
761                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
762         mErrorPolicyManager
763                 .mHandler
764                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
765                 .sendToTarget();
766         mTestLooper.dispatchAll();
767 
768         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 6, 12, 24
769         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
770         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
771         assertEquals(6, time);
772 
773         mErrorPolicyManager
774                 .mHandler
775                 .obtainMessage(IwlanEventListener.WIFI_DISABLE_EVENT)
776                 .sendToTarget();
777         advanceClockByTimeMs(500);
778         verify(mMockDataServiceProvider).notifyApnUnthrottled(eq(apn));
779 
780         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
781         assertTrue(bringUpTunnel);
782 
783         iwlanError = buildIwlanIkeAuthFailedError();
784         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
785         assertEquals(6, time);
786     }
787 
788     @Test
testWFCDisableUnthrottle()789     public void testWFCDisableUnthrottle() throws Exception {
790         String apn = "ims";
791         String config =
792                 "[{"
793                         + "\"ApnName\": \""
794                         + apn
795                         + "\","
796                         + "\"ErrorTypes\": [{"
797                         + ErrorPolicyString.builder()
798                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
799                                 .setErrorDetails(List.of("24", "34"))
800                                 .setRetryArray(List.of("6", "12", "24"))
801                                 .setUnthrottlingEvents(
802                                         List.of("WIFI_CALLING_DISABLE_EVENT", "WIFI_DISABLE_EVENT"))
803                                 .build()
804                                 .getErrorPolicyInString()
805                         + "}, {"
806                         + ErrorPolicyString.builder()
807                                 .setErrorType("GENERIC_ERROR_TYPE")
808                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
809                                 .setRetryArray(List.of("0"))
810                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
811                                 .build()
812                                 .getErrorPolicyInString()
813                         + "}]"
814                         + "}]";
815         IwlanCarrierConfig.putTestConfigString(
816                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
817         mErrorPolicyManager
818                 .mHandler
819                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
820                 .sendToTarget();
821         mTestLooper.dispatchAll();
822 
823         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 6, 12, 24
824         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
825         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
826         assertEquals(6, time);
827 
828         mErrorPolicyManager
829                 .mHandler
830                 .obtainMessage(IwlanEventListener.WIFI_CALLING_DISABLE_EVENT)
831                 .sendToTarget();
832         advanceClockByTimeMs(500);
833         verify(mMockDataServiceProvider).notifyApnUnthrottled(eq(apn));
834 
835         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
836         assertTrue(bringUpTunnel);
837 
838         iwlanError = buildIwlanIkeAuthFailedError();
839         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
840         assertEquals(6, time);
841     }
842 
843     @Test
testAPMUnthrottle()844     public void testAPMUnthrottle() throws Exception {
845         String apn = "ims";
846         String config =
847                 "[{"
848                         + "\"ApnName\": \""
849                         + apn
850                         + "\","
851                         + "\"ErrorTypes\": [{"
852                         + ErrorPolicyString.builder()
853                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
854                                 .setErrorDetails(List.of("24", "34"))
855                                 .setRetryArray(List.of("4", "8", "16"))
856                                 .setUnthrottlingEvents(
857                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
858                                 .build()
859                                 .getErrorPolicyInString()
860                         + "}, {"
861                         + ErrorPolicyString.builder()
862                                 .setErrorType("GENERIC_ERROR_TYPE")
863                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
864                                 .setRetryArray(List.of("0"))
865                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
866                                 .build()
867                                 .getErrorPolicyInString()
868                         + "}]"
869                         + "}]";
870         IwlanCarrierConfig.putTestConfigString(
871                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
872         mErrorPolicyManager
873                 .mHandler
874                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
875                 .sendToTarget();
876         mTestLooper.dispatchAll();
877 
878         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
879         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
880         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
881         assertEquals(4, time);
882 
883         mErrorPolicyManager
884                 .mHandler
885                 .obtainMessage(IwlanEventListener.APM_ENABLE_EVENT)
886                 .sendToTarget();
887         advanceClockByTimeMs(500);
888         verify(mMockDataServiceProvider).notifyApnUnthrottled(eq(apn));
889 
890         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
891         assertTrue(bringUpTunnel);
892 
893         iwlanError = buildIwlanIkeAuthFailedError();
894         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
895         assertEquals(4, time);
896     }
897 
898     @Test
testWifiApChangedUnthrottle()899     public void testWifiApChangedUnthrottle() throws Exception {
900         String apn = "ims";
901         String config =
902                 "[{"
903                         + "\"ApnName\": \""
904                         + apn
905                         + "\","
906                         + "\"ErrorTypes\": [{"
907                         + ErrorPolicyString.builder()
908                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
909                                 .setErrorDetails(List.of("24", "34"))
910                                 .setRetryArray(List.of("6", "12", "24"))
911                                 .setUnthrottlingEvents(
912                                         List.of(
913                                                 "WIFI_CALLING_DISABLE_EVENT",
914                                                 "WIFI_DISABLE_EVENT",
915                                                 "WIFI_AP_CHANGED_EVENT"))
916                                 .build()
917                                 .getErrorPolicyInString()
918                         + "}, {"
919                         + ErrorPolicyString.builder()
920                                 .setErrorType("GENERIC_ERROR_TYPE")
921                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
922                                 .setRetryArray(List.of("0"))
923                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
924                                 .build()
925                                 .getErrorPolicyInString()
926                         + "}]"
927                         + "}]";
928         IwlanCarrierConfig.putTestConfigString(
929                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
930         mErrorPolicyManager
931                 .mHandler
932                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
933                 .sendToTarget();
934         mTestLooper.dispatchAll();
935 
936         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 6, 12, 24
937         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
938         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
939         assertEquals(6, time);
940 
941         mErrorPolicyManager
942                 .mHandler
943                 .obtainMessage(IwlanEventListener.WIFI_AP_CHANGED_EVENT)
944                 .sendToTarget();
945         advanceClockByTimeMs(500);
946         verify(mMockDataServiceProvider).notifyApnUnthrottled(eq(apn));
947 
948         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
949         assertTrue(bringUpTunnel);
950 
951         iwlanError = buildIwlanIkeAuthFailedError();
952         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
953         assertEquals(6, time);
954     }
955 
956     @Test
testGetDataFailCauseRetryTime()957     public void testGetDataFailCauseRetryTime() throws Exception {
958         String apn1 = "ims";
959         String apn2 = "mms";
960         String config =
961                 "[{"
962                         + "\"ApnName\": \""
963                         + apn1
964                         + "\","
965                         + "\"ErrorTypes\": [{"
966                         + ErrorPolicyString.builder()
967                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
968                                 .setErrorDetails(List.of("24", "34"))
969                                 .setRetryArray(List.of("4", "8", "16"))
970                                 .setUnthrottlingEvents(
971                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
972                                 .build()
973                                 .getErrorPolicyInString()
974                         + "}, {"
975                         + ErrorPolicyString.builder()
976                                 .setErrorType("GENERIC_ERROR_TYPE")
977                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
978                                 .setRetryArray(List.of("0"))
979                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
980                                 .build()
981                                 .getErrorPolicyInString()
982                         + "}]"
983                         + "}]";
984         IwlanCarrierConfig.putTestConfigString(
985                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
986         mErrorPolicyManager
987                 .mHandler
988                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
989                 .sendToTarget();
990         mTestLooper.dispatchAll();
991 
992         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
993         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
994         long time = mErrorPolicyManager.reportIwlanError(apn1, iwlanError);
995         assertEquals(4, time);
996 
997         iwlanError =
998                 buildIwlanIkeProtocolError(
999                         8192 /*PDN_CONNECTION_REJECTION*/, new byte[] {0x00, 0x01});
1000         time = mErrorPolicyManager.reportIwlanError(apn2, iwlanError);
1001         assertEquals(5, time);
1002 
1003         int failCause = mErrorPolicyManager.getDataFailCause(apn1);
1004         assertEquals(DataFailCause.IWLAN_IKEV2_AUTH_FAILURE, failCause);
1005 
1006         failCause = mErrorPolicyManager.getDataFailCause(apn2);
1007         assertEquals(DataFailCause.IWLAN_PDN_CONNECTION_REJECTION, failCause);
1008 
1009         assertEquals(Duration.ofSeconds(4), mErrorPolicyManager.getRemainingBackoffDuration(apn1));
1010 
1011         assertEquals(Duration.ofSeconds(5), mErrorPolicyManager.getRemainingBackoffDuration(apn2));
1012     }
1013 
1014     @Test
testBackOffTime()1015     public void testBackOffTime() throws Exception {
1016         String apn = "ims";
1017         String config =
1018                 "[{"
1019                         + "\"ApnName\": \""
1020                         + apn
1021                         + "\","
1022                         + "\"ErrorTypes\": [{"
1023                         + ErrorPolicyString.builder()
1024                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
1025                                 .setErrorDetails(List.of("24", "34"))
1026                                 .setRetryArray(List.of("10", "15", "20"))
1027                                 .setUnthrottlingEvents(
1028                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
1029                                 .build()
1030                                 .getErrorPolicyInString()
1031                         + "}, {"
1032                         + ErrorPolicyString.builder()
1033                                 .setErrorType("GENERIC_ERROR_TYPE")
1034                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
1035                                 .setRetryArray(List.of("0"))
1036                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
1037                                 .build()
1038                                 .getErrorPolicyInString()
1039                         + "}]"
1040                         + "}]";
1041 
1042         IwlanCarrierConfig.putTestConfigString(
1043                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
1044         mErrorPolicyManager
1045                 .mHandler
1046                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
1047                 .sendToTarget();
1048         mTestLooper.dispatchAll();
1049 
1050         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
1051         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
1052         mErrorPolicyManager.reportIwlanError(apn, iwlanError, 2);
1053 
1054         assertEquals(Duration.ofSeconds(2), mErrorPolicyManager.getRemainingBackoffDuration(apn));
1055 
1056         // advanceClockByTimeMs for 2 seconds and make sure that we can bring up tunnel after 2 secs
1057         // as back off time - 2 secs should override the retry time in policy - 10 secs
1058         advanceClockByTimeMs(2000);
1059         boolean bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
1060         assertTrue(bringUpTunnel);
1061 
1062         // test whether the same error reported later uses the right policy
1063         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1064         assertEquals(10, time);
1065 
1066         bringUpTunnel = mErrorPolicyManager.canBringUpTunnel(apn);
1067         assertFalse(bringUpTunnel);
1068 
1069         mErrorPolicyManager.reportIwlanError(apn, iwlanError, 5);
1070         assertEquals(Duration.ofSeconds(5), mErrorPolicyManager.getRemainingBackoffDuration(apn));
1071 
1072         // test whether the same error reported later starts from the beginning of retry array
1073         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1074         assertEquals(10, time);
1075 
1076         // retry time should be -1 when no error
1077         time = mErrorPolicyManager.reportIwlanError(apn, new IwlanError(IwlanError.NO_ERROR), 5);
1078         assertEquals(time, -1);
1079     }
1080 
1081     @Test
testErrorPolicyWithNumAttemptsPerFqdn()1082     public void testErrorPolicyWithNumAttemptsPerFqdn() throws Exception {
1083         // ErrorPolicyManager#getCurrentFqdnIndex() is tested when the ErrorType
1084         // parameter "NumAttemptsPerFqdn" is configured.
1085         String apn = "ims";
1086         String config =
1087                 "[{"
1088                         + "\"ApnName\": \""
1089                         + apn
1090                         + "\","
1091                         + "\"ErrorTypes\": [{"
1092                         + ErrorPolicyString.builder()
1093                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
1094                                 .setErrorDetails(List.of("15500")) /* CONGESTION */
1095                                 .setRetryArray(
1096                                         List.of(
1097                                                 "0", "0", "300", "600", "1200", "0", "0", "0",
1098                                                 "300", "600", "1200", "-1"))
1099                                 .setUnthrottlingEvents(
1100                                         List.of(
1101                                                 "APM_ENABLE_EVENT",
1102                                                 "WIFI_DISABLE_EVENT",
1103                                                 "WIFI_CALLING_DISABLE_EVENT"))
1104                                 .setNumAttemptsPerFqdn("6")
1105                                 .build()
1106                                 .getErrorPolicyInString()
1107                         + "}]"
1108                         + "}]";
1109 
1110         IwlanCarrierConfig.putTestConfigString(
1111                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
1112         mErrorPolicyManager
1113                 .mHandler
1114                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
1115                 .sendToTarget();
1116         mTestLooper.dispatchAll();
1117         assertEquals(DataFailCause.NONE, mErrorPolicyManager.getMostRecentDataFailCause());
1118 
1119         // IKE_PROTOCOL_ERROR_TYPE(15500)
1120         // UE constructs 2 PLMN FQDNs.
1121         IwlanError iwlanError = buildIwlanIkeProtocolError(15500 /* CONGESTION */);
1122 
1123         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1124         assertEquals(0, time);
1125         assertEquals(
1126                 DataFailCause.IWLAN_CONGESTION, mErrorPolicyManager.getMostRecentDataFailCause());
1127 
1128         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1129         assertEquals(0, time);
1130         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1131         assertEquals(300, time);
1132         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1133         assertEquals(600, time);
1134 
1135         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1136         assertEquals(1200, time);
1137         assertEquals(0, mErrorPolicyManager.getCurrentFqdnIndex(2));
1138 
1139         // Cycles to next FQDN
1140         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1141         assertEquals(0, time);
1142         assertEquals(1, mErrorPolicyManager.getCurrentFqdnIndex(2));
1143 
1144         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1145         assertEquals(0, time);
1146         assertEquals(1, mErrorPolicyManager.getCurrentFqdnIndex(2));
1147 
1148         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1149         assertEquals(0, time);
1150         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1151         assertEquals(300, time);
1152         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1153         assertEquals(600, time);
1154         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1155         assertEquals(1200, time);
1156 
1157         // Steady state retry duration, cycles back to 1st FQDN.
1158         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1159         assertEquals(1200, time);
1160         assertEquals(0, mErrorPolicyManager.getCurrentFqdnIndex(2));
1161     }
1162 
1163     @Test
testShouldRetryWithInitialAttach()1164     public void testShouldRetryWithInitialAttach() throws Exception {
1165         String apn = "ims";
1166         String config =
1167                 "[{"
1168                         + "\"ApnName\": \""
1169                         + apn
1170                         + "\","
1171                         + "\"ErrorTypes\": [{"
1172                         + ErrorPolicyString.builder()
1173                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
1174                                 .setErrorDetails(List.of("24", "34"))
1175                                 .setRetryArray(List.of("4", "8", "16"))
1176                                 .setUnthrottlingEvents(
1177                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
1178                                 .setHandoverAttemptCount("2")
1179                                 .build()
1180                                 .getErrorPolicyInString()
1181                         + "}]"
1182                         + "}]";
1183 
1184         IwlanCarrierConfig.putTestConfigString(
1185                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
1186         mErrorPolicyManager
1187                 .mHandler
1188                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
1189                 .sendToTarget();
1190         mTestLooper.dispatchAll();
1191 
1192         // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 4,8,16
1193         IwlanError iwlanError = buildIwlanIkeAuthFailedError();
1194         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1195         assertEquals(4, time);
1196         assertFalse(mErrorPolicyManager.shouldRetryWithInitialAttach(apn));
1197 
1198         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1199         assertEquals(8, time);
1200         // Reached handover attempt count and error is IKE protocol error
1201         assertTrue(mErrorPolicyManager.shouldRetryWithInitialAttach(apn));
1202     }
1203 
1204     @Test
testShouldRetryWithInitialAttachForInternalError()1205     public void testShouldRetryWithInitialAttachForInternalError() throws Exception {
1206         String apn = "ims";
1207         String config =
1208                 "[{"
1209                         + "\"ApnName\": \""
1210                         + apn
1211                         + "\","
1212                         + "\"ErrorTypes\": [{"
1213                         + ErrorPolicyString.builder()
1214                                 .setErrorType("IKE_PROTOCOL_ERROR_TYPE")
1215                                 .setErrorDetails(List.of("24", "34"))
1216                                 .setRetryArray(List.of("4", "8", "16"))
1217                                 .setUnthrottlingEvents(
1218                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
1219                                 .setHandoverAttemptCount("2")
1220                                 .build()
1221                                 .getErrorPolicyInString()
1222                         + "}, {"
1223                         + ErrorPolicyString.builder()
1224                                 .setErrorType("GENERIC_ERROR_TYPE")
1225                                 .setErrorDetails(List.of("SERVER_SELECTION_FAILED"))
1226                                 .setRetryArray(List.of("0", "0"))
1227                                 .setUnthrottlingEvents(List.of("APM_ENABLE_EVENT"))
1228                                 .build()
1229                                 .getErrorPolicyInString()
1230                         + "}]"
1231                         + "}]";
1232 
1233         IwlanCarrierConfig.putTestConfigString(
1234                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, config);
1235         mErrorPolicyManager
1236                 .mHandler
1237                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
1238                 .sendToTarget();
1239         mTestLooper.dispatchAll();
1240 
1241         // GENERIC_PROTOCOL_ERROR_TYPE - SERVER_SELECTION_FAILED and retryArray = 0, 0
1242         IwlanError iwlanError = new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
1243         long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1244         assertEquals(0, time);
1245         assertFalse(mErrorPolicyManager.shouldRetryWithInitialAttach(apn));
1246 
1247         time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1248         assertEquals(0, time);
1249         // Should not retry with initial attach as the errors are not IKE_PROTOCOL_ERROR_TYPE
1250         assertFalse(mErrorPolicyManager.shouldRetryWithInitialAttach(apn));
1251     }
1252 
1253     @Test
testHandoverAttemptCountInvalidErrorType()1254     public void testHandoverAttemptCountInvalidErrorType() throws Exception {
1255         String apn = "ims";
1256         String config =
1257                 "[{"
1258                         + "\"ApnName\": \""
1259                         + apn
1260                         + "\","
1261                         + "\"ErrorTypes\": [{"
1262                         + ErrorPolicyString.builder()
1263                                 .setErrorType("GENERIC_ERROR_TYPE")
1264                                 .setErrorDetails(List.of("*"))
1265                                 .setRetryArray(List.of("4", "8", "16"))
1266                                 .setUnthrottlingEvents(
1267                                         List.of("APM_ENABLE_EVENT", "WIFI_AP_CHANGED_EVENT"))
1268                                 .setHandoverAttemptCount("2")
1269                                 .build()
1270                                 .getErrorPolicyInString()
1271                         + "}]"
1272                         + "}]";
1273 
1274         assertThrows(
1275                 IllegalArgumentException.class,
1276                 () -> mErrorPolicyManager.readErrorPolicies(new JSONArray(config)));
1277     }
1278 
1279     @Test
testErrorStats()1280     public void testErrorStats() throws Exception {
1281         String apn1 = "ims";
1282         String apn2 = "mms";
1283 
1284         IwlanError iwlanError1 = buildIwlanIkeAuthFailedError();
1285         long ikeAuthCountApn1 = 4L;
1286         long ikeAuthCountApn2 = 5L;
1287         for (int i = 0; i < ikeAuthCountApn1; i++) {
1288             mErrorPolicyManager.reportIwlanError(apn1, iwlanError1);
1289         }
1290         for (int i = 0; i < ikeAuthCountApn2; i++) {
1291             mErrorPolicyManager.reportIwlanError(apn2, iwlanError1);
1292         }
1293 
1294         long serverSelectionCountApn1 = 3L;
1295         long serverSelectionCountApn2 = 6L;
1296         IwlanError iwlanError2 = new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
1297         for (int i = 0; i < serverSelectionCountApn1; i++) {
1298             mErrorPolicyManager.reportIwlanError(apn1, iwlanError2);
1299         }
1300         // calling backoff timer api
1301         for (int i = 0; i < serverSelectionCountApn2; i++) {
1302             mErrorPolicyManager.reportIwlanError(apn2, iwlanError2, 3);
1303         }
1304 
1305         Map<String, Long> apn1Stats = mErrorPolicyManager.getErrorStats().mStats.get(apn1);
1306         Map<String, Long> apn2Stats = mErrorPolicyManager.getErrorStats().mStats.get(apn2);
1307 
1308         long resultAuthApn1 = apn1Stats.get(iwlanError1.toString());
1309         long resultAuthApn2 = apn2Stats.get(iwlanError1.toString());
1310         long resultServerApn1 = apn1Stats.get(iwlanError2.toString());
1311         long resultServerApn2 = apn2Stats.get(iwlanError2.toString());
1312         assertEquals(resultAuthApn1, ikeAuthCountApn1);
1313         assertEquals(resultAuthApn2, ikeAuthCountApn2);
1314         assertEquals(resultServerApn1, serverSelectionCountApn1);
1315         assertEquals(resultServerApn2, serverSelectionCountApn2);
1316     }
1317 
1318     @Test
testGetLastRetryIndex()1319     public void testGetLastRetryIndex() {
1320         String apn = "ims";
1321 
1322         mErrorPolicyManager
1323                 .mHandler
1324                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
1325                 .sendToTarget();
1326         mTestLooper.dispatchAll();
1327 
1328         // error count should be 0 when no error yet
1329         assertEquals(0, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1330 
1331         // same error reported, should accumulate
1332         IwlanError iwlanAuthError = buildIwlanIkeAuthFailedError();
1333         mErrorPolicyManager.reportIwlanError(apn, iwlanAuthError);
1334         assertEquals(1, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1335         mErrorPolicyManager.reportIwlanError(apn, iwlanAuthError);
1336         assertEquals(2, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1337         mErrorPolicyManager.reportIwlanError(apn, iwlanAuthError);
1338         assertEquals(3, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1339 
1340         // different error reported, should start with 1 then accumulate
1341         IwlanError iwlanOtherProtocolError = buildIwlanIkeProtocolError(9002);
1342         mErrorPolicyManager.reportIwlanError(apn, iwlanOtherProtocolError);
1343         assertEquals(1, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1344         mErrorPolicyManager.reportIwlanError(apn, iwlanOtherProtocolError);
1345         assertEquals(2, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1346 
1347         // different error with specific backoff time reported, should start with 1 then accumulate
1348         IwlanError iwlanInternalAddressFailure = buildIwlanIkeInternalAddressFailure();
1349         mErrorPolicyManager.reportIwlanError(apn, iwlanInternalAddressFailure, 5);
1350         assertEquals(1, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1351         mErrorPolicyManager.reportIwlanError(apn, iwlanInternalAddressFailure, 5);
1352         assertEquals(2, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1353 
1354         // same error with specific backoff time, should continue from last error count (2)
1355         mErrorPolicyManager.reportIwlanError(apn, iwlanOtherProtocolError, 5);
1356         assertEquals(3, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1357         // error without backoff time again, should continue from last error count (3)
1358         mErrorPolicyManager.reportIwlanError(apn, iwlanOtherProtocolError);
1359         assertEquals(4, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1360 
1361         // the retry index from iwlan auth error should be reserved
1362         mErrorPolicyManager.reportIwlanError(apn, iwlanAuthError);
1363         assertEquals(4, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1364 
1365         // Unthrottle event should reset the error count
1366         mErrorPolicyManager
1367                 .mHandler
1368                 .obtainMessage(IwlanEventListener.APM_ENABLE_EVENT)
1369                 .sendToTarget();
1370         mTestLooper.dispatchAll();
1371 
1372         assertEquals(0, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1373 
1374         mErrorPolicyManager.reportIwlanError(apn, iwlanAuthError);
1375         assertEquals(1, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1376 
1377         mErrorPolicyManager.reportIwlanError(apn, iwlanOtherProtocolError, 5);
1378         assertEquals(1, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1379 
1380         mErrorPolicyManager.reportIwlanError(apn, new IwlanError(IwlanError.NO_ERROR));
1381         // NO_ERROR should reset the error count
1382         assertEquals(0, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1383 
1384         mErrorPolicyManager.reportIwlanError(apn, iwlanAuthError);
1385         assertEquals(1, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1386 
1387         mErrorPolicyManager.reportIwlanError(apn, iwlanOtherProtocolError, 5);
1388         assertEquals(1, mErrorPolicyManager.getLastErrorCountOfSameCause(apn));
1389     }
1390 
advanceClockByTimeMs(long time)1391     private void advanceClockByTimeMs(long time) {
1392         mMockedClockTime += time;
1393         mTestLooper.dispatchAll();
1394     }
1395 
1396     @Test
testShouldNotThrowWhenDefaultConfigInvalid()1397     public void testShouldNotThrowWhenDefaultConfigInvalid() throws Exception {
1398         String apn = "ims";
1399         AssetManager mockAssetManager = mock(AssetManager.class);
1400         doReturn(mockAssetManager).when(mMockContext).getAssets();
1401 
1402         // when the default config do not match all error with "ErrorType": "*"
1403         String defaultConfigErrorTypeJson =
1404                 "{\"ErrorType\": \"IKE_PROTOCOL_ERROR_TYPE\", \"ErrorDetails\": [\"*\"], "
1405                         + "\"RetryArray\": [\"0\"], \"UnthrottlingEvents\": []}";
1406         String defaultConfigJson =
1407                 "[{\"ApnName\": \"*\", \"ErrorTypes\": [" + defaultConfigErrorTypeJson + "]}]";
1408         IwlanCarrierConfig.putTestConfigString(
1409                 IwlanCarrierConfig.KEY_ERROR_POLICY_CONFIG_STRING, defaultConfigJson);
1410 
1411         // need to reconstruct error policy manager with the mocked default config
1412         mErrorPolicyManager.releaseInstance();
1413         mErrorPolicyManager = spy(ErrorPolicyManager.getInstance(mMockContext, DEFAULT_SLOT_INDEX));
1414         doReturn(mTestLooper.getLooper()).when(mErrorPolicyManager).getLooper();
1415         mErrorPolicyManager.initHandler();
1416 
1417         mErrorPolicyManager
1418                 .mHandler
1419                 .obtainMessage(IwlanEventListener.CARRIER_CONFIG_CHANGED_EVENT)
1420                 .sendToTarget();
1421         mTestLooper.dispatchAll();
1422 
1423         // if some error happen and no policy in carrier config match, and the default config do
1424         // not have at least 1 policy can apply to all error, it should not throw error
1425         IwlanError iwlanError = new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
1426         mErrorPolicyManager.reportIwlanError(apn, iwlanError);
1427     }
1428 }
1429