Loading src/java/com/android/internal/telephony/InboundSmsHandler.java +49 −51 Original line number Diff line number Diff line Loading @@ -125,8 +125,7 @@ public abstract class InboundSmsHandler extends StateMachine { public static final int ID_COLUMN = 7; public static final String SELECT_BY_ID = "_id=?"; public static final String SELECT_BY_REFERENCE = "address=? AND reference_number=? AND " + "count=? AND deleted=0"; public static final String SELECT_BY_REFERENCE = "address=? AND reference_number=? AND count=?"; /** New SMS received as an AsyncResult. */ public static final int EVENT_NEW_SMS = 1; Loading Loading @@ -162,8 +161,6 @@ public abstract class InboundSmsHandler extends StateMachine { /** URI for raw table of SMS provider. */ private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); private static final Uri sRawUriPermanentDelete = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete"); protected final Context mContext; private final ContentResolver mResolver; Loading Loading @@ -793,13 +790,13 @@ public abstract class InboundSmsHandler extends StateMachine { if (result == Activity.RESULT_OK) { return true; } else { deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), false); deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs()); return false; } } if (BlockChecker.isBlocked(mContext, tracker.getAddress())) { deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), true); deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs()); return false; } Loading Loading @@ -986,10 +983,8 @@ public abstract class InboundSmsHandler extends StateMachine { /** * Helper for {@link SmsBroadcastUndelivered} to delete an old message in the raw table. */ private void deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs, boolean permanentDelete) { Uri uri = permanentDelete ? sRawUriPermanentDelete : sRawUri; int rows = mResolver.delete(uri, deleteWhere, deleteWhereArgs); private void deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs) { int rows = mResolver.delete(sRawUri, deleteWhere, deleteWhereArgs); if (rows == 0) { loge("No rows were deleted from raw table!"); } else if (DBG) { Loading Loading @@ -1079,6 +1074,7 @@ public abstract class InboundSmsHandler extends StateMachine { * @return true on success; false on failure to write to database */ private int addTrackerToRawTable(InboundSmsTracker tracker) { if (tracker.getMessageCount() != 1) { // check for duplicate message segments Cursor cursor = null; try { Loading @@ -1089,8 +1085,8 @@ public abstract class InboundSmsHandler extends StateMachine { String address = tracker.getAddress(); String refNumber = Integer.toString(tracker.getReferenceNumber()); String count = Integer.toString(tracker.getMessageCount()); String seqNumber = Integer.toString(sequence); String date = Long.toString(tracker.getTimestamp()); // set the delete selection args for multi-part message String[] deleteWhereArgs = {address, refNumber, count}; Loading @@ -1098,8 +1094,8 @@ public abstract class InboundSmsHandler extends StateMachine { // Check for duplicate message segments cursor = mResolver.query(sRawUri, PDU_PROJECTION, "address=? AND reference_number=? AND count=? AND sequence=? AND date=?", new String[] {address, refNumber, count, seqNumber, date}, null); "address=? AND reference_number=? AND count=? AND sequence=?", new String[] {address, refNumber, count, seqNumber}, null); // moveToNext() returns false if no duplicates were found if (cursor.moveToNext()) { Loading @@ -1114,6 +1110,7 @@ public abstract class InboundSmsHandler extends StateMachine { } return Intents.RESULT_SMS_DUPLICATED; // reject message } cursor.close(); } catch (SQLException e) { loge("Can't access multipart SMS database", e); return Intents.RESULT_SMS_GENERIC_ERROR; // reject message Loading @@ -1122,6 +1119,7 @@ public abstract class InboundSmsHandler extends StateMachine { cursor.close(); } } } ContentValues values = tracker.getContentValues(); Loading Loading @@ -1214,7 +1212,7 @@ public abstract class InboundSmsHandler extends StateMachine { log("successful broadcast, deleting from raw table."); } deleteFromRawTable(mDeleteWhere, mDeleteWhereArgs, false); deleteFromRawTable(mDeleteWhere, mDeleteWhereArgs); sendMessage(EVENT_BROADCAST_COMPLETE); int durationMillis = (int) ((System.nanoTime() - mBroadcastTimeNano) / 1000000); Loading Loading @@ -1320,7 +1318,7 @@ public abstract class InboundSmsHandler extends StateMachine { try { // Needs phone package permissions. deleteFromRawTable(mSmsFilter.mSmsBroadcastReceiver.mDeleteWhere, mSmsFilter.mSmsBroadcastReceiver.mDeleteWhereArgs, false); mSmsFilter.mSmsBroadcastReceiver.mDeleteWhereArgs); } finally { Binder.restoreCallingIdentity(token); } Loading src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java +3 −8 Original line number Diff line number Diff line Loading @@ -65,8 +65,6 @@ public class SmsBroadcastUndelivered { /** URI for raw table from SmsProvider. */ private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); private static final Uri sRawUriPermanentDelete = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete"); private static SmsBroadcastUndelivered instance; /** Content resolver to use to access raw table from SmsProvider. */ Loading Loading @@ -137,9 +135,7 @@ public class SmsBroadcastUndelivered { HashSet<SmsReferenceKey> oldMultiPartMessages = new HashSet<SmsReferenceKey>(4); Cursor cursor = null; try { // query only non-deleted ones cursor = mResolver.query(sRawUri, PDU_PENDING_MESSAGE_PROJECTION, "deleted = 0", null, null); cursor = mResolver.query(sRawUri, PDU_PENDING_MESSAGE_PROJECTION, null, null, null); if (cursor == null) { Rlog.e(TAG, "error getting pending message cursor"); return; Loading Loading @@ -186,9 +182,8 @@ public class SmsBroadcastUndelivered { } // Delete old incomplete message segments for (SmsReferenceKey message : oldMultiPartMessages) { // delete permanently int rows = mResolver.delete(sRawUriPermanentDelete, InboundSmsHandler.SELECT_BY_REFERENCE, message.getDeleteWhereArgs()); int rows = mResolver.delete(sRawUri, InboundSmsHandler.SELECT_BY_REFERENCE, message.getDeleteWhereArgs()); if (rows == 0) { Rlog.e(TAG, "No rows were deleted from raw table!"); } else if (DBG) { Loading src/java/com/android/internal/telephony/SmsMessageBase.java +1 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ public abstract class SmsMessageBase { /** {@hide} */ protected boolean mIsEmail; /** {@hide} Time when SC (service centre) received the message */ /** {@hide} */ protected long mScTimeMillis; /** {@hide} The raw PDU of the message */ Loading tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java +37 −161 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ import org.mockito.Mock; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class GsmInboundSmsHandlerTest extends TelephonyTest { @Mock Loading @@ -78,9 +77,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { private FakeSmsContentProvider mContentProvider; private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); private static final Uri sRawUriPermanentDelete = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete"); private ContentValues mInboundSmsTrackerCV = new ContentValues(); // For multi-part SMS private ContentValues mInboundSmsTrackerCVPart1; Loading @@ -97,56 +93,13 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { "destination_port", "address", "sub_id", "pdu", "deleted"}; private List<ArrayList<Object>> mListOfRows = new ArrayList<ArrayList<Object>>(); "pdu"}; private MatrixCursor mRawCursor = new MatrixCursor(mRawColumns); private int mNumRows = 0; private int getColumnIndex(String columnName) { int i = 0; for (String s : mRawColumns) { if (s.equals(columnName)) { break; } i++; } return i; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count = 0; if (mNumRows > 0) { // parse selection and selectionArgs SelectionParams selectionParams = new SelectionParams(); selectionParams.parseSelectionParams(selection, selectionArgs); List<Integer> deleteRows = new ArrayList<Integer>(); int i = -1; for (ArrayList<Object> row : mListOfRows) { i++; // filter based on selection parameters if needed if (selection != null) { if (!selectionParams.isMatch(row)) { continue; } } if (uri.compareTo(sRawUri) == 0) { row.set(getColumnIndex("deleted"), "1"); } else { // save index for removal deleteRows.add(i); } count++; } if (uri.compareTo(sRawUriPermanentDelete) == 0) { for (i = deleteRows.size() - 1; i >= 0; i--) { mListOfRows.remove(i); } } } return count; return 0; } @Override Loading @@ -154,7 +107,7 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { Uri newUri = null; if (uri.compareTo(sRawUri) == 0) { if (values != null) { mListOfRows.add(convertRawCVtoArrayList(values)); mRawCursor.addRow(convertRawCVtoArrayList(values)); mNumRows++; newUri = Uri.withAppendedPath(uri, "" + mNumRows); } Loading @@ -167,11 +120,9 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { ArrayList<Object> newRow = new ArrayList<>(); for (String key : mRawColumns) { if (values.containsKey(key)) { newRow.add(values.getAsString(key)); newRow.add(values.get(key)); } else if (key.equals("_id")) { newRow.add(mNumRows + 1); } else if (key.equals("deleted")) { newRow.add("0"); } else { newRow.add(null); } Loading @@ -179,11 +130,15 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { return newRow; } private class SelectionParams { @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { logd("query called for: " + selection); MatrixCursor cursor = new MatrixCursor(projection); if (mNumRows > 0) { // parse selection and selectionArgs String[] paramName = null; String[] paramValue = null; private void parseSelectionParams(String selection, String[] selectionArgs) { if (selection != null) { selection = selection.toLowerCase(); String[] selectionParams = selection.toLowerCase().split("and"); Loading @@ -202,52 +157,38 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { } } } } private boolean isMatch(ArrayList<Object> row) { mRawCursor.moveToFirst(); do { ArrayList<Object> row = new ArrayList<>(); // filter based on selection parameters if needed if (selection != null) { boolean match = true; for (int i = 0; i < paramName.length; i++) { int columnIndex = 0; for (String columnName : mRawColumns) { if (columnName.equals(paramName[i])) { if (!paramValue[i].equals(row.get(columnIndex))) { return false; } else { // move on to next param int columnIndex = mRawCursor.getColumnIndex(columnName); if (columnName.equals(paramName[i]) && !mRawCursor.getString(columnIndex).equals(paramValue[i])) { match = false; break; } } columnIndex++; } } return true; if (!match) { break; } } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { logd("query called for: " + selection); MatrixCursor cursor = new MatrixCursor(projection); if (mNumRows > 0) { // parse selection and selectionArgs SelectionParams selectionParams = new SelectionParams(); selectionParams.parseSelectionParams(selection, selectionArgs); for (ArrayList<Object> row : mListOfRows) { ArrayList<Object> retRow = new ArrayList<>(); // filter based on selection parameters if needed if (selection != null) { if (!selectionParams.isMatch(row)) { // move on to next row if current one does not satisfy selection criteria if (!match) { continue; } } for (String columnName : projection) { int columnIndex = getColumnIndex(columnName); retRow.add(row.get(columnIndex)); } cursor.addRow(retRow); int columnIndex = mRawCursor.getColumnIndex(columnName); row.add(mRawCursor.getString(columnIndex)); } cursor.addRow(row); } while(mRawCursor.moveToNext()); } if (cursor != null) { logd("returning rows: " + cursor.getCount()); Loading Loading @@ -442,7 +383,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { mInboundSmsTrackerCVPart1.put("reference_number", 1); mInboundSmsTrackerCVPart1.put("sequence", 1); mInboundSmsTrackerCVPart1.put("count", 2); mInboundSmsTrackerCVPart1.put("date", System.currentTimeMillis()); doReturn(2).when(mInboundSmsTrackerPart1).getMessageCount(); doReturn(1).when(mInboundSmsTrackerPart1).getReferenceNumber(); Loading @@ -451,8 +391,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { doReturn(1).when(mInboundSmsTrackerPart1).getIndexOffset(); doReturn(-1).when(mInboundSmsTrackerPart1).getDestPort(); doReturn(mSmsPdu).when(mInboundSmsTrackerPart1).getPdu(); doReturn(mInboundSmsTrackerCVPart1.get("date")).when(mInboundSmsTrackerPart1). getTimestamp(); doReturn(mInboundSmsTrackerCVPart1).when(mInboundSmsTrackerPart1).getContentValues(); // Part 2 Loading @@ -463,7 +401,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { mInboundSmsTrackerCVPart2.put("reference_number", 1); mInboundSmsTrackerCVPart2.put("sequence", 2); mInboundSmsTrackerCVPart2.put("count", 2); mInboundSmsTrackerCVPart2.put("date", System.currentTimeMillis()); doReturn(2).when(mInboundSmsTrackerPart2).getMessageCount(); doReturn(1).when(mInboundSmsTrackerPart2).getReferenceNumber(); Loading @@ -472,8 +409,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { doReturn(1).when(mInboundSmsTrackerPart2).getIndexOffset(); doReturn(-1).when(mInboundSmsTrackerPart2).getDestPort(); doReturn(mSmsPdu).when(mInboundSmsTrackerPart2).getPdu(); doReturn(mInboundSmsTrackerCVPart2.get("date")).when(mInboundSmsTrackerPart2). getTimestamp(); doReturn(mInboundSmsTrackerCVPart2).when(mInboundSmsTrackerPart2).getContentValues(); } Loading @@ -487,10 +422,10 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { 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()); mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null, mSmsMessage, null)); waitForMs(100); Loading @@ -505,42 +440,7 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { mSmsMessage, null)); waitForMs(100); // verify broadcast intents verifySmsIntentBroadcasts(0); // if an additional copy of one of the segments above is received, it should not be kept in // the db and should not be combined with any subsequent messages received from the same // sender // additional copy of part 2 of message doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) .makeInboundSmsTracker(any(byte[].class), anyLong(), anyInt(), anyBoolean(), anyString(), anyInt(), anyInt(), anyInt(), anyBoolean()); mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null, mSmsMessage, null)); waitForMs(100); // verify no additional broadcasts sent verify(mContext, times(2)).sendBroadcast(any(Intent.class)); // part 1 of new sms recieved from same sender with same parameters, just different // timestamps, should not be combined with the additional part 2 received above // call prepareMultiPartSms() to update timestamps prepareMultiPartSms(); // part 1 of new sms doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) .makeInboundSmsTracker(any(byte[].class), anyLong(), anyInt(), anyBoolean(), anyString(), anyInt(), anyInt(), anyInt(), anyBoolean()); mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null, mSmsMessage, null)); waitForMs(100); // verify no additional broadcasts sent verify(mContext, times(2)).sendBroadcast(any(Intent.class)); assertEquals("IdleState", getCurrentState().getName()); } @Test Loading Loading @@ -598,30 +498,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { verifyDataSmsIntentBroadcasts(1); } @Test @MediumTest public void testBroadcastUndeliveredDeleted() throws Exception { replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null); SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler); doReturn(0).when(mInboundSmsTracker).getDestPort(); //add a fake entry to db ContentValues rawSms = new ContentValues(); rawSms.put("deleted", 1); mContentProvider.insert(sRawUri, rawSms); //make it a single-part message doReturn(1).when(mInboundSmsTracker).getMessageCount(); //when user unlocks the device, broadcast should not be sent for new message mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED)); waitForMs(100); verify(mContext, times(1)).sendBroadcast(any(Intent.class)); assertEquals("IdleState", getCurrentState().getName()); } @Test @MediumTest public void testBroadcastUndeliveredMultiPart() throws Exception { Loading Loading
src/java/com/android/internal/telephony/InboundSmsHandler.java +49 −51 Original line number Diff line number Diff line Loading @@ -125,8 +125,7 @@ public abstract class InboundSmsHandler extends StateMachine { public static final int ID_COLUMN = 7; public static final String SELECT_BY_ID = "_id=?"; public static final String SELECT_BY_REFERENCE = "address=? AND reference_number=? AND " + "count=? AND deleted=0"; public static final String SELECT_BY_REFERENCE = "address=? AND reference_number=? AND count=?"; /** New SMS received as an AsyncResult. */ public static final int EVENT_NEW_SMS = 1; Loading Loading @@ -162,8 +161,6 @@ public abstract class InboundSmsHandler extends StateMachine { /** URI for raw table of SMS provider. */ private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); private static final Uri sRawUriPermanentDelete = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete"); protected final Context mContext; private final ContentResolver mResolver; Loading Loading @@ -793,13 +790,13 @@ public abstract class InboundSmsHandler extends StateMachine { if (result == Activity.RESULT_OK) { return true; } else { deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), false); deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs()); return false; } } if (BlockChecker.isBlocked(mContext, tracker.getAddress())) { deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), true); deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs()); return false; } Loading Loading @@ -986,10 +983,8 @@ public abstract class InboundSmsHandler extends StateMachine { /** * Helper for {@link SmsBroadcastUndelivered} to delete an old message in the raw table. */ private void deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs, boolean permanentDelete) { Uri uri = permanentDelete ? sRawUriPermanentDelete : sRawUri; int rows = mResolver.delete(uri, deleteWhere, deleteWhereArgs); private void deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs) { int rows = mResolver.delete(sRawUri, deleteWhere, deleteWhereArgs); if (rows == 0) { loge("No rows were deleted from raw table!"); } else if (DBG) { Loading Loading @@ -1079,6 +1074,7 @@ public abstract class InboundSmsHandler extends StateMachine { * @return true on success; false on failure to write to database */ private int addTrackerToRawTable(InboundSmsTracker tracker) { if (tracker.getMessageCount() != 1) { // check for duplicate message segments Cursor cursor = null; try { Loading @@ -1089,8 +1085,8 @@ public abstract class InboundSmsHandler extends StateMachine { String address = tracker.getAddress(); String refNumber = Integer.toString(tracker.getReferenceNumber()); String count = Integer.toString(tracker.getMessageCount()); String seqNumber = Integer.toString(sequence); String date = Long.toString(tracker.getTimestamp()); // set the delete selection args for multi-part message String[] deleteWhereArgs = {address, refNumber, count}; Loading @@ -1098,8 +1094,8 @@ public abstract class InboundSmsHandler extends StateMachine { // Check for duplicate message segments cursor = mResolver.query(sRawUri, PDU_PROJECTION, "address=? AND reference_number=? AND count=? AND sequence=? AND date=?", new String[] {address, refNumber, count, seqNumber, date}, null); "address=? AND reference_number=? AND count=? AND sequence=?", new String[] {address, refNumber, count, seqNumber}, null); // moveToNext() returns false if no duplicates were found if (cursor.moveToNext()) { Loading @@ -1114,6 +1110,7 @@ public abstract class InboundSmsHandler extends StateMachine { } return Intents.RESULT_SMS_DUPLICATED; // reject message } cursor.close(); } catch (SQLException e) { loge("Can't access multipart SMS database", e); return Intents.RESULT_SMS_GENERIC_ERROR; // reject message Loading @@ -1122,6 +1119,7 @@ public abstract class InboundSmsHandler extends StateMachine { cursor.close(); } } } ContentValues values = tracker.getContentValues(); Loading Loading @@ -1214,7 +1212,7 @@ public abstract class InboundSmsHandler extends StateMachine { log("successful broadcast, deleting from raw table."); } deleteFromRawTable(mDeleteWhere, mDeleteWhereArgs, false); deleteFromRawTable(mDeleteWhere, mDeleteWhereArgs); sendMessage(EVENT_BROADCAST_COMPLETE); int durationMillis = (int) ((System.nanoTime() - mBroadcastTimeNano) / 1000000); Loading Loading @@ -1320,7 +1318,7 @@ public abstract class InboundSmsHandler extends StateMachine { try { // Needs phone package permissions. deleteFromRawTable(mSmsFilter.mSmsBroadcastReceiver.mDeleteWhere, mSmsFilter.mSmsBroadcastReceiver.mDeleteWhereArgs, false); mSmsFilter.mSmsBroadcastReceiver.mDeleteWhereArgs); } finally { Binder.restoreCallingIdentity(token); } Loading
src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java +3 −8 Original line number Diff line number Diff line Loading @@ -65,8 +65,6 @@ public class SmsBroadcastUndelivered { /** URI for raw table from SmsProvider. */ private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); private static final Uri sRawUriPermanentDelete = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete"); private static SmsBroadcastUndelivered instance; /** Content resolver to use to access raw table from SmsProvider. */ Loading Loading @@ -137,9 +135,7 @@ public class SmsBroadcastUndelivered { HashSet<SmsReferenceKey> oldMultiPartMessages = new HashSet<SmsReferenceKey>(4); Cursor cursor = null; try { // query only non-deleted ones cursor = mResolver.query(sRawUri, PDU_PENDING_MESSAGE_PROJECTION, "deleted = 0", null, null); cursor = mResolver.query(sRawUri, PDU_PENDING_MESSAGE_PROJECTION, null, null, null); if (cursor == null) { Rlog.e(TAG, "error getting pending message cursor"); return; Loading Loading @@ -186,9 +182,8 @@ public class SmsBroadcastUndelivered { } // Delete old incomplete message segments for (SmsReferenceKey message : oldMultiPartMessages) { // delete permanently int rows = mResolver.delete(sRawUriPermanentDelete, InboundSmsHandler.SELECT_BY_REFERENCE, message.getDeleteWhereArgs()); int rows = mResolver.delete(sRawUri, InboundSmsHandler.SELECT_BY_REFERENCE, message.getDeleteWhereArgs()); if (rows == 0) { Rlog.e(TAG, "No rows were deleted from raw table!"); } else if (DBG) { Loading
src/java/com/android/internal/telephony/SmsMessageBase.java +1 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ public abstract class SmsMessageBase { /** {@hide} */ protected boolean mIsEmail; /** {@hide} Time when SC (service centre) received the message */ /** {@hide} */ protected long mScTimeMillis; /** {@hide} The raw PDU of the message */ Loading
tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java +37 −161 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ import org.mockito.Mock; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class GsmInboundSmsHandlerTest extends TelephonyTest { @Mock Loading @@ -78,9 +77,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { private FakeSmsContentProvider mContentProvider; private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); private static final Uri sRawUriPermanentDelete = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete"); private ContentValues mInboundSmsTrackerCV = new ContentValues(); // For multi-part SMS private ContentValues mInboundSmsTrackerCVPart1; Loading @@ -97,56 +93,13 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { "destination_port", "address", "sub_id", "pdu", "deleted"}; private List<ArrayList<Object>> mListOfRows = new ArrayList<ArrayList<Object>>(); "pdu"}; private MatrixCursor mRawCursor = new MatrixCursor(mRawColumns); private int mNumRows = 0; private int getColumnIndex(String columnName) { int i = 0; for (String s : mRawColumns) { if (s.equals(columnName)) { break; } i++; } return i; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count = 0; if (mNumRows > 0) { // parse selection and selectionArgs SelectionParams selectionParams = new SelectionParams(); selectionParams.parseSelectionParams(selection, selectionArgs); List<Integer> deleteRows = new ArrayList<Integer>(); int i = -1; for (ArrayList<Object> row : mListOfRows) { i++; // filter based on selection parameters if needed if (selection != null) { if (!selectionParams.isMatch(row)) { continue; } } if (uri.compareTo(sRawUri) == 0) { row.set(getColumnIndex("deleted"), "1"); } else { // save index for removal deleteRows.add(i); } count++; } if (uri.compareTo(sRawUriPermanentDelete) == 0) { for (i = deleteRows.size() - 1; i >= 0; i--) { mListOfRows.remove(i); } } } return count; return 0; } @Override Loading @@ -154,7 +107,7 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { Uri newUri = null; if (uri.compareTo(sRawUri) == 0) { if (values != null) { mListOfRows.add(convertRawCVtoArrayList(values)); mRawCursor.addRow(convertRawCVtoArrayList(values)); mNumRows++; newUri = Uri.withAppendedPath(uri, "" + mNumRows); } Loading @@ -167,11 +120,9 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { ArrayList<Object> newRow = new ArrayList<>(); for (String key : mRawColumns) { if (values.containsKey(key)) { newRow.add(values.getAsString(key)); newRow.add(values.get(key)); } else if (key.equals("_id")) { newRow.add(mNumRows + 1); } else if (key.equals("deleted")) { newRow.add("0"); } else { newRow.add(null); } Loading @@ -179,11 +130,15 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { return newRow; } private class SelectionParams { @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { logd("query called for: " + selection); MatrixCursor cursor = new MatrixCursor(projection); if (mNumRows > 0) { // parse selection and selectionArgs String[] paramName = null; String[] paramValue = null; private void parseSelectionParams(String selection, String[] selectionArgs) { if (selection != null) { selection = selection.toLowerCase(); String[] selectionParams = selection.toLowerCase().split("and"); Loading @@ -202,52 +157,38 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { } } } } private boolean isMatch(ArrayList<Object> row) { mRawCursor.moveToFirst(); do { ArrayList<Object> row = new ArrayList<>(); // filter based on selection parameters if needed if (selection != null) { boolean match = true; for (int i = 0; i < paramName.length; i++) { int columnIndex = 0; for (String columnName : mRawColumns) { if (columnName.equals(paramName[i])) { if (!paramValue[i].equals(row.get(columnIndex))) { return false; } else { // move on to next param int columnIndex = mRawCursor.getColumnIndex(columnName); if (columnName.equals(paramName[i]) && !mRawCursor.getString(columnIndex).equals(paramValue[i])) { match = false; break; } } columnIndex++; } } return true; if (!match) { break; } } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { logd("query called for: " + selection); MatrixCursor cursor = new MatrixCursor(projection); if (mNumRows > 0) { // parse selection and selectionArgs SelectionParams selectionParams = new SelectionParams(); selectionParams.parseSelectionParams(selection, selectionArgs); for (ArrayList<Object> row : mListOfRows) { ArrayList<Object> retRow = new ArrayList<>(); // filter based on selection parameters if needed if (selection != null) { if (!selectionParams.isMatch(row)) { // move on to next row if current one does not satisfy selection criteria if (!match) { continue; } } for (String columnName : projection) { int columnIndex = getColumnIndex(columnName); retRow.add(row.get(columnIndex)); } cursor.addRow(retRow); int columnIndex = mRawCursor.getColumnIndex(columnName); row.add(mRawCursor.getString(columnIndex)); } cursor.addRow(row); } while(mRawCursor.moveToNext()); } if (cursor != null) { logd("returning rows: " + cursor.getCount()); Loading Loading @@ -442,7 +383,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { mInboundSmsTrackerCVPart1.put("reference_number", 1); mInboundSmsTrackerCVPart1.put("sequence", 1); mInboundSmsTrackerCVPart1.put("count", 2); mInboundSmsTrackerCVPart1.put("date", System.currentTimeMillis()); doReturn(2).when(mInboundSmsTrackerPart1).getMessageCount(); doReturn(1).when(mInboundSmsTrackerPart1).getReferenceNumber(); Loading @@ -451,8 +391,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { doReturn(1).when(mInboundSmsTrackerPart1).getIndexOffset(); doReturn(-1).when(mInboundSmsTrackerPart1).getDestPort(); doReturn(mSmsPdu).when(mInboundSmsTrackerPart1).getPdu(); doReturn(mInboundSmsTrackerCVPart1.get("date")).when(mInboundSmsTrackerPart1). getTimestamp(); doReturn(mInboundSmsTrackerCVPart1).when(mInboundSmsTrackerPart1).getContentValues(); // Part 2 Loading @@ -463,7 +401,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { mInboundSmsTrackerCVPart2.put("reference_number", 1); mInboundSmsTrackerCVPart2.put("sequence", 2); mInboundSmsTrackerCVPart2.put("count", 2); mInboundSmsTrackerCVPart2.put("date", System.currentTimeMillis()); doReturn(2).when(mInboundSmsTrackerPart2).getMessageCount(); doReturn(1).when(mInboundSmsTrackerPart2).getReferenceNumber(); Loading @@ -472,8 +409,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { doReturn(1).when(mInboundSmsTrackerPart2).getIndexOffset(); doReturn(-1).when(mInboundSmsTrackerPart2).getDestPort(); doReturn(mSmsPdu).when(mInboundSmsTrackerPart2).getPdu(); doReturn(mInboundSmsTrackerCVPart2.get("date")).when(mInboundSmsTrackerPart2). getTimestamp(); doReturn(mInboundSmsTrackerCVPart2).when(mInboundSmsTrackerPart2).getContentValues(); } Loading @@ -487,10 +422,10 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { 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()); mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null, mSmsMessage, null)); waitForMs(100); Loading @@ -505,42 +440,7 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { mSmsMessage, null)); waitForMs(100); // verify broadcast intents verifySmsIntentBroadcasts(0); // if an additional copy of one of the segments above is received, it should not be kept in // the db and should not be combined with any subsequent messages received from the same // sender // additional copy of part 2 of message doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory) .makeInboundSmsTracker(any(byte[].class), anyLong(), anyInt(), anyBoolean(), anyString(), anyInt(), anyInt(), anyInt(), anyBoolean()); mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null, mSmsMessage, null)); waitForMs(100); // verify no additional broadcasts sent verify(mContext, times(2)).sendBroadcast(any(Intent.class)); // part 1 of new sms recieved from same sender with same parameters, just different // timestamps, should not be combined with the additional part 2 received above // call prepareMultiPartSms() to update timestamps prepareMultiPartSms(); // part 1 of new sms doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory) .makeInboundSmsTracker(any(byte[].class), anyLong(), anyInt(), anyBoolean(), anyString(), anyInt(), anyInt(), anyInt(), anyBoolean()); mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null, mSmsMessage, null)); waitForMs(100); // verify no additional broadcasts sent verify(mContext, times(2)).sendBroadcast(any(Intent.class)); assertEquals("IdleState", getCurrentState().getName()); } @Test Loading Loading @@ -598,30 +498,6 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest { verifyDataSmsIntentBroadcasts(1); } @Test @MediumTest public void testBroadcastUndeliveredDeleted() throws Exception { replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null); SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler); doReturn(0).when(mInboundSmsTracker).getDestPort(); //add a fake entry to db ContentValues rawSms = new ContentValues(); rawSms.put("deleted", 1); mContentProvider.insert(sRawUri, rawSms); //make it a single-part message doReturn(1).when(mInboundSmsTracker).getMessageCount(); //when user unlocks the device, broadcast should not be sent for new message mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED)); waitForMs(100); verify(mContext, times(1)).sendBroadcast(any(Intent.class)); assertEquals("IdleState", getCurrentState().getName()); } @Test @MediumTest public void testBroadcastUndeliveredMultiPart() throws Exception { Loading