Add null check to avoid exception.

Code was already added for b/28614514; moving it to check a little
earlier. Also adding another null pointer check.

This takes care of b/28842442 too.

Bug: 28883656
Change-Id: Ib8e29a7cc18bffa45a361c27a640fef791d6cafa
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index efc907c..8aed4e8 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -780,6 +780,14 @@
             }
         }
 
+        // Do not process null pdu(s). Check for that and return false in that case.
+        List<byte[]> pduList = Arrays.asList(pdus);
+        if (pduList.size() == 0 || pduList.contains(null)) {
+            loge("processMessagePart: returning false due to " +
+                    (pduList.size() == 0 ? "pduList.size() == 0" : "pduList.contains(null)"));
+            return false;
+        }
+
         if (!mUserManager.isUserUnlocked()) {
             return processMessagePartWithUserLocked(tracker, pdus, destPort);
         }
@@ -793,7 +801,12 @@
                 // 3GPP needs to extract the User Data from the PDU; 3GPP2 has already done this
                 if (!tracker.is3gpp2()) {
                     SmsMessage msg = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP);
-                    pdu = msg.getUserData();
+                    if (msg != null) {
+                        pdu = msg.getUserData();
+                    } else {
+                        loge("processMessagePart: SmsMessage.createFromPdu returned null");
+                        return false;
+                    }
                 }
                 output.write(pdu, 0, pdu.length);
             }
@@ -894,15 +907,6 @@
      */
     private boolean filterSms(byte[][] pdus, int destPort,
         InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked) {
-        // Do not send null pdu(s) to CarrierSmsFilter. Check for that and return false in that case
-        List<byte[]> pduList = Arrays.asList(pdus);
-        if (pduList == null || pduList.size() == 0 || pduList.contains(null)) {
-            loge("filterSmsWithCarrierOrSystemApp: Bypassing carrier/system sms filter due to " +
-                    (pduList == null ? "pduList == null" : (pduList.size() == 0 ?
-                            "pduList.size() == 0" : "pduList.contains(null)")));
-            return false;
-        }
-
         List<String> carrierPackages = null;
         UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
         if (card != null) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index f65eeac..82a5976 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -596,6 +596,46 @@
 
     @Test
     @MediumTest
+    public void testMultiPartIncompleteSms() {
+        /**
+         * Test scenario: 2 messages are received with same address, ref number, count, and
+         * seqNumber, with count = 2 and seqNumber = 1. We should not try to merge these.
+         */
+        transitionFromStartupToIdle();
+
+        // prepare SMS part 1 and part 2
+        prepareMultiPartSms();
+        // change seqNumber in part 2 to 1
+        mInboundSmsTrackerCVPart2.put("sequence", 1);
+
+        mSmsHeader.concatRef = new SmsHeader.ConcatRef();
+        doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader();
+
+        doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
+                .makeInboundSmsTracker(any(byte[].class), anyLong(), anyInt(), anyBoolean(),
+                        anyString(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyString());
+        mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
+                mSmsMessage, null));
+        waitForMs(100);
+
+        // State machine should go back to idle and wait for second part
+        assertEquals("IdleState", getCurrentState().getName());
+
+        doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
+                .makeInboundSmsTracker(any(byte[].class), anyLong(), anyInt(), anyBoolean(),
+                        anyString(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyString());
+        mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
+                mSmsMessage, null));
+        waitForMs(100);
+
+        // verify no broadcasts sent
+        verify(mContext, never()).sendBroadcast(any(Intent.class));
+        // State machine should go back to idle
+        assertEquals("IdleState", getCurrentState().getName());
+    }
+
+    @Test
+    @MediumTest
     public void testMultipartSmsFromBlockedNumber_noBroadcastsSent() {
         mFakeBlockedNumberContentProvider.mBlockedNumbers.add("1234567890");