{
	"id": "90380614-d130-4e5f-9368-f172b79a5a66",
	"created_at": "2026-04-06T00:21:59.500151Z",
	"updated_at": "2026-04-10T03:21:35.755423Z",
	"deleted_at": null,
	"sha1_hash": "b991c16cb0decb3a5b04441fb1fa63f047fba701",
	"title": "src/com/android/providers/telephony/SmsProvider.java - platform/packages/providers/TelephonyProvider - Git at Google",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 80667,
	"plain_text": "src/com/android/providers/telephony/SmsProvider.java -\r\nplatform/packages/providers/TelephonyProvider - Git at Google\r\nArchived: 2026-04-05 17:15:12 UTC\r\n/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0\r\n(the \"License\"); * you may not use this file except in compliance with the License. * You may obtain a copy of the\r\nLicense at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in\r\nwriting, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT\r\nWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific\r\nlanguage governing permissions and * limitations under the License. */package\r\ncom.android.providers.telephony;import android.content.ContentProvider;import\r\nandroid.content.ContentResolver;import android.content.ContentValues;import\r\nandroid.content.UriMatcher;import android.database.Cursor;import android.database.DatabaseUtils;import\r\nandroid.database.MatrixCursor;import android.database.sqlite.SQLiteDatabase;import\r\nandroid.database.sqlite.SQLiteOpenHelper;import android.database.sqlite.SQLiteQueryBuilder;import\r\nandroid.net.Uri;import android.provider.Contacts;import android.provider.Telephony;import\r\nandroid.provider.Telephony.Mms;import android.provider.Telephony.MmsSms;import\r\nandroid.provider.Telephony.Sms;import android.provider.Telephony.TextBasedSmsColumns;import\r\nandroid.provider.Telephony.Threads;import android.telephony.SmsManager;import\r\nandroid.telephony.SmsMessage;import android.text.TextUtils;import android.util.Log;import\r\njava.util.ArrayList;import java.util.HashMap;public class SmsProvider extends ContentProvider { private static\r\nfinal Uri NOTIFICATION_URI = Uri.parse(\"content://sms\"); private static final Uri ICC_URI =\r\nUri.parse(\"content://sms/icc\"); static final String TABLE_SMS = \"sms\"; private static final String TABLE_RAW\r\n= \"raw\"; private static final String TABLE_SR_PENDING = \"sr_pending\"; private static final String\r\nTABLE_WORDS = \"words\"; private static final Integer ONE = Integer.valueOf(1); private static final String[]\r\nCONTACT_QUERY_PROJECTION = new String[] { Contacts.Phones.PERSON_ID }; private static final int\r\nPERSON_ID_COLUMN = 0; /** * These are the columns that are available when reading SMS * messages from\r\nthe ICC. Columns whose names begin with \"is_\" * have either \"true\" or \"false\" as their values. */ private final\r\nstatic String[] ICC_COLUMNS = new String[] { // N.B.: These columns must appear in the same order as the //\r\ncalls to add appear in convertIccToSms. \"service_center_address\", // getServiceCenterAddress \"address\", //\r\ngetDisplayOriginatingAddress \"message_class\", // getMessageClass \"body\", // getDisplayMessageBody \"date\", //\r\ngetTimestampMillis \"status\", // getStatusOnIcc \"index_on_icc\", // getIndexOnIcc \"is_status_report\", //\r\nisStatusReportMessage \"transport_type\", // Always \"sms\". \"type\", // Always MESSAGE_TYPE_ALL. \"locked\", //\r\nAlways 0 (false). \"error_code\", // Always 0 \"_id\" }; @Override public boolean onCreate() { mOpenHelper =\r\nMmsSmsDatabaseHelper.getInstance(getContext()); return true; } @Override public Cursor query(Uri url,\r\nString[] projectionIn, String selection, String[] selectionArgs, String sort) { SQLiteQueryBuilder qb = new\r\nSQLiteQueryBuilder(); // Generate the body of the query. int match = sURLMatcher.match(url); switch (match) {\r\ncase SMS_ALL: constructQueryForBox(qb, Sms.MESSAGE_TYPE_ALL); break; case SMS_UNDELIVERED:\r\nconstructQueryForUndelivered(qb); break; case SMS_FAILED: constructQueryForBox(qb,\r\nhttps://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/7e7c274/src/com/android/providers/telephony/SmsProvider.java\r\nPage 1 of 6\n\nSms.MESSAGE_TYPE_FAILED); break; case SMS_QUEUED: constructQueryForBox(qb,\r\nSms.MESSAGE_TYPE_QUEUED); break; case SMS_INBOX: constructQueryForBox(qb,\r\nSms.MESSAGE_TYPE_INBOX); break; case SMS_SENT: constructQueryForBox(qb,\r\nSms.MESSAGE_TYPE_SENT); break; case SMS_DRAFT: constructQueryForBox(qb,\r\nSms.MESSAGE_TYPE_DRAFT); break; case SMS_OUTBOX: constructQueryForBox(qb,\r\nSms.MESSAGE_TYPE_OUTBOX); break; case SMS_ALL_ID: qb.setTables(TABLE_SMS); qb.appendWhere(\"\r\n(_id = \" + url.getPathSegments().get(0) + \")\"); break; case SMS_INBOX_ID: case SMS_FAILED_ID: case\r\nSMS_SENT_ID: case SMS_DRAFT_ID: case SMS_OUTBOX_ID: qb.setTables(TABLE_SMS);\r\nqb.appendWhere(\"(_id = \" + url.getPathSegments().get(1) + \")\"); break; case SMS_CONVERSATIONS_ID: int\r\nthreadID; try { threadID = Integer.parseInt(url.getPathSegments().get(1)); if (Log.isLoggable(TAG,\r\nLog.VERBOSE)) { Log.d(TAG, \"query conversations: threadID=\" + threadID); } } catch (Exception ex) {\r\nLog.e(TAG, \"Bad conversation thread id: \" + url.getPathSegments().get(1)); return null; }\r\nqb.setTables(TABLE_SMS); qb.appendWhere(\"thread_id = \" + threadID); break; case SMS_CONVERSATIONS:\r\nqb.setTables(\"sms, (SELECT thread_id AS group_thread_id, MAX(date)AS group_date,\" + \"COUNT(*) AS\r\nmsg_count FROM sms GROUP BY thread_id) AS groups\"); qb.appendWhere(\"sms.thread_id =\r\ngroups.group_thread_id AND sms.date =\" + \"groups.group_date\");\r\nqb.setProjectionMap(sConversationProjectionMap); break; case SMS_RAW_MESSAGE: qb.setTables(\"raw\");\r\nbreak; case SMS_STATUS_PENDING: qb.setTables(\"sr_pending\"); break; case SMS_ATTACHMENT:\r\nqb.setTables(\"attachments\"); break; case SMS_ATTACHMENT_ID: qb.setTables(\"attachments\");\r\nqb.appendWhere( \"(sms_id = \" + url.getPathSegments().get(1) + \")\"); break; case SMS_QUERY_THREAD_ID:\r\nqb.setTables(\"canonical_addresses\"); if (projectionIn == null) { projectionIn = sIDProjection; } break; case\r\nSMS_STATUS_ID: qb.setTables(TABLE_SMS); qb.appendWhere(\"(_id = \" + url.getPathSegments().get(1) +\r\n\")\"); break; case SMS_ALL_ICC: return getAllMessagesFromIcc(); case SMS_ICC: String messageIndexString =\r\nurl.getPathSegments().get(1); return getSingleMessageFromIcc(messageIndexString); default: Log.e(TAG,\r\n\"Invalid request: \" + url); return null; } String orderBy = null; if (!TextUtils.isEmpty(sort)) { orderBy = sort; } else\r\nif (qb.getTables().equals(TABLE_SMS)) { orderBy = Sms.DEFAULT_SORT_ORDER; } SQLiteDatabase db =\r\nmOpenHelper.getReadableDatabase(); Cursor ret = qb.query(db, projectionIn, selection, selectionArgs, null, null,\r\norderBy); // TODO: Since the URLs are a mess, always use content://sms\r\nret.setNotificationUri(getContext().getContentResolver(), NOTIFICATION_URI); return ret; } private Object[]\r\nconvertIccToSms(SmsMessage message, int id) { // N.B.: These calls must appear in the same order as the //\r\ncolumns appear in ICC_COLUMNS. Object[] row = new Object[13]; row[0] =\r\nmessage.getServiceCenterAddress(); row[1] = message.getDisplayOriginatingAddress(); row[2] =\r\nString.valueOf(message.getMessageClass()); row[3] = message.getDisplayMessageBody(); row[4] =\r\nmessage.getTimestampMillis(); row[5] = Sms.STATUS_NONE; row[6] = message.getIndexOnIcc(); row[7] =\r\nmessage.isStatusReportMessage(); row[8] = \"sms\"; row[9] = TextBasedSmsColumns.MESSAGE_TYPE_ALL;\r\nrow[10] = 0; // locked row[11] = 0; // error_code row[12] = id; return row; } /** * Return a Cursor containing just\r\none message from the ICC. */ private Cursor getSingleMessageFromIcc(String messageIndexString) { try { int\r\nmessageIndex = Integer.parseInt(messageIndexString); SmsManager smsManager = SmsManager.getDefault();\r\nArrayList\u003cSmsMessage\u003e messages = smsManager.getAllMessagesFromIcc(); SmsMessage message =\r\nmessages.get(messageIndex); if (message == null) { throw new IllegalArgumentException( \"Message not\r\nretrieved. ID: \" + messageIndexString); } MatrixCursor cursor = new MatrixCursor(ICC_COLUMNS, 1);\r\ncursor.addRow(convertIccToSms(message, 0)); return withIccNotificationUri(cursor); } catch\r\nhttps://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/7e7c274/src/com/android/providers/telephony/SmsProvider.java\r\nPage 2 of 6\n\n(NumberFormatException exception) { throw new IllegalArgumentException( \"Bad SMS ICC ID: \" +\r\nmessageIndexString); } } /** * Return a Cursor listing all the messages stored on the ICC. */ private Cursor\r\ngetAllMessagesFromIcc() { SmsManager smsManager = SmsManager.getDefault(); ArrayList\u003cSmsMessage\u003e\r\nmessages = smsManager.getAllMessagesFromIcc(); final int count = messages.size(); MatrixCursor cursor = new\r\nMatrixCursor(ICC_COLUMNS, count); for (int i = 0; i \u003c count; i++) { SmsMessage message = messages.get(i); if\r\n(message != null) { cursor.addRow(convertIccToSms(message, i)); } } return withIccNotificationUri(cursor); }\r\nprivate Cursor withIccNotificationUri(Cursor cursor) {\r\ncursor.setNotificationUri(getContext().getContentResolver(), ICC_URI); return cursor; } private void\r\nconstructQueryForBox(SQLiteQueryBuilder qb, int type) { qb.setTables(TABLE_SMS); if (type !=\r\nSms.MESSAGE_TYPE_ALL) { qb.appendWhere(\"type=\" + type); } } private void\r\nconstructQueryForUndelivered(SQLiteQueryBuilder qb) { qb.setTables(TABLE_SMS); qb.appendWhere(\"\r\n(type=\" + Sms.MESSAGE_TYPE_OUTBOX + \" OR type=\" + Sms.MESSAGE_TYPE_FAILED + \" OR type=\"\r\n+ Sms.MESSAGE_TYPE_QUEUED + \")\"); } @Override public String getType(Uri url) { switch\r\n(url.getPathSegments().size()) { case 0: return VND_ANDROID_DIR_SMS; case 1: try {\r\nInteger.parseInt(url.getPathSegments().get(0)); return VND_ANDROID_SMS; } catch (NumberFormatException\r\nex) { return VND_ANDROID_DIR_SMS; } case 2: // TODO: What about \"threadID\"? if\r\n(url.getPathSegments().get(0).equals(\"conversations\")) { return VND_ANDROID_SMSCHAT; } else { return\r\nVND_ANDROID_SMS; } } return null; } @Override public Uri insert(Uri url, ContentValues initialValues) {\r\nContentValues values; long rowID; int type = Sms.MESSAGE_TYPE_ALL; int match =\r\nsURLMatcher.match(url); String table = TABLE_SMS; switch (match) { case SMS_ALL: Integer typeObj =\r\ninitialValues.getAsInteger(Sms.TYPE); if (typeObj != null) { type = typeObj.intValue(); } else { // default to\r\ninbox type = Sms.MESSAGE_TYPE_INBOX; } break; case SMS_INBOX: type =\r\nSms.MESSAGE_TYPE_INBOX; break; case SMS_FAILED: type = Sms.MESSAGE_TYPE_FAILED; break;\r\ncase SMS_QUEUED: type = Sms.MESSAGE_TYPE_QUEUED; break; case SMS_SENT: type =\r\nSms.MESSAGE_TYPE_SENT; break; case SMS_DRAFT: type = Sms.MESSAGE_TYPE_DRAFT; break; case\r\nSMS_OUTBOX: type = Sms.MESSAGE_TYPE_OUTBOX; break; case SMS_RAW_MESSAGE: table = \"raw\";\r\nbreak; case SMS_STATUS_PENDING: table = \"sr_pending\"; break; case SMS_ATTACHMENT: table =\r\n\"attachments\"; break; case SMS_NEW_THREAD_ID: table = \"canonical_addresses\"; break; default: Log.e(TAG,\r\n\"Invalid request: \" + url); return null; } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if\r\n(table.equals(TABLE_SMS)) { boolean addDate = false; boolean addType = false; // Make sure that the date and\r\ntype are set if (initialValues == null) { values = new ContentValues(1); addDate = true; addType = true; } else {\r\nvalues = new ContentValues(initialValues); if (!initialValues.containsKey(Sms.DATE)) { addDate = true; } if\r\n(!initialValues.containsKey(Sms.TYPE)) { addType = true; } } if (addDate) { values.put(Sms.DATE, new\r\nLong(System.currentTimeMillis())); } if (addType \u0026\u0026 (type != Sms.MESSAGE_TYPE_ALL)) {\r\nvalues.put(Sms.TYPE, Integer.valueOf(type)); } // thread_id Long threadId =\r\nvalues.getAsLong(Sms.THREAD_ID); String address = values.getAsString(Sms.ADDRESS); if (((threadId ==\r\nnull) || (threadId == 0)) \u0026\u0026 (!TextUtils.isEmpty(address))) { values.put(Sms.THREAD_ID,\r\nThreads.getOrCreateThreadId( getContext(), address)); } // If this message is going in as a draft, it should replace\r\nany // other draft messages in the thread. Just delete all draft // messages with this thread ID. We could add an OR\r\nREPLACE to // the insert below, but we'd have to query to find the old _id // to produce a conflict anyway. if\r\n(values.getAsInteger(Sms.TYPE) == Sms.MESSAGE_TYPE_DRAFT) { db.delete(TABLE_SMS, \"thread_id=?\r\nAND type=?\", new String[] { values.getAsString(Sms.THREAD_ID),\r\nhttps://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/7e7c274/src/com/android/providers/telephony/SmsProvider.java\r\nPage 3 of 6\n\nInteger.toString(Sms.MESSAGE_TYPE_DRAFT) }); } if (type == Sms.MESSAGE_TYPE_INBOX) { // Look\r\nup the person if not already filled in. if ((values.getAsLong(Sms.PERSON) == null) \u0026\u0026\r\n(!TextUtils.isEmpty(address))) { Cursor cursor = null; Uri uri =\r\nUri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, Uri.encode(address)); try { cursor =\r\ngetContext().getContentResolver().query( uri, CONTACT_QUERY_PROJECTION, null, null, null); if\r\n(cursor.moveToFirst()) { Long id = Long.valueOf(cursor.getLong(PERSON_ID_COLUMN));\r\nvalues.put(Sms.PERSON, id); } } catch (Exception ex) { Log.e(TAG, \"insert: query contact uri \" + uri + \" caught\r\n\", ex); } finally { if (cursor != null) { cursor.close(); } } } } else { // Mark all non-inbox messages read.\r\nvalues.put(Sms.READ, ONE); } } else { if (initialValues == null) { values = new ContentValues(1); } else {\r\nvalues = initialValues; } } rowID = db.insert(table, \"body\", values); // Don't use a trigger for updating the words\r\ntable because of a bug // in FTS3. The bug is such that the call to get the last inserted // row is incorrect. if (table\r\n== TABLE_SMS) { // Update the words table with a corresponding row. The words table // allows us to search for\r\nwords quickly, without scanning the whole // table; ContentValues cv = new ContentValues();\r\ncv.put(Telephony.MmsSms.WordsTable.ID, rowID); cv.put(Telephony.MmsSms.WordsTable.INDEXED_TEXT,\r\nvalues.getAsString(\"body\")); cv.put(Telephony.MmsSms.WordsTable.SOURCE_ROW_ID, rowID);\r\ncv.put(Telephony.MmsSms.WordsTable.TABLE_ID, 1); db.insert(TABLE_WORDS,\r\nTelephony.MmsSms.WordsTable.INDEXED_TEXT, cv); } if (rowID \u003e 0) { Uri uri = Uri.parse(\"content://\" +\r\ntable + \"/\" + rowID); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.d(TAG, \"insert \" + uri + \" succeeded\"); }\r\nnotifyChange(uri); return uri; } else { Log.e(TAG,\"insert: failed! \" + values.toString()); } return null; } @Override\r\npublic int delete(Uri url, String where, String[] whereArgs) { int count; int match = sURLMatcher.match(url);\r\nSQLiteDatabase db = mOpenHelper.getWritableDatabase(); switch (match) { case SMS_ALL: count =\r\ndb.delete(TABLE_SMS, where, whereArgs); if (count != 0) { // Don't update threads unless something changed.\r\nMmsSmsDatabaseHelper.updateAllThreads(db, where, whereArgs); } break; case SMS_ALL_ID: try { int\r\nmessage_id = Integer.parseInt(url.getPathSegments().get(0)); count = MmsSmsDatabaseHelper.deleteOneSms(db,\r\nmessage_id); } catch (Exception e) { throw new IllegalArgumentException( \"Bad message id: \" +\r\nurl.getPathSegments().get(0)); } break; case SMS_CONVERSATIONS_ID: int threadID; try { threadID =\r\nInteger.parseInt(url.getPathSegments().get(1)); } catch (Exception ex) { throw new IllegalArgumentException(\r\n\"Bad conversation thread id: \" + url.getPathSegments().get(1)); } // delete the messages from the sms table where\r\n= DatabaseUtils.concatenateWhere(\"thread_id=\" + threadID, where); count = db.delete(TABLE_SMS, where,\r\nwhereArgs); MmsSmsDatabaseHelper.updateThread(db, threadID); break; case SMS_RAW_MESSAGE: count =\r\ndb.delete(\"raw\", where, whereArgs); break; case SMS_STATUS_PENDING: count = db.delete(\"sr_pending\",\r\nwhere, whereArgs); break; case SMS_ICC: String messageIndexString = url.getPathSegments().get(1); return\r\ndeleteMessageFromIcc(messageIndexString); default: throw new IllegalArgumentException(\"Unknown URL\"); }\r\nif (count \u003e 0) { notifyChange(url); } return count; } /** * Delete the message at index from ICC. Return true iff *\r\nsuccessful. */ private int deleteMessageFromIcc(String messageIndexString) { SmsManager smsManager =\r\nSmsManager.getDefault(); try { return smsManager.deleteMessageFromIcc(\r\nInteger.parseInt(messageIndexString)) ? 1 : 0; } catch (NumberFormatException exception) { throw new\r\nIllegalArgumentException( \"Bad SMS ICC ID: \" + messageIndexString); } finally { ContentResolver cr =\r\ngetContext().getContentResolver(); cr.notifyChange(ICC_URI, null); } } @Override public int update(Uri url,\r\nContentValues values, String where, String[] whereArgs) { int count = 0; String table = TABLE_SMS; String\r\nextraWhere = null; SQLiteDatabase db = mOpenHelper.getWritableDatabase(); switch (sURLMatcher.match(url))\r\n{ case SMS_RAW_MESSAGE: table = TABLE_RAW; break; case SMS_STATUS_PENDING: table =\r\nhttps://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/7e7c274/src/com/android/providers/telephony/SmsProvider.java\r\nPage 4 of 6\n\nTABLE_SR_PENDING; break; case SMS_ALL: case SMS_FAILED: case SMS_QUEUED: case SMS_INBOX:\r\ncase SMS_SENT: case SMS_DRAFT: case SMS_OUTBOX: case SMS_CONVERSATIONS: break; case\r\nSMS_ALL_ID: extraWhere = \"_id=\" + url.getPathSegments().get(0); break; case SMS_INBOX_ID: case\r\nSMS_FAILED_ID: case SMS_SENT_ID: case SMS_DRAFT_ID: case SMS_OUTBOX_ID: extraWhere =\r\n\"_id=\" + url.getPathSegments().get(1); break; case SMS_CONVERSATIONS_ID: { String threadId =\r\nurl.getPathSegments().get(1); try { Integer.parseInt(threadId); } catch (Exception ex) { Log.e(TAG, \"Bad\r\nconversation thread id: \" + threadId); break; } extraWhere = \"thread_id=\" + threadId; break; } case\r\nSMS_STATUS_ID: extraWhere = \"_id=\" + url.getPathSegments().get(1); break; default: throw new\r\nUnsupportedOperationException( \"URI \" + url + \" not supported\"); } where =\r\nDatabaseUtils.concatenateWhere(where, extraWhere); count = db.update(table, values, where, whereArgs); if\r\n(count \u003e 0) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.d(TAG, \"update \" + url + \" succeeded\"); }\r\nnotifyChange(url); } return count; } private void notifyChange(Uri uri) { ContentResolver cr =\r\ngetContext().getContentResolver(); cr.notifyChange(uri, null); cr.notifyChange(MmsSms.CONTENT_URI, null);\r\ncr.notifyChange(Uri.parse(\"content://mms-sms/conversations/\"), null); } private SQLiteOpenHelper\r\nmOpenHelper; private final static String TAG = \"SmsProvider\"; private final static String VND_ANDROID_SMS\r\n= \"vnd.android.cursor.item/sms\"; private final static String VND_ANDROID_SMSCHAT =\r\n\"vnd.android.cursor.item/sms-chat\"; private final static String VND_ANDROID_DIR_SMS =\r\n\"vnd.android.cursor.dir/sms\"; private static final HashMap\u003cString, String\u003e sConversationProjectionMap = new\r\nHashMap\u003cString, String\u003e(); private static final String[] sIDProjection = new String[] { \"_id\" }; private static final\r\nint SMS_ALL = 0; private static final int SMS_ALL_ID = 1; private static final int SMS_INBOX = 2; private\r\nstatic final int SMS_INBOX_ID = 3; private static final int SMS_SENT = 4; private static final int\r\nSMS_SENT_ID = 5; private static final int SMS_DRAFT = 6; private static final int SMS_DRAFT_ID = 7;\r\nprivate static final int SMS_OUTBOX = 8; private static final int SMS_OUTBOX_ID = 9; private static final int\r\nSMS_CONVERSATIONS = 10; private static final int SMS_CONVERSATIONS_ID = 11; private static final int\r\nSMS_RAW_MESSAGE = 15; private static final int SMS_ATTACHMENT = 16; private static final int\r\nSMS_ATTACHMENT_ID = 17; private static final int SMS_NEW_THREAD_ID = 18; private static final int\r\nSMS_QUERY_THREAD_ID = 19; private static final int SMS_STATUS_ID = 20; private static final int\r\nSMS_STATUS_PENDING = 21; private static final int SMS_ALL_ICC = 22; private static final int SMS_ICC =\r\n23; private static final int SMS_FAILED = 24; private static final int SMS_FAILED_ID = 25; private static final\r\nint SMS_QUEUED = 26; private static final int SMS_UNDELIVERED = 27; private static final UriMatcher\r\nsURLMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sURLMatcher.addURI(\"sms\", null,\r\nSMS_ALL); sURLMatcher.addURI(\"sms\", \"#\", SMS_ALL_ID); sURLMatcher.addURI(\"sms\", \"inbox\",\r\nSMS_INBOX); sURLMatcher.addURI(\"sms\", \"inbox/#\", SMS_INBOX_ID); sURLMatcher.addURI(\"sms\",\r\n\"sent\", SMS_SENT); sURLMatcher.addURI(\"sms\", \"sent/#\", SMS_SENT_ID); sURLMatcher.addURI(\"sms\",\r\n\"draft\", SMS_DRAFT); sURLMatcher.addURI(\"sms\", \"draft/#\", SMS_DRAFT_ID);\r\nsURLMatcher.addURI(\"sms\", \"outbox\", SMS_OUTBOX); sURLMatcher.addURI(\"sms\", \"outbox/#\",\r\nSMS_OUTBOX_ID); sURLMatcher.addURI(\"sms\", \"undelivered\", SMS_UNDELIVERED);\r\nsURLMatcher.addURI(\"sms\", \"failed\", SMS_FAILED); sURLMatcher.addURI(\"sms\", \"failed/#\",\r\nSMS_FAILED_ID); sURLMatcher.addURI(\"sms\", \"queued\", SMS_QUEUED); sURLMatcher.addURI(\"sms\",\r\n\"conversations\", SMS_CONVERSATIONS); sURLMatcher.addURI(\"sms\", \"conversations/*\",\r\nSMS_CONVERSATIONS_ID); sURLMatcher.addURI(\"sms\", \"raw\", SMS_RAW_MESSAGE);\r\nsURLMatcher.addURI(\"sms\", \"attachments\", SMS_ATTACHMENT); sURLMatcher.addURI(\"sms\",\r\nhttps://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/7e7c274/src/com/android/providers/telephony/SmsProvider.java\r\nPage 5 of 6\n\n\"attachments/#\", SMS_ATTACHMENT_ID); sURLMatcher.addURI(\"sms\", \"threadID\",\r\nSMS_NEW_THREAD_ID); sURLMatcher.addURI(\"sms\", \"threadID/*\", SMS_QUERY_THREAD_ID);\r\nsURLMatcher.addURI(\"sms\", \"status/#\", SMS_STATUS_ID); sURLMatcher.addURI(\"sms\", \"sr_pending\",\r\nSMS_STATUS_PENDING); sURLMatcher.addURI(\"sms\", \"icc\", SMS_ALL_ICC);\r\nsURLMatcher.addURI(\"sms\", \"icc/#\", SMS_ICC); //we keep these for not breaking old applications\r\nsURLMatcher.addURI(\"sms\", \"sim\", SMS_ALL_ICC); sURLMatcher.addURI(\"sms\", \"sim/#\", SMS_ICC);\r\nsConversationProjectionMap.put(Sms.Conversations.SNIPPET, \"sms.body AS snippet\");\r\nsConversationProjectionMap.put(Sms.Conversations.THREAD_ID, \"sms.thread_id AS thread_id\");\r\nsConversationProjectionMap.put(Sms.Conversations.MESSAGE_COUNT, \"groups.msg_count AS msg_count\");\r\nsConversationProjectionMap.put(\"delta\", null); }}\r\nSource: https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/7e7c274/src/com/android/providers/telephony/S\r\nmsProvider.java\r\nhttps://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/7e7c274/src/com/android/providers/telephony/SmsProvider.java\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/7e7c274/src/com/android/providers/telephony/SmsProvider.java"
	],
	"report_names": [
		"SmsProvider.java"
	],
	"threat_actors": [],
	"ts_created_at": 1775434919,
	"ts_updated_at": 1775791295,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/b991c16cb0decb3a5b04441fb1fa63f047fba701.pdf",
		"text": "https://archive.orkl.eu/b991c16cb0decb3a5b04441fb1fa63f047fba701.txt",
		"img": "https://archive.orkl.eu/b991c16cb0decb3a5b04441fb1fa63f047fba701.jpg"
	}
}