1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ons; 18 19 import static org.mockito.Mockito.any; 20 import static org.mockito.Mockito.doNothing; 21 import static org.mockito.Mockito.doReturn; 22 import static org.mockito.Mockito.eq; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.times; 25 import static org.mockito.Mockito.verify; 26 import static org.mockito.Mockito.verifyZeroInteractions; 27 28 import android.content.Context; 29 import android.content.Intent; 30 import android.os.Looper; 31 import android.os.PersistableBundle; 32 import android.telephony.CarrierConfigManager; 33 import android.telephony.SubscriptionInfo; 34 import android.telephony.euicc.DownloadableSubscription; 35 import android.telephony.euicc.EuiccManager; 36 import android.util.Log; 37 import android.util.Pair; 38 39 import com.android.ons.ONSProfileDownloader.DownloadProfileResult; 40 41 import org.junit.After; 42 import org.junit.Before; 43 import org.junit.Test; 44 import org.mockito.Mock; 45 import org.mockito.MockitoAnnotations; 46 47 public class ONSProfileDownloaderTest extends ONSBaseTest { 48 private static final String TAG = ONSProfileDownloaderTest.class.getName(); 49 private static final int TEST_SUB_ID = 1; 50 private static final String TEST_SMDP_ADDRESS = "TEST-ESIM.COM"; 51 52 @Mock 53 Context mMockContext; 54 @Mock 55 EuiccManager mMockEUICCManager; 56 @Mock 57 SubscriptionInfo mMockSubInfo; 58 @Mock 59 CarrierConfigManager mMockCarrierConfigManager; 60 @Mock 61 private ONSProfileConfigurator mMockONSProfileConfig; 62 @Mock 63 ONSProfileDownloader.IONSProfileDownloaderListener mMockDownloadListener; 64 65 @Before setUp()66 public void setUp() throws Exception { 67 super.setUp("ONSTest"); 68 MockitoAnnotations.initMocks(this); 69 Looper.prepare(); 70 } 71 72 static class WorkerThread extends Thread { 73 Looper mWorkerLooper; 74 private final Runnable mRunnable; 75 WorkerThread(Runnable runnable)76 WorkerThread(Runnable runnable) { 77 mRunnable = runnable; 78 } 79 80 @Override run()81 public void run() { 82 super.run(); 83 Looper.prepare(); 84 mWorkerLooper = Looper.myLooper(); 85 mRunnable.run(); 86 mWorkerLooper.loop(); 87 } 88 exit()89 public void exit() { 90 mWorkerLooper.quitSafely(); 91 } 92 } 93 94 @Test testNullSMDPAddress()95 public void testNullSMDPAddress() { 96 doReturn(TEST_SUB_ID).when(mMockSubInfo).getSubscriptionId(); 97 PersistableBundle config = new PersistableBundle(); 98 config.putString(CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, null); 99 doReturn(config).when(mMockCarrierConfigManager).getConfigForSubId(TEST_SUB_ID); 100 101 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mMockContext, 102 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, null); 103 104 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 105 106 verify(mMockEUICCManager, never()).downloadSubscription(null, true, null); 107 } 108 109 @Test testDownloadSuccessCallback()110 public void testDownloadSuccessCallback() { 111 112 final Object lock = new Object(); 113 final ONSProfileDownloader.IONSProfileDownloaderListener mListener = 114 new ONSProfileDownloader.IONSProfileDownloaderListener() { 115 @Override 116 public void onDownloadComplete(int primarySubId) { 117 assertEquals(primarySubId, TEST_SUB_ID); 118 synchronized (lock) { 119 lock.notify(); 120 } 121 } 122 123 @Override 124 public void onDownloadError( 125 int pSIMSubId, 126 ONSProfileDownloader.DownloadRetryResultCode operationCode, 127 int detailedErrorCode) { 128 129 } 130 }; 131 132 Runnable runnable = new Runnable() { 133 @Override 134 public void run() { 135 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mMockContext, 136 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 137 mListener); 138 139 Intent intent = new Intent(mContext, ONSProfileResultReceiver.class); 140 intent.setAction(ONSProfileDownloader.ACTION_ONS_ESIM_DOWNLOAD); 141 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, ONSProfileDownloader.class.getName()); 142 intent.putExtra(ONSProfileDownloader.PARAM_PRIMARY_SUBID, TEST_SUB_ID); 143 intent.putExtra(ONSProfileDownloader.PARAM_REQUEST_TYPE, 144 ONSProfileDownloader.REQUEST_CODE_DOWNLOAD_SUB); 145 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE, 0); 146 147 onsProfileDownloader.onCallbackIntentReceived(intent, 148 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK); 149 } 150 }; 151 152 WorkerThread workerThread = new WorkerThread(runnable); 153 workerThread.start(); 154 155 synchronized (lock) { 156 try { 157 lock.wait(); 158 } catch (Exception e) { 159 Log.e(TAG, e.getMessage()); 160 } 161 } 162 163 workerThread.exit(); 164 } 165 166 @Test testDownloadFailureUnresolvableError()167 public void testDownloadFailureUnresolvableError() { 168 PersistableBundle config = new PersistableBundle(); 169 config.putInt(CarrierConfigManager.KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT, 1); 170 config.putInt(CarrierConfigManager.KEY_ESIM_MAX_DOWNLOAD_RETRY_ATTEMPTS_INT, 2); 171 config.putString(CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, TEST_SMDP_ADDRESS); 172 doReturn(config).when(mMockCarrierConfigManager).getConfigForSubId(TEST_SUB_ID); 173 174 Runnable runnable = new Runnable() { 175 @Override 176 public void run() { 177 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mMockContext, 178 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 179 mMockDownloadListener); 180 181 Intent intent = new Intent(mContext, ONSProfileResultReceiver.class); 182 intent.setAction(ONSProfileDownloader.ACTION_ONS_ESIM_DOWNLOAD); 183 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, ONSProfileDownloader.class.getName()); 184 intent.putExtra(ONSProfileDownloader.PARAM_PRIMARY_SUBID, TEST_SUB_ID); 185 intent.putExtra(ONSProfileDownloader.PARAM_REQUEST_TYPE, 186 ONSProfileDownloader.REQUEST_CODE_DOWNLOAD_SUB); 187 188 onsProfileDownloader.onCallbackIntentReceived(intent, 189 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR); 190 } 191 }; 192 193 WorkerThread workerThread = new WorkerThread(runnable); 194 workerThread.start(); 195 196 try { 197 Thread.sleep(3000); 198 } catch (Exception e) { 199 e.printStackTrace(); 200 } 201 202 verifyZeroInteractions(mMockEUICCManager); 203 workerThread.exit(); 204 } 205 206 @Test testDownloadFailureMemoryFullError()207 public void testDownloadFailureMemoryFullError() { 208 209 Runnable runnable = new Runnable() { 210 @Override 211 public void run() { 212 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mMockContext, 213 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 214 mMockDownloadListener); 215 216 Intent intent = new Intent(mContext, ONSProfileResultReceiver.class); 217 intent.setAction(ONSProfileDownloader.ACTION_ONS_ESIM_DOWNLOAD); 218 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, ONSProfileDownloader.class.getName()); 219 intent.putExtra(ONSProfileDownloader.PARAM_PRIMARY_SUBID, TEST_SUB_ID); 220 intent.putExtra(ONSProfileDownloader.PARAM_REQUEST_TYPE, 221 ONSProfileDownloader.REQUEST_CODE_DOWNLOAD_SUB); 222 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE, 223 EuiccManager.OPERATION_EUICC_GSMA); 224 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE, 225 EuiccManager.ERROR_EUICC_INSUFFICIENT_MEMORY); 226 227 onsProfileDownloader.onCallbackIntentReceived(intent, 228 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR); 229 } 230 }; 231 232 WorkerThread workerThread = new WorkerThread(runnable); 233 workerThread.start(); 234 235 try { 236 Thread.sleep(1000); 237 } catch (Exception e) { 238 Log.e(TAG, e.getMessage()); 239 } 240 241 verify(mMockDownloadListener).onDownloadError( 242 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_MEMORY_FULL, 0); 243 workerThread.exit(); 244 } 245 246 @Test testDownloadFailureConnectionError()247 public void testDownloadFailureConnectionError() { 248 PersistableBundle config = new PersistableBundle(); 249 config.putInt(CarrierConfigManager.KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT, 1); 250 config.putInt(CarrierConfigManager.KEY_ESIM_MAX_DOWNLOAD_RETRY_ATTEMPTS_INT, 2); 251 config.putString(CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, TEST_SMDP_ADDRESS); 252 doReturn(config).when(mMockCarrierConfigManager).getConfigForSubId(TEST_SUB_ID); 253 doNothing().when(mMockDownloadListener).onDownloadError( 254 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_RETRY_DOWNLOAD, 0); 255 256 Runnable runnable = new Runnable() { 257 @Override 258 public void run() { 259 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mContext, 260 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 261 mMockDownloadListener); 262 263 Intent intent = new Intent(mContext, ONSProfileResultReceiver.class); 264 intent.setAction(ONSProfileDownloader.ACTION_ONS_ESIM_DOWNLOAD); 265 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, ONSProfileDownloader.class.getName()); 266 intent.putExtra(ONSProfileDownloader.PARAM_PRIMARY_SUBID, TEST_SUB_ID); 267 intent.putExtra(ONSProfileDownloader.PARAM_REQUEST_TYPE, 268 ONSProfileDownloader.REQUEST_CODE_DOWNLOAD_SUB); 269 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE, 270 EuiccManager.ERROR_CONNECTION_ERROR); 271 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE, 272 EuiccManager.OPERATION_SMDX); 273 274 onsProfileDownloader.onCallbackIntentReceived(intent, 275 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR); 276 } 277 }; 278 279 WorkerThread workerThread = new WorkerThread(runnable); 280 workerThread.start(); 281 282 //After first download error, next download will be triggered between 1 & 2* 283 //CarrierConfigManager.KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT(1sec for testing) 284 //Should take less than 2 secs for download re-attempt. 285 try { 286 Thread.sleep(3000); 287 } catch (Exception e) { 288 Log.e(TAG, e.getMessage()); 289 } 290 291 String testActCode = DownloadableSubscription.forActivationCode(TEST_SMDP_ADDRESS) 292 .getEncodedActivationCode(); 293 294 verify(mMockDownloadListener).onDownloadError( 295 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_RETRY_DOWNLOAD, 0); 296 297 workerThread.exit(); 298 } 299 300 @Test testDownloadFailureTimeout()301 public void testDownloadFailureTimeout() { 302 PersistableBundle config = new PersistableBundle(); 303 config.putInt(CarrierConfigManager.KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT, 1); 304 config.putInt(CarrierConfigManager.KEY_ESIM_MAX_DOWNLOAD_RETRY_ATTEMPTS_INT, 2); 305 config.putString(CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, TEST_SMDP_ADDRESS); 306 doReturn(config).when(mMockCarrierConfigManager).getConfigForSubId(TEST_SUB_ID); 307 doNothing().when(mMockDownloadListener).onDownloadError( 308 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_RETRY_DOWNLOAD, 0); 309 310 Runnable runnable = new Runnable() { 311 @Override 312 public void run() { 313 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mContext, 314 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 315 mMockDownloadListener); 316 317 Intent intent = new Intent(mContext, ONSProfileResultReceiver.class); 318 intent.setAction(ONSProfileDownloader.ACTION_ONS_ESIM_DOWNLOAD); 319 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, ONSProfileDownloader.class.getName()); 320 intent.putExtra(ONSProfileDownloader.PARAM_PRIMARY_SUBID, TEST_SUB_ID); 321 intent.putExtra(ONSProfileDownloader.PARAM_REQUEST_TYPE, 322 ONSProfileDownloader.REQUEST_CODE_DOWNLOAD_SUB); 323 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE, 324 EuiccManager.OPERATION_SIM_SLOT); 325 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE, 326 EuiccManager.ERROR_TIME_OUT); 327 328 onsProfileDownloader.onCallbackIntentReceived(intent, 329 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR); 330 } 331 }; 332 333 WorkerThread workerThread = new WorkerThread(runnable); 334 workerThread.start(); 335 336 //After first download error, next download will be triggered between 1 & 2* 337 //CarrierConfigManager.KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT(1sec for testing) 338 //Should take less than 2 secs for download re-attempt. 339 try { 340 Thread.sleep(3000); 341 } catch (Exception e) { 342 Log.e(TAG, e.getMessage()); 343 } 344 345 String testActCode = DownloadableSubscription.forActivationCode(TEST_SMDP_ADDRESS) 346 .getEncodedActivationCode(); 347 348 verify(mMockDownloadListener).onDownloadError( 349 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_RETRY_DOWNLOAD, 0); 350 351 workerThread.exit(); 352 } 353 354 @Test testDownloadFailureOperationBusy()355 public void testDownloadFailureOperationBusy() { 356 PersistableBundle config = new PersistableBundle(); 357 config.putInt(CarrierConfigManager.KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT, 1); 358 config.putInt(CarrierConfigManager.KEY_ESIM_MAX_DOWNLOAD_RETRY_ATTEMPTS_INT, 2); 359 config.putString(CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, TEST_SMDP_ADDRESS); 360 doReturn(config).when(mMockCarrierConfigManager).getConfigForSubId(TEST_SUB_ID); 361 doNothing().when(mMockDownloadListener).onDownloadError( 362 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_RETRY_DOWNLOAD, 0); 363 364 Runnable runnable = new Runnable() { 365 @Override 366 public void run() { 367 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mContext, 368 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 369 mMockDownloadListener); 370 371 Intent intent = new Intent(mContext, ONSProfileResultReceiver.class); 372 intent.setAction(ONSProfileDownloader.ACTION_ONS_ESIM_DOWNLOAD); 373 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, ONSProfileDownloader.class.getName()); 374 intent.putExtra(ONSProfileDownloader.PARAM_PRIMARY_SUBID, TEST_SUB_ID); 375 intent.putExtra(ONSProfileDownloader.PARAM_REQUEST_TYPE, 376 ONSProfileDownloader.REQUEST_CODE_DOWNLOAD_SUB); 377 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE, 378 EuiccManager.OPERATION_DOWNLOAD); 379 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE, 380 EuiccManager.ERROR_OPERATION_BUSY); 381 382 onsProfileDownloader.onCallbackIntentReceived(intent, 383 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR); 384 } 385 }; 386 387 WorkerThread workerThread = new WorkerThread(runnable); 388 workerThread.start(); 389 390 //After first download error, next download will be triggered between 1 & 2* 391 //CarrierConfigManager.KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT(1sec for testing) 392 //Should take less than 2 secs for download re-attempt. 393 try { 394 Thread.sleep(3000); 395 } catch (Exception e) { 396 Log.e(TAG, e.getMessage()); 397 } 398 399 String testActCode = DownloadableSubscription.forActivationCode(TEST_SMDP_ADDRESS) 400 .getEncodedActivationCode(); 401 402 verify(mMockDownloadListener).onDownloadError( 403 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_RETRY_DOWNLOAD, 0); 404 405 workerThread.exit(); 406 } 407 408 @Test testDownloadFailureInvalidResponse()409 public void testDownloadFailureInvalidResponse() { 410 PersistableBundle config = new PersistableBundle(); 411 config.putInt(CarrierConfigManager.KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT, 1); 412 config.putInt(CarrierConfigManager.KEY_ESIM_MAX_DOWNLOAD_RETRY_ATTEMPTS_INT, 2); 413 config.putString(CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, TEST_SMDP_ADDRESS); 414 doReturn(config).when(mMockCarrierConfigManager).getConfigForSubId(TEST_SUB_ID); 415 doNothing().when(mMockDownloadListener).onDownloadError( 416 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_RETRY_DOWNLOAD, 0); 417 418 Runnable runnable = new Runnable() { 419 @Override 420 public void run() { 421 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mContext, 422 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 423 mMockDownloadListener); 424 425 Intent intent = new Intent(mContext, ONSProfileResultReceiver.class); 426 intent.setAction(ONSProfileDownloader.ACTION_ONS_ESIM_DOWNLOAD); 427 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, ONSProfileDownloader.class.getName()); 428 intent.putExtra(ONSProfileDownloader.PARAM_PRIMARY_SUBID, TEST_SUB_ID); 429 intent.putExtra(ONSProfileDownloader.PARAM_REQUEST_TYPE, 430 ONSProfileDownloader.REQUEST_CODE_DOWNLOAD_SUB); 431 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE, 432 EuiccManager.OPERATION_SMDX); 433 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE, 434 EuiccManager.ERROR_INVALID_RESPONSE); 435 436 onsProfileDownloader.onCallbackIntentReceived(intent, 437 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR); 438 } 439 }; 440 441 WorkerThread workerThread = new WorkerThread(runnable); 442 workerThread.start(); 443 444 try { 445 Thread.sleep(3000); 446 } catch (Exception e) { 447 e.printStackTrace(); 448 } 449 450 verify(mMockDownloadListener).onDownloadError( 451 TEST_SUB_ID, ONSProfileDownloader.DownloadRetryResultCode.ERR_UNRESOLVABLE, 0); 452 workerThread.exit(); 453 } 454 455 @Test testDownloadOpCode()456 public void testDownloadOpCode() { 457 final Object lock = new Object(); 458 459 Runnable runnable = new Runnable() { 460 @Override 461 public void run() { 462 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mMockContext, 463 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 464 mMockDownloadListener); 465 466 ONSProfileDownloader.DownloadHandler downloadHandler = 467 onsProfileDownloader.new DownloadHandler(); 468 469 ONSProfileDownloader.DownloadRetryResultCode res = 470 downloadHandler.mapDownloaderErrorCode( 471 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0, 0, 0); 472 assertEquals( 473 ONSProfileDownloader.DownloadRetryResultCode.DOWNLOAD_SUCCESSFUL, res); 474 475 res = downloadHandler.mapDownloaderErrorCode( 476 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR, 0, 477 EuiccManager.OPERATION_EUICC_GSMA, 478 EuiccManager.ERROR_EUICC_INSUFFICIENT_MEMORY); 479 assertEquals(ONSProfileDownloader.DownloadRetryResultCode 480 .ERR_MEMORY_FULL, res); 481 482 res = downloadHandler.mapDownloaderErrorCode( 483 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR, 0, 484 EuiccManager.OPERATION_SIM_SLOT, 485 EuiccManager.ERROR_TIME_OUT); 486 assertEquals(ONSProfileDownloader.DownloadRetryResultCode 487 .ERR_RETRY_DOWNLOAD, res); 488 489 res = downloadHandler.mapDownloaderErrorCode( 490 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR, 0, 491 EuiccManager.OPERATION_SMDX, 492 EuiccManager.ERROR_CONNECTION_ERROR); 493 assertEquals(ONSProfileDownloader.DownloadRetryResultCode 494 .ERR_RETRY_DOWNLOAD, res); 495 496 res = downloadHandler.mapDownloaderErrorCode( 497 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR, 0, 498 EuiccManager.OPERATION_SMDX, 499 EuiccManager.ERROR_INVALID_RESPONSE); 500 assertEquals(ONSProfileDownloader.DownloadRetryResultCode 501 .ERR_UNRESOLVABLE, res); 502 503 res = downloadHandler.mapDownloaderErrorCode( 504 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR, 0, 505 EuiccManager.OPERATION_SMDX, 506 EuiccManager.ERROR_INVALID_RESPONSE); 507 assertEquals(ONSProfileDownloader.DownloadRetryResultCode 508 .ERR_UNRESOLVABLE, res); 509 510 res = downloadHandler.mapDownloaderErrorCode( 511 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR, 0xA810048, 512 EuiccManager.OPERATION_SMDX_SUBJECT_REASON_CODE, 0); 513 assertEquals(ONSProfileDownloader.DownloadRetryResultCode 514 .ERR_MEMORY_FULL, res); 515 516 synchronized (lock) { 517 lock.notifyAll(); 518 } 519 } 520 }; 521 522 WorkerThread workerThread = new WorkerThread(runnable); 523 workerThread.start(); 524 525 synchronized (lock) { 526 try { 527 lock.wait(); 528 } catch (Exception e) { 529 Log.e(TAG, e.getLocalizedMessage()); 530 } 531 } 532 533 workerThread.exit(); 534 } 535 536 @Test testSMDPErrorParsing()537 public void testSMDPErrorParsing() { 538 final Object lock = new Object(); 539 540 Runnable runnable = new Runnable() { 541 @Override 542 public void run() { 543 Pair<String, String> res = ONSProfileDownloader 544 .decodeSmdxSubjectAndReasonCode(0xA8B1051); 545 //0A->OPERATION_SMDX_SUBJECT_REASON_CODE 546 //8B1 -> 8.11.1 547 //051 -> 5.1 548 assertEquals("8.11.1", res.first); 549 assertEquals("5.1", res.second); 550 551 res = ONSProfileDownloader 552 .decodeSmdxSubjectAndReasonCode(0xA810061); 553 //0A->OPERATION_SMDX_SUBJECT_REASON_CODE 554 //810 -> 8.1.0 555 //061 -> 6.1 556 assertEquals("8.1.0", res.first); 557 assertEquals("6.1", res.second); 558 559 res = ONSProfileDownloader 560 .decodeSmdxSubjectAndReasonCode(0xA810048); 561 //0A->OPERATION_SMDX_SUBJECT_REASON_CODE 562 //810 -> 8.1.0 563 //048 -> 4.8 564 assertEquals("8.1.0", res.first); 565 assertEquals("4.8", res.second); 566 567 res = ONSProfileDownloader 568 .decodeSmdxSubjectAndReasonCode(0xA8B1022); 569 //0A->OPERATION_SMDX_SUBJECT_REASON_CODE 570 //8B1 -> 8.11.1 571 //022 -> 2.2 572 assertEquals("8.11.1", res.first); 573 assertEquals("2.2", res.second); 574 575 synchronized (lock) { 576 lock.notifyAll(); 577 } 578 } 579 }; 580 581 WorkerThread workerThread = new WorkerThread(runnable); 582 workerThread.start(); 583 584 synchronized (lock) { 585 try { 586 lock.wait(); 587 } catch (Exception e) { 588 Log.e(TAG, e.getLocalizedMessage()); 589 } 590 } 591 592 workerThread.exit(); 593 } 594 595 @Test testMultipleDownloadRequests()596 public void testMultipleDownloadRequests() { 597 doReturn(TEST_SUB_ID).when(mMockSubInfo).getSubscriptionId(); 598 PersistableBundle config = new PersistableBundle(); 599 config.putString(CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, TEST_SMDP_ADDRESS); 600 doReturn(config).when(mMockCarrierConfigManager).getConfigForSubId(TEST_SUB_ID); 601 602 ONSProfileDownloader onsProfileDownloader = new ONSProfileDownloader(mContext, 603 mMockCarrierConfigManager, mMockEUICCManager, mMockONSProfileConfig, 604 mMockDownloadListener); 605 606 //When multiple download requests are received, download should be triggered only once. 607 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 608 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 609 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 610 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 611 verify(mMockEUICCManager, times(1)).downloadSubscription(any(), eq(true), any()); 612 613 //Simulate response for download request from LPA. 614 Intent intent = new Intent(mContext, ONSProfileResultReceiver.class); 615 intent.setAction(ONSProfileDownloader.ACTION_ONS_ESIM_DOWNLOAD); 616 intent.putExtra(Intent.EXTRA_COMPONENT_NAME, ONSProfileDownloader.class.getName()); 617 intent.putExtra(ONSProfileDownloader.PARAM_PRIMARY_SUBID, TEST_SUB_ID); 618 intent.putExtra(ONSProfileDownloader.PARAM_REQUEST_TYPE, 619 ONSProfileDownloader.REQUEST_CODE_DOWNLOAD_SUB); 620 intent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE, 621 EuiccManager.OPERATION_DOWNLOAD); 622 623 onsProfileDownloader.onCallbackIntentReceived(intent, 624 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK); 625 626 //Trigger new download after a sec 627 try { 628 Thread.sleep(1000); 629 } catch (Exception e) { 630 e.printStackTrace(); 631 } 632 633 //After download response is received, new download requests should be processed. 634 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 635 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 636 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 637 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 638 verify(mMockEUICCManager, times(1)).downloadSubscription(any(), eq(true), any()); 639 } 640 641 @Test testDownloadRequestFailures()642 public void testDownloadRequestFailures() { 643 doReturn(TEST_SUB_ID).when(mMockSubInfo).getSubscriptionId(); 644 PersistableBundle invalidConfig = new PersistableBundle(); 645 invalidConfig.putString(CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, ""); 646 647 PersistableBundle validConfig = new PersistableBundle(); 648 validConfig.putString( 649 CarrierConfigManager.KEY_SMDP_SERVER_ADDRESS_STRING, TEST_SMDP_ADDRESS); 650 651 // Only the first download request, will receive invalid SMDP server address. 652 doReturn(invalidConfig, validConfig) 653 .when(mMockCarrierConfigManager) 654 .getConfigForSubId(TEST_SUB_ID); 655 656 ONSProfileDownloader onsProfileDownloader = 657 new ONSProfileDownloader( 658 mContext, 659 mMockCarrierConfigManager, 660 mMockEUICCManager, 661 mMockONSProfileConfig, 662 mMockDownloadListener); 663 664 // First download request to be failed with INVALID_SMDP_ADDRESS error because of empty SMDP 665 // server address in configuration. 666 DownloadProfileResult retryResultCode = 667 onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 668 assertEquals(DownloadProfileResult.INVALID_SMDP_ADDRESS, retryResultCode); 669 670 verify(mMockEUICCManager, never()).downloadSubscription(any(), eq(true), any()); 671 672 // Second Download request should be success and processed to EuiccManager. 673 retryResultCode = onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 674 assertEquals(DownloadProfileResult.SUCCESS, retryResultCode); 675 verify(mMockEUICCManager).downloadSubscription(any(), eq(true), any()); 676 677 // Since download request is in progress, no further request to be sent to EuiccManager. 678 // They should return with DUPLICATE_REQUEST error. 679 retryResultCode = onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 680 assertEquals(DownloadProfileResult.DUPLICATE_REQUEST, retryResultCode); 681 682 retryResultCode = onsProfileDownloader.downloadProfile(mMockSubInfo.getSubscriptionId()); 683 assertEquals(DownloadProfileResult.DUPLICATE_REQUEST, retryResultCode); 684 685 verify(mMockEUICCManager).downloadSubscription(any(), eq(true), any()); 686 } 687 688 @After tearDown()689 public void tearDown() throws Exception { 690 super.tearDown(); 691 } 692 } 693