blob: 37d1787ad8d1326b011c4110e12fc36451e03d15 [file] [log] [blame]
The Android Open Source Project7236c3a2009-03-03 19:32:44 -08001/*
2 * Copyright (C) 2007 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
17package com.android.providers.telephony;
18
19import com.google.android.mms.pdu.PduHeaders;
20
21import android.content.ContentProvider;
22import android.content.ContentValues;
23import android.content.Context;
24import android.content.Intent;
25import android.content.UriMatcher;
26import android.database.Cursor;
27import android.database.sqlite.SQLiteDatabase;
28import android.database.sqlite.SQLiteOpenHelper;
29import android.database.sqlite.SQLiteQueryBuilder;
30import android.net.Uri;
31import android.os.ParcelFileDescriptor;
32import android.provider.BaseColumns;
33import android.provider.Telephony.Mms;
34import android.provider.Telephony.MmsSms;
35import android.provider.Telephony.Mms.Addr;
36import android.provider.Telephony.Mms.Part;
37import android.provider.Telephony.Mms.Rate;
38import android.text.TextUtils;
39import android.util.Config;
40import android.util.Log;
41
42import java.io.File;
43import java.io.FileNotFoundException;
44import java.io.IOException;
45
46/**
47 * The class to provide base facility to access MMS related content,
48 * which is stored in a SQLite database and in the file system.
49 */
50public class MmsProvider extends ContentProvider {
51 static final String TABLE_PDU = "pdu";
52 static final String TABLE_ADDR = "addr";
53 static final String TABLE_PART = "part";
54 static final String TABLE_RATE = "rate";
55 static final String TABLE_DRM = "drm";
56
57 @Override
58 public boolean onCreate() {
59 mOpenHelper = MmsSmsDatabaseHelper.getInstance(getContext());
60 return true;
61 }
62
63 @Override
64 public Cursor query(Uri uri, String[] projection,
65 String selection, String[] selectionArgs, String sortOrder) {
66 SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
67
68 // Generate the body of the query.
69 int match = sURLMatcher.match(uri);
70 if (LOCAL_LOGV) {
71 Log.v(TAG, "Query uri=" + uri + ", match=" + match);
72 }
73
74 switch (match) {
75 case MMS_ALL:
76 constructQueryForBox(qb, Mms.MESSAGE_BOX_ALL);
77 break;
78 case MMS_INBOX:
79 constructQueryForBox(qb, Mms.MESSAGE_BOX_INBOX);
80 break;
81 case MMS_SENT:
82 constructQueryForBox(qb, Mms.MESSAGE_BOX_SENT);
83 break;
84 case MMS_DRAFTS:
85 constructQueryForBox(qb, Mms.MESSAGE_BOX_DRAFTS);
86 break;
87 case MMS_OUTBOX:
88 constructQueryForBox(qb, Mms.MESSAGE_BOX_OUTBOX);
89 break;
90 case MMS_ALL_ID:
91 qb.setTables(TABLE_PDU);
92 qb.appendWhere(Mms._ID + "=" + uri.getPathSegments().get(0));
93 break;
94 case MMS_INBOX_ID:
95 case MMS_SENT_ID:
96 case MMS_DRAFTS_ID:
97 case MMS_OUTBOX_ID:
98 qb.setTables(TABLE_PDU);
99 qb.appendWhere(Mms._ID + "=" + uri.getPathSegments().get(1));
100 qb.appendWhere(" AND " + Mms.MESSAGE_BOX + "="
101 + getMessageBoxByMatch(match));
102 break;
103 case MMS_ALL_PART:
104 qb.setTables(TABLE_PART);
105 break;
106 case MMS_MSG_PART:
107 qb.setTables(TABLE_PART);
108 qb.appendWhere(Part.MSG_ID + "=" + uri.getPathSegments().get(0));
109 break;
110 case MMS_PART_ID:
111 qb.setTables(TABLE_PART);
112 qb.appendWhere(Part._ID + "=" + uri.getPathSegments().get(1));
113 break;
114 case MMS_MSG_ADDR:
115 qb.setTables(TABLE_ADDR);
116 qb.appendWhere(Addr.MSG_ID + "=" + uri.getPathSegments().get(0));
117 break;
118 case MMS_REPORT_STATUS:
119 /*
120 SELECT DISTINCT address,
121 T.delivery_status AS delivery_status,
122 T.read_status AS read_status
123 FROM addr
124 INNER JOIN (SELECT P1._id AS id1, P2._id AS id2, P3._id AS id3,
125 ifnull(P2.st, 0) AS delivery_status,
126 ifnull(P3.read_status, 0) AS read_status
127 FROM pdu P1
128 INNER JOIN pdu P2
129 ON P1.m_id = P2.m_id AND P2.m_type = 134
130 LEFT JOIN pdu P3
131 ON P1.m_id = P3.m_id AND P3.m_type = 136
132 UNION
133 SELECT P1._id AS id1, P2._id AS id2, P3._id AS id3,
134 ifnull(P2.st, 0) AS delivery_status,
135 ifnull(P3.read_status, 0) AS read_status
136 FROM pdu P1
137 INNER JOIN pdu P3
138 ON P1.m_id = P3.m_id AND P3.m_type = 136
139 LEFT JOIN pdu P2
140 ON P1.m_id = P2.m_id AND P2.m_type = 134) T
141 ON (msg_id = id2 AND type = 151)
142 OR (msg_id = id3 AND type = 137)
143 WHERE T.id1 = ?;
144 */
145 qb.setTables("addr INNER JOIN (SELECT P1._id AS id1, P2._id" +
146 " AS id2, P3._id AS id3, ifnull(P2.st, 0) AS" +
147 " delivery_status, ifnull(P3.read_status, 0) AS" +
148 " read_status FROM pdu P1 INNER JOIN pdu P2 ON" +
149 " P1.m_id=P2.m_id AND P2.m_type=134 LEFT JOIN" +
150 " pdu P3 ON P1.m_id=P3.m_id AND P3.m_type=136" +
151 " UNION SELECT P1._id AS id1, P2._id AS id2, P3._id" +
152 " AS id3, ifnull(P2.st, 0) AS delivery_status," +
153 " ifnull(P3.read_status, 0) AS read_status FROM" +
154 " pdu P1 INNER JOIN pdu P3 ON P1.m_id=P3.m_id AND" +
155 " P3.m_type=136 LEFT JOIN pdu P2 ON P1.m_id=P2.m_id" +
156 " AND P2.m_type=134) T ON (msg_id=id2 AND type=151)" +
157 " OR (msg_id=id3 AND type=137)");
158 qb.appendWhere("T.id1 = " + uri.getLastPathSegment());
159 qb.setDistinct(true);
160 break;
161 case MMS_REPORT_REQUEST:
162 /*
163 SELECT address, d_rpt, rr
164 FROM addr join pdu on pdu._id = addr.msg_id
165 WHERE pdu._id = messageId AND addr.type = 151
166 */
167 qb.setTables(TABLE_ADDR + " join " +
168 TABLE_PDU + " on pdu._id = addr.msg_id");
169 qb.appendWhere("pdu._id = " + uri.getLastPathSegment());
170 qb.appendWhere(" AND " + "addr.type = " + PduHeaders.TO);
171 break;
172 case MMS_SENDING_RATE:
173 qb.setTables(TABLE_RATE);
174 break;
175 case MMS_DRM_STORAGE_ID:
176 qb.setTables(TABLE_DRM);
177 qb.appendWhere(BaseColumns._ID + "=" + uri.getLastPathSegment());
178 break;
179 default:
180 Log.e(TAG, "Invalid request: " + uri);
181 return null;
182 }
183
184 String finalSortOrder = null;
185 if (TextUtils.isEmpty(sortOrder)) {
186 if (qb.getTables().equals(TABLE_PDU)) {
187 finalSortOrder = Mms.DATE + " DESC";
188 } else if (qb.getTables().equals(TABLE_PART)) {
189 finalSortOrder = Part.SEQ;
190 }
191 } else {
192 finalSortOrder = sortOrder;
193 }
194
195 SQLiteDatabase db = mOpenHelper.getReadableDatabase();
196 Cursor ret = qb.query(db, projection, selection,
197 selectionArgs, null, null, finalSortOrder);
198
199 // TODO: Does this need to be a URI for this provider.
200 ret.setNotificationUri(getContext().getContentResolver(), uri);
201 return ret;
202 }
203
204 private void constructQueryForBox(SQLiteQueryBuilder qb, int msgBox) {
205 qb.setTables(TABLE_PDU);
206
207 if (msgBox != Mms.MESSAGE_BOX_ALL) {
208 qb.appendWhere(Mms.MESSAGE_BOX + "=" + msgBox);
209 }
210 }
211
212 @Override
213 public String getType(Uri uri) {
214 int match = sURLMatcher.match(uri);
215 switch (match) {
216 case MMS_ALL:
217 case MMS_INBOX:
218 case MMS_SENT:
219 case MMS_DRAFTS:
220 case MMS_OUTBOX:
221 return VND_ANDROID_DIR_MMS;
222 case MMS_ALL_ID:
223 case MMS_INBOX_ID:
224 case MMS_SENT_ID:
225 case MMS_DRAFTS_ID:
226 case MMS_OUTBOX_ID:
227 return VND_ANDROID_MMS;
228 case MMS_PART_ID: {
229 Cursor cursor = mOpenHelper.getReadableDatabase().query(
230 TABLE_PART, new String[] { Part.CONTENT_TYPE },
231 Part._ID + " = ?", new String[] { uri.getLastPathSegment() },
232 null, null, null);
233 if (cursor != null) {
234 try {
235 if ((cursor.getCount() == 1) && cursor.moveToFirst()) {
236 return cursor.getString(0);
237 } else {
238 Log.e(TAG, "cursor.count() != 1: " + uri);
239 }
240 } finally {
241 cursor.close();
242 }
243 } else {
244 Log.e(TAG, "cursor == null: " + uri);
245 }
246 return "*/*";
247 }
248 case MMS_ALL_PART:
249 case MMS_MSG_PART:
250 case MMS_MSG_ADDR:
251 default:
252 return "*/*";
253 }
254 }
255
256 @Override
257 public Uri insert(Uri uri, ContentValues values) {
258 int msgBox = Mms.MESSAGE_BOX_ALL;
259 boolean notify = true;
260
261 int match = sURLMatcher.match(uri);
262 if (LOCAL_LOGV) {
263 Log.v(TAG, "Insert uri=" + uri + ", match=" + match);
264 }
265
266 String table = TABLE_PDU;
267 switch (match) {
268 case MMS_ALL:
269 Object msgBoxObj = values.getAsInteger(Mms.MESSAGE_BOX);
270 if (msgBoxObj != null) {
271 msgBox = (Integer) msgBoxObj;
272 }
273 else {
274 // default to inbox
275 msgBox = Mms.MESSAGE_BOX_INBOX;
276 }
277 break;
278 case MMS_INBOX:
279 msgBox = Mms.MESSAGE_BOX_INBOX;
280 break;
281 case MMS_SENT:
282 msgBox = Mms.MESSAGE_BOX_SENT;
283 break;
284 case MMS_DRAFTS:
285 msgBox = Mms.MESSAGE_BOX_DRAFTS;
286 break;
287 case MMS_OUTBOX:
288 msgBox = Mms.MESSAGE_BOX_OUTBOX;
289 break;
290 case MMS_MSG_PART:
291 notify = false;
292 table = TABLE_PART;
293 break;
294 case MMS_MSG_ADDR:
295 notify = false;
296 table = TABLE_ADDR;
297 break;
298 case MMS_SENDING_RATE:
299 notify = false;
300 table = TABLE_RATE;
301 break;
302 case MMS_DRM_STORAGE:
303 notify = false;
304 table = TABLE_DRM;
305 break;
306 default:
307 Log.e(TAG, "Invalid request: " + uri);
308 return null;
309 }
310
311 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
312 ContentValues finalValues;
313 Uri res = Mms.CONTENT_URI;
314 long rowId;
315
316 if (table.equals(TABLE_PDU)) {
317 boolean addDate = !values.containsKey(Mms.DATE);
318 boolean addMsgBox = !values.containsKey(Mms.MESSAGE_BOX);
319
320 // Filter keys we don't support yet.
321 filterUnsupportedKeys(values);
322
323 // TODO: Should initialValues be validated, e.g. if it
324 // missed some significant keys?
325 finalValues = new ContentValues(values);
326
327 long timeInMillis = System.currentTimeMillis();
328
329 if (addDate) {
330 finalValues.put(Mms.DATE, timeInMillis / 1000L);
331 }
332
333 if (addMsgBox && (msgBox != Mms.MESSAGE_BOX_ALL)) {
334 finalValues.put(Mms.MESSAGE_BOX, msgBox);
335 }
336
337 if (msgBox != Mms.MESSAGE_BOX_INBOX) {
338 // Mark all non-inbox messages read.
339 finalValues.put(Mms.READ, 1);
340 }
341
342 if ((rowId = db.insert(table, null, finalValues)) <= 0) {
343 Log.e(TAG, "MmsProvider.insert: failed! " + finalValues);
344 return null;
345 }
346
347 res = Uri.parse(res + "/" + rowId);
348
349 } else if (table.equals(TABLE_ADDR)) {
350 finalValues = new ContentValues(values);
351 finalValues.put(Addr.MSG_ID, uri.getPathSegments().get(0));
352
353 if ((rowId = db.insert(table, null, finalValues)) <= 0) {
354 Log.e(TAG, "Failed to insert address: " + finalValues);
355 return null;
356 }
357
358 res = Uri.parse(res + "/addr/" + rowId);
359 } else if (table.equals(TABLE_PART)) {
360 finalValues = new ContentValues(values);
361
362 if (match == MMS_MSG_PART) {
363 finalValues.put(Part.MSG_ID, uri.getPathSegments().get(0));
364 }
365
366 // Generate the '_data' field of the part with default
367 // permission settings.
368 String path = getContext().getDir("parts", 0).getPath()
369 + "/PART_" + System.currentTimeMillis();
370
371 finalValues.put(Part._DATA, path);
372
373 File partFile = new File(path);
374 if (!partFile.exists()) {
375 try {
376 if (!partFile.createNewFile()) {
377 throw new IllegalStateException(
378 "Unable to create new partFile: " + path);
379 }
380 } catch (IOException e) {
381 Log.e(TAG, "createNewFile", e);
382 throw new IllegalStateException(
383 "Unable to create new partFile: " + path);
384 }
385 }
386
387 if ((rowId = db.insert(table, null, finalValues)) <= 0) {
388 Log.e(TAG, "MmsProvider.insert: failed! " + finalValues);
389 return null;
390 }
391
392 res = Uri.parse(res + "/part/" + rowId);
393 } else if (table.equals(TABLE_RATE)) {
394 long now = values.getAsLong(Rate.SENT_TIME);
395 long oneHourAgo = now - 1000 * 60 * 60;
396 // Delete all unused rows (time earlier than one hour ago).
397 db.delete(table, Rate.SENT_TIME + "<=" + oneHourAgo, null);
398 db.insert(table, null, values);
399 } else if (table.equals(TABLE_DRM)) {
400 String path = getContext().getDir("parts", 0).getPath()
401 + "/PART_" + System.currentTimeMillis();
402 finalValues = new ContentValues(1);
403 finalValues.put("_data", path);
404
405 File partFile = new File(path);
406 if (!partFile.exists()) {
407 try {
408 if (!partFile.createNewFile()) {
409 throw new IllegalStateException(
410 "Unable to create new file: " + path);
411 }
412 } catch (IOException e) {
413 Log.e(TAG, "createNewFile", e);
414 throw new IllegalStateException(
415 "Unable to create new file: " + path);
416 }
417 }
418
419 if ((rowId = db.insert(table, null, finalValues)) <= 0) {
420 Log.e(TAG, "MmsProvider.insert: failed! " + finalValues);
421 return null;
422 }
423 res = Uri.parse(res + "/drm/" + rowId);
424 } else {
425 throw new AssertionError("Unknown table type: " + table);
426 }
427
428 if (notify) {
429 notifyChange();
430 }
431 return res;
432 }
433
434 private int getMessageBoxByMatch(int match) {
435 switch (match) {
436 case MMS_INBOX_ID:
437 case MMS_INBOX:
438 return Mms.MESSAGE_BOX_INBOX;
439 case MMS_SENT_ID:
440 case MMS_SENT:
441 return Mms.MESSAGE_BOX_SENT;
442 case MMS_DRAFTS_ID:
443 case MMS_DRAFTS:
444 return Mms.MESSAGE_BOX_DRAFTS;
445 case MMS_OUTBOX_ID:
446 case MMS_OUTBOX:
447 return Mms.MESSAGE_BOX_OUTBOX;
448 default:
449 throw new IllegalArgumentException("bad Arg: " + match);
450 }
451 }
452
453 @Override
454 public int delete(Uri uri, String selection,
455 String[] selectionArgs) {
456 int match = sURLMatcher.match(uri);
457 if (LOCAL_LOGV) {
458 Log.v(TAG, "Delete uri=" + uri + ", match=" + match);
459 }
460
461 String table, extraSelection = null;
462 boolean notify = false;
463
464 switch (match) {
465 case MMS_ALL_ID:
466 case MMS_INBOX_ID:
467 case MMS_SENT_ID:
468 case MMS_DRAFTS_ID:
469 case MMS_OUTBOX_ID:
470 notify = true;
471 table = TABLE_PDU;
472 extraSelection = Mms._ID + "=" + uri.getLastPathSegment();
473 break;
474 case MMS_ALL:
475 case MMS_INBOX:
476 case MMS_SENT:
477 case MMS_DRAFTS:
478 case MMS_OUTBOX:
479 notify = true;
480 table = TABLE_PDU;
481 if (match != MMS_ALL) {
482 int msgBox = getMessageBoxByMatch(match);
483 extraSelection = Mms.MESSAGE_BOX + "=" + msgBox;
484 }
485 break;
486 case MMS_ALL_PART:
487 table = TABLE_PART;
488 break;
489 case MMS_MSG_PART:
490 table = TABLE_PART;
491 extraSelection = Part.MSG_ID + "=" + uri.getPathSegments().get(0);
492 break;
493 case MMS_PART_ID:
494 table = TABLE_PART;
495 extraSelection = Part._ID + "=" + uri.getPathSegments().get(1);
496 break;
497 case MMS_MSG_ADDR:
498 table = TABLE_ADDR;
499 extraSelection = Addr.MSG_ID + "=" + uri.getPathSegments().get(0);
500 break;
501 case MMS_DRM_STORAGE:
502 table = TABLE_DRM;
503 break;
504 default:
505 Log.w(TAG, "No match for URI '" + uri + "'");
506 return 0;
507 }
508
509 String finalSelection = concatSelections(selection, extraSelection);
510 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
511 int deletedRows = 0;
512
513 if (TABLE_PDU.equals(table)) {
514 deletedRows = deleteMessages(getContext(), db, finalSelection,
515 selectionArgs, uri);
516 } else if (TABLE_PART.equals(table)) {
517 deletedRows = deleteParts(db, finalSelection, selectionArgs);
518 } else if (TABLE_DRM.equals(table)) {
519 deletedRows = deleteTempDrmData(db, finalSelection, selectionArgs);
520 } else {
521 deletedRows = db.delete(table, finalSelection, selectionArgs);
522 }
523
524 if ((deletedRows > 0) && notify) {
525 notifyChange();
526 }
527 return deletedRows;
528 }
529
530 static int deleteMessages(Context context, SQLiteDatabase db,
531 String selection, String[] selectionArgs, Uri uri) {
532 Cursor cursor = db.query(TABLE_PDU, new String[] { Mms._ID },
533 selection, selectionArgs, null, null, null);
534 if (cursor == null) {
535 return 0;
536 }
537
538 try {
539 if (cursor.getCount() == 0) {
540 return 0;
541 }
542
543 while (cursor.moveToNext()) {
544 deleteParts(db, Part.MSG_ID + " = ?",
545 new String[] { String.valueOf(cursor.getLong(0)) });
546 }
547 } finally {
548 cursor.close();
549 }
550
551 int count = db.delete(TABLE_PDU, selection, selectionArgs);
552 if (count > 0) {
553 Intent intent = new Intent(Mms.Intents.CONTENT_CHANGED_ACTION);
554 intent.putExtra(Mms.Intents.DELETED_CONTENTS, uri);
555 if (LOCAL_LOGV) {
556 Log.v(TAG, "Broadcasting intent: " + intent);
557 }
558 context.sendBroadcast(intent);
559 }
560 return count;
561 }
562
563 private static int deleteParts(SQLiteDatabase db, String selection,
564 String[] selectionArgs) {
565 return deleteDataRows(db, TABLE_PART, selection, selectionArgs);
566 }
567
568 private static int deleteTempDrmData(SQLiteDatabase db, String selection,
569 String[] selectionArgs) {
570 return deleteDataRows(db, TABLE_DRM, selection, selectionArgs);
571 }
572
573 private static int deleteDataRows(SQLiteDatabase db, String table,
574 String selection, String[] selectionArgs) {
575 Cursor cursor = db.query(table, new String[] { "_data" },
576 selection, selectionArgs, null, null, null);
577 if (cursor == null) {
578 // FIXME: This might be an error, ignore it may cause
579 // unpredictable result.
580 return 0;
581 }
582
583 try {
584 if (cursor.getCount() == 0) {
585 return 0;
586 }
587
588 while (cursor.moveToNext()) {
589 try {
590 // Delete the associated files saved on file-system.
591 new File(cursor.getString(0)).delete();
592 } catch (Throwable ex) {
593 Log.e(TAG, ex.getMessage(), ex);
594 }
595 }
596 } finally {
597 cursor.close();
598 }
599
600 return db.delete(table, selection, selectionArgs);
601 }
602
603 @Override
604 public int update(Uri uri, ContentValues values,
605 String selection, String[] selectionArgs) {
606 int match = sURLMatcher.match(uri);
607 if (LOCAL_LOGV) {
608 Log.v(TAG, "Update uri=" + uri + ", match=" + match);
609 }
610
611 boolean notify = false;
612 String msgId = null;
613 String table;
614
615 switch (match) {
616 case MMS_ALL_ID:
617 case MMS_INBOX_ID:
618 case MMS_SENT_ID:
619 case MMS_DRAFTS_ID:
620 case MMS_OUTBOX_ID:
621 msgId = uri.getLastPathSegment();
622 // fall-through
623 case MMS_ALL:
624 case MMS_INBOX:
625 case MMS_SENT:
626 case MMS_DRAFTS:
627 case MMS_OUTBOX:
628 notify = true;
629 table = TABLE_PDU;
630 break;
631 case MMS_MSG_PART:
632 case MMS_PART_ID:
633 table = TABLE_PART;
634 break;
635 default:
636 Log.w(TAG, "Update operation for '" + uri + "' not implemented.");
637 return 0;
638 }
639
640 String extraSelection = null;
641 ContentValues finalValues;
642 if (table.equals(TABLE_PDU)) {
643 // Filter keys that we don't support yet.
644 filterUnsupportedKeys(values);
645 finalValues = new ContentValues(values);
646
647 if (msgId != null) {
648 extraSelection = Mms._ID + "=" + msgId;
649 }
650 } else if (table.equals(TABLE_PART)) {
651 finalValues = new ContentValues(values);
652
653 switch (match) {
654 case MMS_MSG_PART:
655 extraSelection = Part.MSG_ID + "=" + uri.getPathSegments().get(0);
656 break;
657 case MMS_PART_ID:
658 extraSelection = Part._ID + "=" + uri.getPathSegments().get(1);
659 break;
660 default:
661 break;
662 }
663 } else {
664 return 0;
665 }
666
667 String finalSelection = concatSelections(selection, extraSelection);
668 SQLiteDatabase db = mOpenHelper.getWritableDatabase();
669 int count = db.update(table, finalValues, finalSelection, selectionArgs);
670 if (notify && (count > 0)) {
671 notifyChange();
672 }
673 return count;
674 }
675
676 @Override
677 public ParcelFileDescriptor openFile(Uri uri, String mode)
678 throws FileNotFoundException {
679 return openFileHelper(uri, mode);
680 }
681
682 private void filterUnsupportedKeys(ContentValues values) {
683 // Some columns are unsupported. They should therefore
684 // neither be inserted nor updated. Filter them out.
685 values.remove(Mms.DELIVERY_TIME_TOKEN);
686 values.remove(Mms.SENDER_VISIBILITY);
687 values.remove(Mms.REPLY_CHARGING);
688 values.remove(Mms.REPLY_CHARGING_DEADLINE_TOKEN);
689 values.remove(Mms.REPLY_CHARGING_DEADLINE);
690 values.remove(Mms.REPLY_CHARGING_ID);
691 values.remove(Mms.REPLY_CHARGING_SIZE);
692 values.remove(Mms.PREVIOUSLY_SENT_BY);
693 values.remove(Mms.PREVIOUSLY_SENT_DATE);
694 values.remove(Mms.STORE);
695 values.remove(Mms.MM_STATE);
696 values.remove(Mms.MM_FLAGS_TOKEN);
697 values.remove(Mms.MM_FLAGS);
698 values.remove(Mms.STORE_STATUS);
699 values.remove(Mms.STORE_STATUS_TEXT);
700 values.remove(Mms.STORED);
701 values.remove(Mms.TOTALS);
702 values.remove(Mms.MBOX_TOTALS);
703 values.remove(Mms.MBOX_TOTALS_TOKEN);
704 values.remove(Mms.QUOTAS);
705 values.remove(Mms.MBOX_QUOTAS);
706 values.remove(Mms.MBOX_QUOTAS_TOKEN);
707 values.remove(Mms.MESSAGE_COUNT);
708 values.remove(Mms.START);
709 values.remove(Mms.DISTRIBUTION_INDICATOR);
710 values.remove(Mms.ELEMENT_DESCRIPTOR);
711 values.remove(Mms.LIMIT);
712 values.remove(Mms.RECOMMENDED_RETRIEVAL_MODE);
713 values.remove(Mms.RECOMMENDED_RETRIEVAL_MODE_TEXT);
714 values.remove(Mms.STATUS_TEXT);
715 values.remove(Mms.APPLIC_ID);
716 values.remove(Mms.REPLY_APPLIC_ID);
717 values.remove(Mms.AUX_APPLIC_ID);
718 values.remove(Mms.DRM_CONTENT);
719 values.remove(Mms.ADAPTATION_ALLOWED);
720 values.remove(Mms.REPLACE_ID);
721 values.remove(Mms.CANCEL_ID);
722 values.remove(Mms.CANCEL_STATUS);
723
724 // Keys shouldn't be inserted or updated.
725 values.remove(Mms._ID);
726 }
727
728 private void notifyChange() {
729 getContext().getContentResolver().notifyChange(
730 MmsSms.CONTENT_URI, null);
731 }
732
733 private final static String TAG = "MmsProvider";
734 private final static String VND_ANDROID_MMS = "vnd.android/mms";
735 private final static String VND_ANDROID_DIR_MMS = "vnd.android-dir/mms";
736 private final static boolean DEBUG = false;
737 private final static boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
738
739 private static final int MMS_ALL = 0;
740 private static final int MMS_ALL_ID = 1;
741 private static final int MMS_INBOX = 2;
742 private static final int MMS_INBOX_ID = 3;
743 private static final int MMS_SENT = 4;
744 private static final int MMS_SENT_ID = 5;
745 private static final int MMS_DRAFTS = 6;
746 private static final int MMS_DRAFTS_ID = 7;
747 private static final int MMS_OUTBOX = 8;
748 private static final int MMS_OUTBOX_ID = 9;
749 private static final int MMS_ALL_PART = 10;
750 private static final int MMS_MSG_PART = 11;
751 private static final int MMS_PART_ID = 12;
752 private static final int MMS_MSG_ADDR = 13;
753 private static final int MMS_SENDING_RATE = 14;
754 private static final int MMS_REPORT_STATUS = 15;
755 private static final int MMS_REPORT_REQUEST = 16;
756 private static final int MMS_DRM_STORAGE = 17;
757 private static final int MMS_DRM_STORAGE_ID = 18;
758
759 private static final UriMatcher
760 sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);
761
762 static {
763 sURLMatcher.addURI("mms", null, MMS_ALL);
764 sURLMatcher.addURI("mms", "#", MMS_ALL_ID);
765 sURLMatcher.addURI("mms", "inbox", MMS_INBOX);
766 sURLMatcher.addURI("mms", "inbox/#", MMS_INBOX_ID);
767 sURLMatcher.addURI("mms", "sent", MMS_SENT);
768 sURLMatcher.addURI("mms", "sent/#", MMS_SENT_ID);
769 sURLMatcher.addURI("mms", "drafts", MMS_DRAFTS);
770 sURLMatcher.addURI("mms", "drafts/#", MMS_DRAFTS_ID);
771 sURLMatcher.addURI("mms", "outbox", MMS_OUTBOX);
772 sURLMatcher.addURI("mms", "outbox/#", MMS_OUTBOX_ID);
773 sURLMatcher.addURI("mms", "part", MMS_ALL_PART);
774 sURLMatcher.addURI("mms", "#/part", MMS_MSG_PART);
775 sURLMatcher.addURI("mms", "part/#", MMS_PART_ID);
776 sURLMatcher.addURI("mms", "#/addr", MMS_MSG_ADDR);
777 sURLMatcher.addURI("mms", "rate", MMS_SENDING_RATE);
778 sURLMatcher.addURI("mms", "report-status/#", MMS_REPORT_STATUS);
779 sURLMatcher.addURI("mms", "report-request/#", MMS_REPORT_REQUEST);
780 sURLMatcher.addURI("mms", "drm", MMS_DRM_STORAGE);
781 sURLMatcher.addURI("mms", "drm/#", MMS_DRM_STORAGE_ID);
782 }
783
784 private SQLiteOpenHelper mOpenHelper;
785
786 private static String concatSelections(String selection1, String selection2) {
787 if (TextUtils.isEmpty(selection1)) {
788 return selection2;
789 } else if (TextUtils.isEmpty(selection2)) {
790 return selection1;
791 } else {
792 return selection1 + " AND " + selection2;
793 }
794 }
795}
796