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