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