1 /* 2 * Copyright (C) 2016 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.internal.telephony.gsm; 18 19 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.fail; 25 import static org.mockito.Matchers.any; 26 import static org.mockito.Matchers.anyBoolean; 27 import static org.mockito.Matchers.anyInt; 28 import static org.mockito.Matchers.anyLong; 29 import static org.mockito.Matchers.eq; 30 import static org.mockito.Matchers.nullable; 31 import static org.mockito.Mockito.atLeastOnce; 32 import static org.mockito.Mockito.doReturn; 33 import static org.mockito.Mockito.never; 34 import static org.mockito.Mockito.spy; 35 import static org.mockito.Mockito.times; 36 import static org.mockito.Mockito.verify; 37 import static org.mockito.Mockito.when; 38 39 import android.app.Notification; 40 import android.app.NotificationManager; 41 import android.content.BroadcastReceiver; 42 import android.content.ContentValues; 43 import android.content.Context; 44 import android.content.Intent; 45 import android.content.IntentFilter; 46 import android.database.Cursor; 47 import android.net.Uri; 48 import android.os.AsyncResult; 49 import android.os.Bundle; 50 import android.os.UserHandle; 51 import android.os.UserManager; 52 import android.provider.Telephony; 53 import android.telephony.SubscriptionManager; 54 import android.test.mock.MockContentResolver; 55 import android.testing.AndroidTestingRunner; 56 import android.testing.TestableLooper; 57 58 import androidx.test.filters.FlakyTest; 59 import androidx.test.filters.MediumTest; 60 61 import com.android.internal.telephony.FakeSmsContentProvider; 62 import com.android.internal.telephony.InboundSmsHandler; 63 import com.android.internal.telephony.InboundSmsTracker; 64 import com.android.internal.telephony.PhoneConstants; 65 import com.android.internal.telephony.SmsBroadcastUndelivered; 66 import com.android.internal.telephony.SmsHeader; 67 import com.android.internal.telephony.SmsStorageMonitor; 68 import com.android.internal.telephony.TelephonyTest; 69 import com.android.internal.telephony.cdma.CdmaInboundSmsHandler; 70 import com.android.internal.util.IState; 71 import com.android.internal.util.StateMachine; 72 73 import org.junit.After; 74 import org.junit.Before; 75 import org.junit.Test; 76 import org.junit.runner.RunWith; 77 import org.mockito.ArgumentCaptor; 78 import org.mockito.Mock; 79 import org.mockito.Mockito; 80 import org.mockito.stubbing.Answer; 81 import org.mockito.verification.VerificationMode; 82 83 import java.lang.reflect.Method; 84 import java.util.ArrayList; 85 import java.util.Collections; 86 import java.util.List; 87 88 @RunWith(AndroidTestingRunner.class) 89 @TestableLooper.RunWithLooper 90 public class GsmInboundSmsHandlerTest extends TelephonyTest { 91 @Mock 92 private SmsStorageMonitor mSmsStorageMonitor; 93 @Mock 94 private android.telephony.SmsMessage mSmsMessage; 95 @Mock 96 private SmsMessage mGsmSmsMessage; 97 @Mock 98 private SmsHeader mSmsHeader; 99 private InboundSmsTracker mInboundSmsTracker; 100 private InboundSmsTracker mInboundSmsTrackerSub1; 101 private InboundSmsTracker mInboundSmsTrackerPart1; 102 private InboundSmsTracker mInboundSmsTrackerPart2; 103 @Mock 104 private CdmaInboundSmsHandler mCdmaInboundSmsHandler; 105 @Mock 106 private InboundSmsHandler.SmsFilter mSmsFilter; 107 @Mock 108 private InboundSmsHandler.SmsFilter mSmsFilter2; 109 private List<InboundSmsHandler.SmsFilter> mSmsFilters; 110 111 private GsmInboundSmsHandler mGsmInboundSmsHandler; 112 113 private FakeSmsContentProvider mContentProvider; 114 private static final String RAW_TABLE_NAME = "raw"; 115 private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, 116 RAW_TABLE_NAME); 117 118 private String mMessageBody = "This is the message body of a single-part message"; 119 private String mMessageBodyPart1 = "This is the first part of a multi-part message"; 120 private String mMessageBodyPart2 = "This is the second part of a multi-part message"; 121 private int mSubId0 = 0; 122 private int mSubId1 = 0; 123 124 byte[] mSmsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF}; 125 getCurrentState()126 private IState getCurrentState() { 127 try { 128 Method method = StateMachine.class.getDeclaredMethod("getCurrentState"); 129 method.setAccessible(true); 130 return (IState) method.invoke(mGsmInboundSmsHandler); 131 } catch (Exception e) { 132 fail(e.toString()); 133 return null; 134 } 135 } 136 137 /** 138 * This is used only for InboundSmsTracker constructed through Cursor. This should be used only 139 * for tests related to SmsBroadcastUndelivered. Also, this adds a second tracker for multisim. 140 */ createInboundSmsTrackerMultiSim()141 private void createInboundSmsTrackerMultiSim() { 142 mInboundSmsTrackerSub1 = new InboundSmsTracker( 143 mContext, 144 mSmsPdu, /* pdu */ 145 System.currentTimeMillis(), /* timestamp */ 146 -1, /* destPort */ 147 false, /* is3gpp2 */ 148 false, /* is3gpp2WapPdu */ 149 "1234567890", /* address */ 150 "1234567890", /* displayAddress */ 151 mMessageBody, /* messageBody */ 152 false, /* isClass0 */ 153 mSubId1, 154 InboundSmsHandler.SOURCE_NOT_INJECTED); 155 156 doReturn(mInboundSmsTracker).doReturn(mInboundSmsTrackerSub1) 157 .when(mTelephonyComponentFactory) 158 .makeInboundSmsTracker(any(Context.class), nullable(Cursor.class), 159 anyBoolean()); 160 } 161 162 @Before setUp()163 public void setUp() throws Exception { 164 super.setUp("GsmInboundSmsHandlerTest"); 165 166 doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean()); 167 doReturn(true).when(mSmsStorageMonitor).isStorageAvailable(); 168 169 UserManager userManager = (UserManager)mContext.getSystemService(Context.USER_SERVICE); 170 doReturn(true).when(userManager).isUserUnlocked(); 171 doReturn(true).when(userManager).isUserRunning(any(UserHandle.class)); 172 173 List<UserHandle> userHandles = new ArrayList(); 174 userHandles.add(UserHandle.SYSTEM); 175 doReturn(userHandles).when(userManager).getUserHandles(anyBoolean()); 176 177 mSmsMessage.mWrappedSmsMessage = mGsmSmsMessage; 178 179 mInboundSmsTracker = new InboundSmsTracker( 180 mContext, 181 mSmsPdu, /* pdu */ 182 System.currentTimeMillis(), /* timestamp */ 183 -1, /* destPort */ 184 false, /* is3gpp2 */ 185 false, /* is3gpp2WapPdu */ 186 "1234567890", /* address */ 187 "1234567890", /* displayAddress */ 188 mMessageBody, /* messageBody */ 189 false, /* isClass0 */ 190 mSubId0, 191 InboundSmsHandler.SOURCE_NOT_INJECTED); 192 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 193 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 194 anyInt(), anyBoolean(), 195 anyBoolean(), nullable(String.class), nullable(String.class), 196 nullable(String.class), anyBoolean(), anyInt(), anyInt()); 197 198 createInboundSmsTrackerMultiSim(); 199 200 mContentProvider = new FakeSmsContentProvider(); 201 ((MockContentResolver)mContext.getContentResolver()).addProvider( 202 Telephony.Sms.CONTENT_URI.getAuthority(), mContentProvider); 203 204 mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(mContext, 205 mSmsStorageMonitor, mPhone); 206 mSmsFilters = new ArrayList<>(); 207 mSmsFilters.add(mSmsFilter); 208 mSmsFilters.add(mSmsFilter2); 209 mGsmInboundSmsHandler.setSmsFiltersForTesting(mSmsFilters); 210 monitorTestableLooper(new TestableLooper(mGsmInboundSmsHandler.getHandler().getLooper())); 211 212 doReturn(mGsmInboundSmsHandler).when(mPhone).getInboundSmsHandler(false); 213 doReturn(mCdmaInboundSmsHandler).when(mPhone).getInboundSmsHandler(true); 214 215 processAllMessages(); 216 logd("setUp: complete"); 217 } 218 219 @After tearDown()220 public void tearDown() throws Exception { 221 // wait for wakelock to be released; timeout at 10s 222 int i = 0; 223 while (mGsmInboundSmsHandler.getWakeLock().isHeld() && i < 100) { 224 waitForMs(100); 225 processAllMessages(); 226 i++; 227 } 228 assertFalse(mGsmInboundSmsHandler.getWakeLock().isHeld()); 229 mGsmInboundSmsHandler.quit(); 230 mGsmInboundSmsHandler = null; 231 mContentProvider.shutdown(); 232 super.tearDown(); 233 } 234 transitionFromStartupToIdle()235 private void transitionFromStartupToIdle() { 236 // verify initially in StartupState 237 assertEquals("StartupState", getCurrentState().getName()); 238 239 // trigger transition to IdleState 240 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_START_ACCEPTING_SMS); 241 processAllMessages(); 242 243 assertEquals("IdleState", getCurrentState().getName()); 244 } 245 verifySmsIntentBroadcasts(int numPastBroadcasts)246 private void verifySmsIntentBroadcasts(int numPastBroadcasts) { 247 verifySmsIntentBroadcasts(numPastBroadcasts, false /* allowBgActivityStarts */); 248 } 249 verifySmsIntentBroadcasts(int numPastBroadcasts, boolean allowBgActivityStarts)250 private void verifySmsIntentBroadcasts(int numPastBroadcasts, boolean allowBgActivityStarts) { 251 verifySmsIntentBroadcasts(numPastBroadcasts, allowBgActivityStarts, mSubId0, 252 false /* moreMessages */); 253 } 254 verifySmsIntentBroadcasts(int numPastBroadcasts, int subId, boolean moreMessages)255 private void verifySmsIntentBroadcasts(int numPastBroadcasts, int subId, boolean moreMessages) { 256 verifySmsIntentBroadcasts(numPastBroadcasts, false /* allowBgActivityStarts */, subId, 257 moreMessages); 258 } 259 verifySmsIntentBroadcasts(int numPastBroadcasts, boolean allowBgActivityStarts, int subId, boolean moreMessages)260 private void verifySmsIntentBroadcasts(int numPastBroadcasts, boolean allowBgActivityStarts, 261 int subId, boolean moreMessages) { 262 ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 263 verify(mContext, times(1 + numPastBroadcasts)).sendBroadcast( 264 intentArgumentCaptor.capture()); 265 Intent intent = intentArgumentCaptor.getAllValues().get(numPastBroadcasts); 266 assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION, intent.getAction()); 267 assertEquals(subId, intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, 268 SubscriptionManager.INVALID_SUBSCRIPTION_ID)); 269 assertEquals(subId, intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 270 SubscriptionManager.INVALID_SUBSCRIPTION_ID)); 271 assertEquals("WaitingState", getCurrentState().getName()); 272 if (allowBgActivityStarts) { 273 Bundle broadcastOptions = mContextFixture.getLastBroadcastOptions(); 274 assertTrue(broadcastOptions 275 .getBoolean("android:broadcast.allowBackgroundActivityStarts")); 276 } 277 278 mContextFixture.sendBroadcastToOrderedBroadcastReceivers(); 279 280 intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 281 verify(mContext, times(2 + numPastBroadcasts)).sendBroadcast( 282 intentArgumentCaptor.capture()); 283 intent = intentArgumentCaptor.getAllValues().get(numPastBroadcasts + 1); 284 assertEquals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION, intent.getAction()); 285 assertEquals(subId, intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, 286 SubscriptionManager.INVALID_SUBSCRIPTION_ID)); 287 assertEquals(subId, intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 288 SubscriptionManager.INVALID_SUBSCRIPTION_ID)); 289 assertEquals("WaitingState", getCurrentState().getName()); 290 291 mContextFixture.sendBroadcastToOrderedBroadcastReceivers(); 292 processAllMessages(); 293 if (!moreMessages) { 294 processAllMessages(); 295 assertEquals("IdleState", getCurrentState().getName()); 296 } 297 } 298 sendNewSms()299 private void sendNewSms() { 300 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, 301 new AsyncResult(null, mSmsMessage, null)); 302 // handle EVENT_NEW_SMS, EVENT_BROADCAST_SMS 303 processAllMessages(); 304 } 305 306 @FlakyTest 307 @Test 308 @MediumTest testNewSms()309 public void testNewSms() { 310 transitionFromStartupToIdle(); 311 312 // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION 313 sendNewSms(); 314 315 verifySmsIntentBroadcasts(0); 316 317 // send same SMS again, verify no broadcasts are sent 318 sendNewSms(); 319 320 verify(mContext, times(2)).sendBroadcast(any(Intent.class)); 321 assertEquals("IdleState", getCurrentState().getName()); 322 323 verifySmsFiltersInvoked(times(1)); 324 } 325 326 @FlakyTest // temporarily disabled, see b/182498318 327 @Test 328 @MediumTest testNewSmsFromBlockedNumber_noBroadcastsSent()329 public void testNewSmsFromBlockedNumber_noBroadcastsSent() { 330 String blockedNumber = "1234567890"; 331 mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber); 332 333 transitionFromStartupToIdle(); 334 335 sendNewSms(); 336 337 verify(mContext, never()).sendBroadcast(any(Intent.class)); 338 assertEquals("IdleState", getCurrentState().getName()); 339 340 // Filter should still be invoked. 341 verifySmsFiltersInvoked(times(1)); 342 } 343 344 @FlakyTest // temporarily disabled, see b/182498318 345 @Test 346 @MediumTest testNewSmsWithUserLocked_notificationShown()347 public void testNewSmsWithUserLocked_notificationShown() { 348 // user locked 349 UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 350 doReturn(false).when(userManager).isUserUnlocked(); 351 352 transitionFromStartupToIdle(); 353 354 sendNewSms(); 355 356 verify(mContext, never()).sendBroadcast(any(Intent.class)); 357 assertEquals("IdleState", getCurrentState().getName()); 358 359 // Filter should be invoked. 360 verifySmsFiltersInvoked(times(1)); 361 362 // New message notification should be shown. 363 NotificationManager notificationManager = 364 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 365 verify(notificationManager).notify( 366 eq(InboundSmsHandler.NOTIFICATION_TAG), 367 eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE), 368 any(Notification.class)); 369 } 370 371 @FlakyTest // temporarily disabled, see b/182498318 372 @Test 373 @MediumTest testNewSmsFromBlockedNumberWithUserLocked_noNotificationShown()374 public void testNewSmsFromBlockedNumberWithUserLocked_noNotificationShown() { 375 String blockedNumber = "1234567890"; 376 mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber); 377 378 // user locked 379 UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 380 doReturn(false).when(userManager).isUserUnlocked(); 381 382 transitionFromStartupToIdle(); 383 384 sendNewSms(); 385 386 verify(mContext, never()).sendBroadcast(any(Intent.class)); 387 assertEquals("IdleState", getCurrentState().getName()); 388 389 // Filter should be invoked. 390 verifySmsFiltersInvoked(times(1)); 391 392 // No new message notification should be shown. 393 NotificationManager notificationManager = 394 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 395 verify(notificationManager, never()).notify( 396 eq(InboundSmsHandler.NOTIFICATION_TAG), 397 eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE), 398 any(Notification.class)); 399 } 400 401 @FlakyTest // temporarily disabled, see b/182498318 402 @Test 403 @MediumTest testNewSms_filterInvoked_noBroadcastsSent()404 public void testNewSms_filterInvoked_noBroadcastsSent() { 405 // Configure the first filter to drop the SMS. 406 when(mSmsFilter.filterSms(any(byte[][].class), anyInt(), 407 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 408 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any())) 409 .thenAnswer((Answer<Boolean>) invocation -> { 410 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_COMPLETE); 411 return true; 412 }); 413 414 transitionFromStartupToIdle(); 415 416 sendNewSms(); 417 418 verify(mContext, never()).sendBroadcast(any(Intent.class)); 419 assertEquals("IdleState", getCurrentState().getName()); 420 421 // verify second filter was never invoked. 422 verify(mSmsFilter2, never()).filterSms(any(byte[][].class), anyInt(), 423 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 424 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any()); 425 } 426 427 @FlakyTest // temporarily disabled, see b/182498318 428 @Test 429 @MediumTest testNewSms_filterChaining_noBroadcastsSent()430 public void testNewSms_filterChaining_noBroadcastsSent() { 431 // Have the first filter indicate it matched without completing the flow. 432 when(mSmsFilter.filterSms(any(byte[][].class), anyInt(), 433 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 434 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any())) 435 .thenReturn(true); 436 437 transitionFromStartupToIdle(); 438 439 sendNewSms(); 440 441 verify(mContext, never()).sendBroadcast(any(Intent.class)); 442 // Now waiting for the first filter to complete. 443 assertEquals("WaitingState", getCurrentState().getName()); 444 445 // Verify the first filter was invoked with the right set of remaining filters. 446 verify(mSmsFilter).filterSms(any(byte[][].class), anyInt(), 447 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 448 anyBoolean(), anyBoolean(), eq(Collections.singletonList(mSmsFilter2))); 449 450 // Verify second filter was never invoked. 451 verify(mSmsFilter2, never()).filterSms(any(byte[][].class), anyInt(), 452 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 453 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any()); 454 455 // Clean up by completing the broadcast, as an asynchronous filter must do. 456 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_COMPLETE); 457 processAllMessages(); 458 assertEquals("IdleState", getCurrentState().getName()); 459 } 460 verifyDataSmsIntentBroadcasts(int numPastBroadcasts)461 private void verifyDataSmsIntentBroadcasts(int numPastBroadcasts) { 462 ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 463 verify(mContext, times(1 + numPastBroadcasts)).sendBroadcast( 464 intentArgumentCaptor.capture()); 465 assertEquals(Telephony.Sms.Intents.DATA_SMS_RECEIVED_ACTION, 466 intentArgumentCaptor.getAllValues().get(numPastBroadcasts).getAction()); 467 // TODO mock messageId correctly in InboundSmsTracker 468 /* assertNotEquals(0L, 469 intentArgumentCaptor.getAllValues().get(numPastBroadcasts) 470 .getLongExtra("messageId", 0L)); */ 471 assertEquals("WaitingState", getCurrentState().getName()); 472 473 mContextFixture.sendBroadcastToOrderedBroadcastReceivers(); 474 processAllMessages(); 475 476 assertEquals("IdleState", getCurrentState().getName()); 477 } 478 479 @FlakyTest // temporarily disabled, see b/182498318 480 @Test 481 @MediumTest testClass0Sms()482 public void testClass0Sms() { 483 transitionFromStartupToIdle(); 484 485 mInboundSmsTracker = new InboundSmsTracker( 486 mContext, 487 mSmsPdu, /* pdu */ 488 System.currentTimeMillis(), /* timestamp */ 489 -1, /* destPort */ 490 false, /* is3gpp2 */ 491 false, /* is3gpp2WapPdu */ 492 "1234567890", /* address */ 493 "1234567890", /* displayAddress */ 494 mMessageBody, /* messageBody */ 495 true, /* isClass0 */ 496 mSubId0, 497 InboundSmsHandler.SOURCE_NOT_INJECTED); 498 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 499 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 500 anyInt(), anyBoolean(), 501 anyBoolean(), nullable(String.class), nullable(String.class), 502 nullable(String.class), anyBoolean(), anyInt(), anyInt()); 503 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_SMS, 504 mInboundSmsTracker); 505 processAllMessages(); 506 507 verifySmsIntentBroadcasts(0, true /* allowBgActivityStarts */); 508 verifySmsFiltersInvoked(times(1)); 509 } 510 511 @FlakyTest // temporarily disabled, see b/182498318 512 @Test 513 @MediumTest testBroadcastSms()514 public void testBroadcastSms() { 515 transitionFromStartupToIdle(); 516 517 mInboundSmsTracker = spy(new InboundSmsTracker( 518 mContext, 519 mSmsPdu, /* pdu */ 520 System.currentTimeMillis(), /* timestamp */ 521 0, /* destPort */ 522 false, /* is3gpp2 */ 523 false, /* is3gpp2WapPdu */ 524 "1234567890", /* address */ 525 "1234567890", /* displayAddress */ 526 mMessageBody, /* messageBody */ 527 false, /* isClass0 */ 528 mSubId0, 529 InboundSmsHandler.SOURCE_NOT_INJECTED)); 530 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 531 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 532 anyInt(), anyBoolean(), 533 anyBoolean(), nullable(String.class), nullable(String.class), 534 nullable(String.class), anyBoolean(), anyInt(), anyInt()); 535 doReturn(2131L).when(mInboundSmsTracker).getMessageId(); 536 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_SMS, 537 mInboundSmsTracker); 538 processAllMessages(); 539 540 verifyDataSmsIntentBroadcasts(0); 541 542 // send same data sms again, and since it's not text sms it should be broadcast again 543 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_SMS, 544 mInboundSmsTracker); 545 processAllMessages(); 546 547 verifyDataSmsIntentBroadcasts(1); 548 549 verifySmsFiltersInvoked(times(2)); 550 } 551 552 @FlakyTest 553 @Test 554 @MediumTest testInjectSms()555 public void testInjectSms() { 556 transitionFromStartupToIdle(); 557 558 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_INJECT_SMS, new AsyncResult(null, 559 mSmsMessage, null)); 560 processAllMessages(); 561 562 verifySmsIntentBroadcasts(0); 563 564 // inject same SMS again, verify no broadcasts are sent 565 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_INJECT_SMS, new AsyncResult(null, 566 mSmsMessage, null)); 567 processAllMessages(); 568 569 verify(mContext, times(2)).sendBroadcast(any(Intent.class)); 570 assertEquals("IdleState", getCurrentState().getName()); 571 572 verifySmsFiltersInvoked(times(1)); 573 } 574 prepareMultiPartSms(boolean is3gpp2WapPush)575 private void prepareMultiPartSms(boolean is3gpp2WapPush) { 576 // Part 1 577 mInboundSmsTrackerPart1 = new InboundSmsTracker( 578 mContext, 579 mSmsPdu, /* pdu */ 580 System.currentTimeMillis(), /* timestamp */ 581 -1, /* destPort */ 582 is3gpp2WapPush, /* is3gpp2 */ 583 "1234567890", /* address */ 584 "1234567890", /* displayAddress */ 585 1, /* referenceNumber */ 586 1, /* sequenceNumber */ 587 2, /* messageCount */ 588 is3gpp2WapPush, /* is3gpp2WapPdu */ 589 mMessageBodyPart1, /* messageBody */ 590 false, /* isClass0 */ 591 mSubId0, 592 InboundSmsHandler.SOURCE_NOT_INJECTED); 593 594 // Part 2 595 mInboundSmsTrackerPart2 = new InboundSmsTracker( 596 mContext, 597 mSmsPdu, /* pdu */ 598 System.currentTimeMillis(), /* timestamp */ 599 -1, /* destPort */ 600 is3gpp2WapPush, /* is3gpp2 */ 601 "1234567890", /* address */ 602 "1234567890", /* displayAddress */ 603 1, /* referenceNumber */ 604 2, /* sequenceNumber */ 605 2, /* messageCount */ 606 is3gpp2WapPush, /* is3gpp2WapPdu */ 607 mMessageBodyPart2, /* messageBody */ 608 false, /* isClass0 */ 609 mSubId0, 610 InboundSmsHandler.SOURCE_NOT_INJECTED); 611 } 612 613 @FlakyTest // temporarily disabled, see b/182498318 614 @Test 615 @MediumTest testMultiPartSmsWithIncompleteWAP()616 public void testMultiPartSmsWithIncompleteWAP() { 617 /** 618 * Test scenario: 3 messages are received with same address, ref number, count. two of the 619 * messages are belonging to the same multi-part SMS and the other one is a 3GPP2WAP. 620 * we should not try to merge 3gpp2wap with the multi-part SMS. 621 */ 622 transitionFromStartupToIdle(); 623 624 // prepare SMS part 1 and part 2 625 prepareMultiPartSms(false); 626 627 mSmsHeader.concatRef = new SmsHeader.ConcatRef(); 628 doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader(); 629 630 // part 2 of non-3gpp2wap arrives first 631 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 632 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 633 anyInt(), anyBoolean(), 634 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 635 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 636 anyInt()); 637 sendNewSms(); 638 639 // State machine should go back to idle and wait for second part 640 assertEquals("IdleState", getCurrentState().getName()); 641 642 // mock a 3gpp2wap push 643 prepareMultiPartSms(true); 644 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 645 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 646 anyInt(), anyBoolean(), 647 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 648 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 649 anyInt()); 650 sendNewSms(); 651 652 // State machine should go back to idle and wait for second part 653 assertEquals("IdleState", getCurrentState().getName()); 654 655 // verify no broadcast sent. 656 verify(mContext, times(0)).sendBroadcast(any(Intent.class)); 657 verifySmsFiltersInvoked(never()); 658 659 // additional copy of part 1 of non-3gpp2wap 660 prepareMultiPartSms(false); 661 doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) 662 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 663 anyInt(), anyBoolean(), 664 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 665 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 666 anyInt()); 667 sendNewSms(); 668 669 // verify broadcast intents 670 verifySmsIntentBroadcasts(0); 671 assertEquals("IdleState", getCurrentState().getName()); 672 // verify there are three segments in the db and only one of them is not marked as deleted. 673 assertEquals(3, mContentProvider.getNumRows()); 674 assertEquals(1, mContentProvider.query(sRawUri, null, "deleted=0", null, null).getCount()); 675 676 verifySmsFiltersInvoked(times(1)); 677 } 678 679 @FlakyTest 680 @Test 681 @MediumTest testMultiPartSms()682 public void testMultiPartSms() { 683 transitionFromStartupToIdle(); 684 685 // prepare SMS part 1 and part 2 686 prepareMultiPartSms(false); 687 688 mSmsHeader.concatRef = new SmsHeader.ConcatRef(); 689 doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader(); 690 691 doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) 692 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 693 anyInt(), anyBoolean(), 694 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 695 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 696 anyInt()); 697 sendNewSms(); 698 699 // State machine should go back to idle and wait for second part 700 assertEquals("IdleState", getCurrentState().getName()); 701 702 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 703 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 704 anyInt(), anyBoolean(), 705 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 706 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 707 anyInt()); 708 sendNewSms(); 709 710 // verify broadcast intents 711 verifySmsIntentBroadcasts(0); 712 verifySmsFiltersInvoked(times(1)); 713 714 // if an additional copy of one of the segments above is received, it should not be kept in 715 // the db and should not be combined with any subsequent messages received from the same 716 // sender 717 718 // additional copy of part 2 of message 719 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 720 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 721 anyInt(), anyBoolean(), 722 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 723 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 724 anyInt()); 725 sendNewSms(); 726 727 // verify no additional broadcasts sent 728 verify(mContext, times(2)).sendBroadcast(any(Intent.class)); 729 verifySmsFiltersInvoked(times(1)); 730 731 // part 1 of new sms recieved from same sender with same parameters, just different 732 // timestamps, should not be combined with the additional part 2 received above 733 734 // call prepareMultiPartSms() to update timestamps 735 prepareMultiPartSms(false); 736 737 // part 1 of new sms 738 doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) 739 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 740 anyInt(), anyBoolean(), 741 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 742 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 743 anyInt()); 744 sendNewSms(); 745 746 // verify no additional broadcasts sent 747 verify(mContext, times(2)).sendBroadcast(any(Intent.class)); 748 verifySmsFiltersInvoked(times(1)); 749 750 assertEquals("IdleState", getCurrentState().getName()); 751 } 752 753 @FlakyTest // temporarily disabled, see b/182498318 754 @Test 755 @MediumTest testMultiPartIncompleteSms()756 public void testMultiPartIncompleteSms() { 757 /** 758 * Test scenario: 2 messages are received with same address, ref number, count, and 759 * seqNumber, with count = 2 and seqNumber = 1. We should not try to merge these. 760 */ 761 transitionFromStartupToIdle(); 762 763 // prepare SMS part 1 and part 2 764 prepareMultiPartSms(false); 765 // change seqNumber in part 2 to 1 766 mInboundSmsTrackerPart2 = new InboundSmsTracker( 767 mContext, 768 mSmsPdu, /* pdu */ 769 System.currentTimeMillis(), /* timestamp */ 770 -1, /* destPort */ 771 false, /* is3gpp2 */ 772 "1234567890", /* address */ 773 "1234567890", /* displayAddress */ 774 1, /* referenceNumber */ 775 1, /* sequenceNumber */ 776 2, /* messageCount */ 777 false, /* is3gpp2WapPdu */ 778 mMessageBodyPart2, /* messageBody */ 779 false, /* isClass0 */ 780 mSubId0, 781 InboundSmsHandler.SOURCE_NOT_INJECTED); 782 783 mSmsHeader.concatRef = new SmsHeader.ConcatRef(); 784 doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader(); 785 786 doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) 787 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 788 anyInt(), anyBoolean(), 789 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 790 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 791 anyInt()); 792 sendNewSms(); 793 794 // State machine should go back to idle and wait for second part 795 assertEquals("IdleState", getCurrentState().getName()); 796 797 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 798 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 799 anyInt(), anyBoolean(), 800 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 801 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 802 anyInt()); 803 sendNewSms(); 804 805 // verify no broadcasts sent 806 verify(mContext, never()).sendBroadcast(any(Intent.class)); 807 // verify there's only 1 of the segments in the db (other should be discarded as dup) 808 assertEquals(1, mContentProvider.getNumRows()); 809 // verify the first one is discarded, and second message is present in the db 810 Cursor c = mContentProvider.query(sRawUri, null, null, null, null); 811 c.moveToFirst(); 812 assertEquals(mMessageBodyPart2, c.getString(c.getColumnIndex("message_body"))); 813 // State machine should go back to idle 814 assertEquals("IdleState", getCurrentState().getName()); 815 verifySmsFiltersInvoked(never()); 816 } 817 818 @FlakyTest // temporarily disabled, see b/182498318 819 @Test 820 @MediumTest testMultiPartSmsWithInvalidSeqNumber()821 public void testMultiPartSmsWithInvalidSeqNumber() { 822 transitionFromStartupToIdle(); 823 824 // prepare SMS part 1 and part 2 825 prepareMultiPartSms(false); 826 827 mSmsHeader.concatRef = new SmsHeader.ConcatRef(); 828 doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader(); 829 830 doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) 831 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 832 anyInt(), anyBoolean(), 833 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 834 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 835 anyInt()); 836 sendNewSms(); 837 838 // verify the message is stored in the raw table 839 assertEquals(1, mContentProvider.getNumRows()); 840 841 // State machine should go back to idle and wait for second part 842 assertEquals("IdleState", getCurrentState().getName()); 843 844 // change seqNumber in part 2 to an invalid value 845 int invalidSeqNumber = -1; 846 mInboundSmsTrackerPart2 = new InboundSmsTracker( 847 mContext, 848 mSmsPdu, /* pdu */ 849 System.currentTimeMillis(), /* timestamp */ 850 -1, /* destPort */ 851 false, /* is3gpp2 */ 852 "1234567890", /* address */ 853 "1234567890", /* displayAddress */ 854 1, /* referenceNumber */ 855 invalidSeqNumber, /* sequenceNumber */ 856 2, /* messageCount */ 857 false, /* is3gpp2WapPdu */ 858 mMessageBodyPart2, /* messageBody */ 859 false, /* isClass0 */ 860 mSubId0, 861 InboundSmsHandler.SOURCE_NOT_INJECTED); 862 863 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 864 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 865 anyInt(), anyBoolean(), 866 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 867 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 868 anyInt()); 869 sendNewSms(); 870 871 // verify no broadcasts sent 872 verify(mContext, never()).sendBroadcast(any(Intent.class)); 873 // State machine should go back to idle 874 assertEquals("IdleState", getCurrentState().getName()); 875 verifySmsFiltersInvoked(never()); 876 } 877 878 @FlakyTest // temporarily disabled, see b/182498318 879 @Test 880 @MediumTest testMultipartSmsFromBlockedNumber_noBroadcastsSent()881 public void testMultipartSmsFromBlockedNumber_noBroadcastsSent() { 882 mFakeBlockedNumberContentProvider.mBlockedNumbers.add("1234567890"); 883 884 transitionFromStartupToIdle(); 885 886 // prepare SMS part 1 and part 2 887 prepareMultiPartSms(false); 888 889 mSmsHeader.concatRef = new SmsHeader.ConcatRef(); 890 doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader(); 891 doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) 892 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 893 anyInt(), anyBoolean(), 894 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 895 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 896 anyInt()); 897 898 sendNewSms(); 899 900 // State machine should go back to idle and wait for second part 901 assertEquals("IdleState", getCurrentState().getName()); 902 903 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 904 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 905 anyInt(), anyBoolean(), 906 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 907 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 908 anyInt()); 909 sendNewSms(); 910 911 verify(mContext, never()).sendBroadcast(any(Intent.class)); 912 assertEquals("IdleState", getCurrentState().getName()); 913 // Filter should still be invoked. 914 verifySmsFiltersInvoked(times(1)); 915 } 916 917 @FlakyTest // temporarily disabled, see b/182498318 918 @Test 919 @MediumTest testMultipartSmsFromBlockedEmail_noBroadcastsSent()920 public void testMultipartSmsFromBlockedEmail_noBroadcastsSent() { 921 mFakeBlockedNumberContentProvider.mBlockedNumbers.add("1234567890@test.com"); 922 923 transitionFromStartupToIdle(); 924 925 // prepare SMS part 1 and part 2 926 prepareMultiPartSms(false); 927 // only the first SMS is configured with the display originating email address 928 mInboundSmsTrackerPart1 = new InboundSmsTracker( 929 mContext, 930 mSmsPdu, /* pdu */ 931 System.currentTimeMillis(), /* timestamp */ 932 -1, /* destPort */ 933 false, /* is3gpp2 */ 934 "1234567890", /* address */ 935 "1234567890@test.com", /* displayAddress */ 936 1, /* referenceNumber */ 937 1, /* sequenceNumber */ 938 2, /* messageCount */ 939 false, /* is3gpp2WapPdu */ 940 mMessageBodyPart1, /* messageBody */ 941 false, /* isClass0 */ 942 mSubId0, 943 InboundSmsHandler.SOURCE_NOT_INJECTED); 944 945 mSmsHeader.concatRef = new SmsHeader.ConcatRef(); 946 doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader(); 947 doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) 948 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 949 anyInt(), anyBoolean(), 950 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 951 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 952 anyInt()); 953 954 sendNewSms(); 955 956 // State machine should go back to idle and wait for second part 957 assertEquals("IdleState", getCurrentState().getName()); 958 959 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 960 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 961 anyInt(), anyBoolean(), 962 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 963 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 964 anyInt()); 965 sendNewSms(); 966 967 verify(mContext, never()).sendBroadcast(any(Intent.class)); 968 assertEquals("IdleState", getCurrentState().getName()); 969 // Filter should still be invoked. 970 verifySmsFiltersInvoked(times(1)); 971 } 972 973 @FlakyTest // temporarily disabled, see b/182498318 974 @Test 975 @MediumTest testMultipartSms_filterInvoked_noBroadcastsSent()976 public void testMultipartSms_filterInvoked_noBroadcastsSent() { 977 // Configure the first filter to drop the SMS. 978 when(mSmsFilter.filterSms(any(byte[][].class), anyInt(), 979 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 980 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any())) 981 .thenAnswer((Answer<Boolean>) invocation -> { 982 mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_COMPLETE); 983 return true; 984 }); 985 986 transitionFromStartupToIdle(); 987 988 // prepare SMS part 1 and part 2 989 prepareMultiPartSms(false); 990 991 mSmsHeader.concatRef = new SmsHeader.ConcatRef(); 992 doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader(); 993 994 doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) 995 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 996 anyInt(), anyBoolean(), 997 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 998 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 999 anyInt()); 1000 sendNewSms(); 1001 1002 // State machine should go back to idle and wait for second part 1003 assertEquals("IdleState", getCurrentState().getName()); 1004 1005 doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) 1006 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 1007 anyInt(), anyBoolean(), 1008 nullable(String.class), nullable(String.class), anyInt(), anyInt(), 1009 anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt(), 1010 anyInt()); 1011 sendNewSms(); 1012 1013 // verify no broadcasts sent 1014 verify(mContext, never()).sendBroadcast(any(Intent.class)); 1015 assertEquals("IdleState", getCurrentState().getName()); 1016 1017 // verify second filter was never invoked. 1018 verify(mSmsFilter2, never()).filterSms(any(byte[][].class), anyInt(), 1019 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 1020 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any()); 1021 } 1022 1023 @FlakyTest // temporarily disabled, see b/182498318 1024 @Test 1025 @MediumTest testBroadcastUndeliveredUserLocked()1026 public void testBroadcastUndeliveredUserLocked() throws Exception { 1027 replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null); 1028 1029 mInboundSmsTracker = new InboundSmsTracker( 1030 mContext, 1031 mSmsPdu, /* pdu */ 1032 System.currentTimeMillis(), /* timestamp */ 1033 0, /* destPort */ 1034 false, /* is3gpp2 */ 1035 false, /* is3gpp2WapPdu */ 1036 "1234567890", /* address */ 1037 "1234567890", /* displayAddress */ 1038 mMessageBody, /* messageBody */ 1039 false, /* isClass0 */ 1040 mSubId0, 1041 InboundSmsHandler.SOURCE_NOT_INJECTED); 1042 1043 doReturn(mInboundSmsTracker) 1044 .when(mTelephonyComponentFactory) 1045 .makeInboundSmsTracker(any(Context.class), nullable(Cursor.class), 1046 anyBoolean()); 1047 1048 // add a fake entry to db 1049 mContentProvider.insert(sRawUri, mInboundSmsTracker.getContentValues()); 1050 1051 // user locked 1052 UserManager userManager = (UserManager)mContext.getSystemService(Context.USER_SERVICE); 1053 doReturn(false).when(userManager).isUserUnlocked(); 1054 1055 SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler); 1056 1057 // verify that a broadcast receiver is registered for current user (user == null) based on 1058 // implementation in ContextFixture. registerReceiver may be called more than once (for 1059 // example by GsmInboundSmsHandler if TEST_MODE is true) 1060 verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class), 1061 any(IntentFilter.class)); 1062 1063 // wait for ScanRawTableThread 1064 waitForMs(100); 1065 processAllMessages(); 1066 1067 // verify no broadcasts sent because due to !isUserUnlocked 1068 verify(mContext, never()).sendBroadcast(any(Intent.class)); 1069 1070 // when user unlocks the device, the message in db should be broadcast 1071 doReturn(true).when(userManager).isUserUnlocked(); 1072 mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED)); 1073 // wait for ScanRawTableThread 1074 waitForMs(100); 1075 processAllMessages(); 1076 1077 verifyDataSmsIntentBroadcasts(1); 1078 verifySmsFiltersInvoked(times(1)); 1079 } 1080 1081 @FlakyTest // temporarily disabled, see b/182498318 1082 @Test 1083 @MediumTest testBroadcastUndeliveredUserUnlocked()1084 public void testBroadcastUndeliveredUserUnlocked() throws Exception { 1085 replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null); 1086 mInboundSmsTracker = new InboundSmsTracker( 1087 mContext, 1088 mSmsPdu, /* pdu */ 1089 System.currentTimeMillis(), /* timestamp */ 1090 0, /* destPort */ 1091 false, /* is3gpp2 */ 1092 false, /* is3gpp2WapPdu */ 1093 "1234567890", /* address */ 1094 "1234567890", /* displayAddress */ 1095 mMessageBody, /* messageBody */ 1096 false, /* isClass0 */ 1097 mSubId0, 1098 InboundSmsHandler.SOURCE_NOT_INJECTED); 1099 1100 doReturn(mInboundSmsTracker) 1101 .when(mTelephonyComponentFactory) 1102 .makeInboundSmsTracker(any(Context.class), nullable(Cursor.class), 1103 anyBoolean()); 1104 1105 // add a fake entry to db 1106 mContentProvider.insert(sRawUri, mInboundSmsTracker.getContentValues()); 1107 1108 SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler); 1109 1110 // wait for ScanRawTableThread 1111 waitForMs(100); 1112 processAllMessages(); 1113 1114 // user is unlocked; intent should be broadcast right away 1115 verifyDataSmsIntentBroadcasts(0); 1116 verifySmsFiltersInvoked(times(1)); 1117 } 1118 1119 @FlakyTest // temporarily disabled, see b/182498318 1120 @Test 1121 @MediumTest testBroadcastUndeliveredDeleted()1122 public void testBroadcastUndeliveredDeleted() throws Exception { 1123 replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null); 1124 SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler); 1125 mInboundSmsTracker = new InboundSmsTracker( 1126 mContext, 1127 mSmsPdu, /* pdu */ 1128 System.currentTimeMillis(), /* timestamp */ 1129 0, /* destPort */ 1130 false, /* is3gpp2 */ 1131 false, /* is3gpp2WapPdu */ 1132 "1234567890", /* address */ 1133 "1234567890", /* displayAddress */ 1134 mMessageBody, /* messageBody */ 1135 false, /* isClass0 */ 1136 mSubId0, 1137 InboundSmsHandler.SOURCE_NOT_INJECTED); 1138 doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory) 1139 .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(), 1140 anyInt(), anyBoolean(), 1141 anyBoolean(), nullable(String.class), nullable(String.class), 1142 nullable(String.class), anyBoolean(), anyInt(), anyInt()); 1143 1144 //add a fake entry to db 1145 ContentValues rawSms = new ContentValues(); 1146 rawSms.put("deleted", 1); 1147 mContentProvider.insert(sRawUri, rawSms); 1148 1149 //when user unlocks the device, broadcast should not be sent for new message 1150 mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED)); 1151 // wait for ScanRawTableThread 1152 waitForMs(100); 1153 processAllMessages(); 1154 1155 verify(mContext, times(1)).sendBroadcast(any(Intent.class)); 1156 assertEquals("IdleState", getCurrentState().getName()); 1157 verifySmsFiltersInvoked(never()); 1158 } 1159 1160 @FlakyTest 1161 @Test 1162 @MediumTest testBroadcastUndeliveredMultiPart()1163 public void testBroadcastUndeliveredMultiPart() throws Exception { 1164 replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null); 1165 1166 // prepare SMS part 1 and part 2 1167 prepareMultiPartSms(false); 1168 1169 //add the 2 SMS parts to db 1170 mContentProvider.insert(sRawUri, mInboundSmsTrackerPart1.getContentValues()); 1171 mContentProvider.insert(sRawUri, mInboundSmsTrackerPart2.getContentValues()); 1172 1173 //return InboundSmsTracker objects corresponding to the 2 parts 1174 doReturn(mInboundSmsTrackerPart1).doReturn(mInboundSmsTrackerPart2). 1175 when(mTelephonyComponentFactory).makeInboundSmsTracker(any(Context.class), 1176 any(Cursor.class), anyBoolean()); 1177 1178 SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler); 1179 // wait for ScanRawTableThread 1180 waitForMs(100); 1181 processAllMessages(); 1182 1183 verifySmsIntentBroadcasts(0); 1184 verifySmsFiltersInvoked(times(1)); 1185 } 1186 1187 @FlakyTest // temporarily disabled, see b/182498318 1188 @Test 1189 @MediumTest testBroadcastUndeliveredMultiSim()1190 public void testBroadcastUndeliveredMultiSim() throws Exception { 1191 replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null); 1192 1193 // add SMSs from different subs to db 1194 mContentProvider.insert(sRawUri, mInboundSmsTracker.getContentValues()); 1195 mContentProvider.insert(sRawUri, mInboundSmsTrackerSub1.getContentValues()); 1196 1197 SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler); 1198 // wait for ScanRawTableThread 1199 waitForMs(100); 1200 processAllMessages(); 1201 1202 verifySmsIntentBroadcasts(0, mSubId0, true); 1203 verifySmsIntentBroadcasts(2, mSubId1, false); 1204 verifySmsFiltersInvoked(times(2)); 1205 } 1206 verifySmsFiltersInvoked(VerificationMode verificationMode)1207 private void verifySmsFiltersInvoked(VerificationMode verificationMode) { 1208 verify(mSmsFilter, verificationMode).filterSms(any(byte[][].class), anyInt(), 1209 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 1210 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any()); 1211 verify(mSmsFilter2, verificationMode).filterSms(any(byte[][].class), anyInt(), 1212 any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class), 1213 anyBoolean(), anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any()); 1214 } 1215 1216 @Test 1217 @MediumTest testBroadcastTimeout()1218 public void testBroadcastTimeout() { 1219 InboundSmsHandler.sTimeoutDurationMillis = 100; 1220 transitionFromStartupToIdle(); 1221 1222 // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION 1223 sendNewSms(); 1224 1225 ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 1226 verify(mContext).sendBroadcast(intentArgumentCaptor.capture()); 1227 Intent intent = intentArgumentCaptor.getAllValues().get(0); 1228 assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION, intent.getAction()); 1229 assertEquals("WaitingState", getCurrentState().getName()); 1230 1231 // don't send broadcast back to InboundSmsHandler, instead wait for timeout 1232 waitForMs(300); 1233 processAllMessages(); 1234 1235 intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 1236 verify(mContext, times(2)).sendBroadcast(intentArgumentCaptor.capture()); 1237 intent = intentArgumentCaptor.getAllValues().get(1); 1238 assertEquals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION, intent.getAction()); 1239 1240 // don't send broadcast back to InboundSmsHandler, instead wait for timeout 1241 waitForMs(300); 1242 processAllMessages(); 1243 1244 assertEquals("IdleState", getCurrentState().getName()); 1245 1246 } 1247 } 1248