auto import from //depot/cupcake/@135843
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 2b16664..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := user development
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES :=
-
-LOCAL_PACKAGE_NAME := TelephonyProvider
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
deleted file mode 100644
index dfbf918..0000000
--- a/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.providers.telephony"
- android:sharedUserId="android.uid.phone"
->
-
- <application android:process="com.android.phone"
- android:allowClearUserData="false"
- android:label="Dialer Storage"
- android:icon="@drawable/ic_launcher_phone">
- <provider android:name="TelephonyProvider" android:authorities="telephony" android:multiprocess="true" />
- <provider android:name="SmsProvider" android:authorities="sms" android:multiprocess="true"
- android:readPermission="android.permission.READ_SMS"
- android:writePermission="android.permission.WRITE_SMS" />
- <provider android:name="MmsProvider" android:authorities="mms" android:multiprocess="true"
- android:readPermission="android.permission.READ_SMS"
- android:writePermission="android.permission.WRITE_SMS" />
- <provider android:name="MmsSmsProvider" android:authorities="mms-sms" android:multiprocess="true"
- android:readPermission="android.permission.READ_SMS"
- android:writePermission="android.permission.WRITE_SMS" />
- </application>
-</manifest>
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/res/drawable/ic_launcher_phone.png b/res/drawable/ic_launcher_phone.png
deleted file mode 100644
index 4e613ec..0000000
--- a/res/drawable/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/src/com/android/providers/telephony/MmsProvider.java b/src/com/android/providers/telephony/MmsProvider.java
deleted file mode 100644
index 37d1787..0000000
--- a/src/com/android/providers/telephony/MmsProvider.java
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.providers.telephony;
-
-import com.google.android.mms.pdu.PduHeaders;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.provider.BaseColumns;
-import android.provider.Telephony.Mms;
-import android.provider.Telephony.MmsSms;
-import android.provider.Telephony.Mms.Addr;
-import android.provider.Telephony.Mms.Part;
-import android.provider.Telephony.Mms.Rate;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-/**
- * The class to provide base facility to access MMS related content,
- * which is stored in a SQLite database and in the file system.
- */
-public class MmsProvider extends ContentProvider {
- static final String TABLE_PDU = "pdu";
- static final String TABLE_ADDR = "addr";
- static final String TABLE_PART = "part";
- static final String TABLE_RATE = "rate";
- static final String TABLE_DRM = "drm";
-
- @Override
- public boolean onCreate() {
- mOpenHelper = MmsSmsDatabaseHelper.getInstance(getContext());
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
- // Generate the body of the query.
- int match = sURLMatcher.match(uri);
- if (LOCAL_LOGV) {
- Log.v(TAG, "Query uri=" + uri + ", match=" + match);
- }
-
- switch (match) {
- case MMS_ALL:
- constructQueryForBox(qb, Mms.MESSAGE_BOX_ALL);
- break;
- case MMS_INBOX:
- constructQueryForBox(qb, Mms.MESSAGE_BOX_INBOX);
- break;
- case MMS_SENT:
- constructQueryForBox(qb, Mms.MESSAGE_BOX_SENT);
- break;
- case MMS_DRAFTS:
- constructQueryForBox(qb, Mms.MESSAGE_BOX_DRAFTS);
- break;
- case MMS_OUTBOX:
- constructQueryForBox(qb, Mms.MESSAGE_BOX_OUTBOX);
- break;
- case MMS_ALL_ID:
- qb.setTables(TABLE_PDU);
- qb.appendWhere(Mms._ID + "=" + uri.getPathSegments().get(0));
- break;
- case MMS_INBOX_ID:
- case MMS_SENT_ID:
- case MMS_DRAFTS_ID:
- case MMS_OUTBOX_ID:
- qb.setTables(TABLE_PDU);
- qb.appendWhere(Mms._ID + "=" + uri.getPathSegments().get(1));
- qb.appendWhere(" AND " + Mms.MESSAGE_BOX + "="
- + getMessageBoxByMatch(match));
- break;
- case MMS_ALL_PART:
- qb.setTables(TABLE_PART);
- break;
- case MMS_MSG_PART:
- qb.setTables(TABLE_PART);
- qb.appendWhere(Part.MSG_ID + "=" + uri.getPathSegments().get(0));
- break;
- case MMS_PART_ID:
- qb.setTables(TABLE_PART);
- qb.appendWhere(Part._ID + "=" + uri.getPathSegments().get(1));
- break;
- case MMS_MSG_ADDR:
- qb.setTables(TABLE_ADDR);
- qb.appendWhere(Addr.MSG_ID + "=" + uri.getPathSegments().get(0));
- break;
- case MMS_REPORT_STATUS:
- /*
- SELECT DISTINCT address,
- T.delivery_status AS delivery_status,
- T.read_status AS read_status
- FROM addr
- INNER JOIN (SELECT P1._id AS id1, P2._id AS id2, P3._id AS id3,
- ifnull(P2.st, 0) AS delivery_status,
- ifnull(P3.read_status, 0) AS read_status
- FROM pdu P1
- INNER JOIN pdu P2
- ON P1.m_id = P2.m_id AND P2.m_type = 134
- LEFT JOIN pdu P3
- ON P1.m_id = P3.m_id AND P3.m_type = 136
- UNION
- SELECT P1._id AS id1, P2._id AS id2, P3._id AS id3,
- ifnull(P2.st, 0) AS delivery_status,
- ifnull(P3.read_status, 0) AS read_status
- FROM pdu P1
- INNER JOIN pdu P3
- ON P1.m_id = P3.m_id AND P3.m_type = 136
- LEFT JOIN pdu P2
- ON P1.m_id = P2.m_id AND P2.m_type = 134) T
- ON (msg_id = id2 AND type = 151)
- OR (msg_id = id3 AND type = 137)
- WHERE T.id1 = ?;
- */
- qb.setTables("addr INNER JOIN (SELECT P1._id AS id1, P2._id" +
- " AS id2, P3._id AS id3, ifnull(P2.st, 0) AS" +
- " delivery_status, ifnull(P3.read_status, 0) AS" +
- " read_status FROM pdu P1 INNER JOIN pdu P2 ON" +
- " P1.m_id=P2.m_id AND P2.m_type=134 LEFT JOIN" +
- " pdu P3 ON P1.m_id=P3.m_id AND P3.m_type=136" +
- " UNION SELECT P1._id AS id1, P2._id AS id2, P3._id" +
- " AS id3, ifnull(P2.st, 0) AS delivery_status," +
- " ifnull(P3.read_status, 0) AS read_status FROM" +
- " pdu P1 INNER JOIN pdu P3 ON P1.m_id=P3.m_id AND" +
- " P3.m_type=136 LEFT JOIN pdu P2 ON P1.m_id=P2.m_id" +
- " AND P2.m_type=134) T ON (msg_id=id2 AND type=151)" +
- " OR (msg_id=id3 AND type=137)");
- qb.appendWhere("T.id1 = " + uri.getLastPathSegment());
- qb.setDistinct(true);
- break;
- case MMS_REPORT_REQUEST:
- /*
- SELECT address, d_rpt, rr
- FROM addr join pdu on pdu._id = addr.msg_id
- WHERE pdu._id = messageId AND addr.type = 151
- */
- qb.setTables(TABLE_ADDR + " join " +
- TABLE_PDU + " on pdu._id = addr.msg_id");
- qb.appendWhere("pdu._id = " + uri.getLastPathSegment());
- qb.appendWhere(" AND " + "addr.type = " + PduHeaders.TO);
- break;
- case MMS_SENDING_RATE:
- qb.setTables(TABLE_RATE);
- break;
- case MMS_DRM_STORAGE_ID:
- qb.setTables(TABLE_DRM);
- qb.appendWhere(BaseColumns._ID + "=" + uri.getLastPathSegment());
- break;
- default:
- Log.e(TAG, "Invalid request: " + uri);
- return null;
- }
-
- String finalSortOrder = null;
- if (TextUtils.isEmpty(sortOrder)) {
- if (qb.getTables().equals(TABLE_PDU)) {
- finalSortOrder = Mms.DATE + " DESC";
- } else if (qb.getTables().equals(TABLE_PART)) {
- finalSortOrder = Part.SEQ;
- }
- } else {
- finalSortOrder = sortOrder;
- }
-
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- Cursor ret = qb.query(db, projection, selection,
- selectionArgs, null, null, finalSortOrder);
-
- // TODO: Does this need to be a URI for this provider.
- ret.setNotificationUri(getContext().getContentResolver(), uri);
- return ret;
- }
-
- private void constructQueryForBox(SQLiteQueryBuilder qb, int msgBox) {
- qb.setTables(TABLE_PDU);
-
- if (msgBox != Mms.MESSAGE_BOX_ALL) {
- qb.appendWhere(Mms.MESSAGE_BOX + "=" + msgBox);
- }
- }
-
- @Override
- public String getType(Uri uri) {
- int match = sURLMatcher.match(uri);
- switch (match) {
- case MMS_ALL:
- case MMS_INBOX:
- case MMS_SENT:
- case MMS_DRAFTS:
- case MMS_OUTBOX:
- return VND_ANDROID_DIR_MMS;
- case MMS_ALL_ID:
- case MMS_INBOX_ID:
- case MMS_SENT_ID:
- case MMS_DRAFTS_ID:
- case MMS_OUTBOX_ID:
- return VND_ANDROID_MMS;
- case MMS_PART_ID: {
- Cursor cursor = mOpenHelper.getReadableDatabase().query(
- TABLE_PART, new String[] { Part.CONTENT_TYPE },
- Part._ID + " = ?", new String[] { uri.getLastPathSegment() },
- null, null, null);
- if (cursor != null) {
- try {
- if ((cursor.getCount() == 1) && cursor.moveToFirst()) {
- return cursor.getString(0);
- } else {
- Log.e(TAG, "cursor.count() != 1: " + uri);
- }
- } finally {
- cursor.close();
- }
- } else {
- Log.e(TAG, "cursor == null: " + uri);
- }
- return "*/*";
- }
- case MMS_ALL_PART:
- case MMS_MSG_PART:
- case MMS_MSG_ADDR:
- default:
- return "*/*";
- }
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- int msgBox = Mms.MESSAGE_BOX_ALL;
- boolean notify = true;
-
- int match = sURLMatcher.match(uri);
- if (LOCAL_LOGV) {
- Log.v(TAG, "Insert uri=" + uri + ", match=" + match);
- }
-
- String table = TABLE_PDU;
- switch (match) {
- case MMS_ALL:
- Object msgBoxObj = values.getAsInteger(Mms.MESSAGE_BOX);
- if (msgBoxObj != null) {
- msgBox = (Integer) msgBoxObj;
- }
- else {
- // default to inbox
- msgBox = Mms.MESSAGE_BOX_INBOX;
- }
- break;
- case MMS_INBOX:
- msgBox = Mms.MESSAGE_BOX_INBOX;
- break;
- case MMS_SENT:
- msgBox = Mms.MESSAGE_BOX_SENT;
- break;
- case MMS_DRAFTS:
- msgBox = Mms.MESSAGE_BOX_DRAFTS;
- break;
- case MMS_OUTBOX:
- msgBox = Mms.MESSAGE_BOX_OUTBOX;
- break;
- case MMS_MSG_PART:
- notify = false;
- table = TABLE_PART;
- break;
- case MMS_MSG_ADDR:
- notify = false;
- table = TABLE_ADDR;
- break;
- case MMS_SENDING_RATE:
- notify = false;
- table = TABLE_RATE;
- break;
- case MMS_DRM_STORAGE:
- notify = false;
- table = TABLE_DRM;
- break;
- default:
- Log.e(TAG, "Invalid request: " + uri);
- return null;
- }
-
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- ContentValues finalValues;
- Uri res = Mms.CONTENT_URI;
- long rowId;
-
- if (table.equals(TABLE_PDU)) {
- boolean addDate = !values.containsKey(Mms.DATE);
- boolean addMsgBox = !values.containsKey(Mms.MESSAGE_BOX);
-
- // Filter keys we don't support yet.
- filterUnsupportedKeys(values);
-
- // TODO: Should initialValues be validated, e.g. if it
- // missed some significant keys?
- finalValues = new ContentValues(values);
-
- long timeInMillis = System.currentTimeMillis();
-
- if (addDate) {
- finalValues.put(Mms.DATE, timeInMillis / 1000L);
- }
-
- if (addMsgBox && (msgBox != Mms.MESSAGE_BOX_ALL)) {
- finalValues.put(Mms.MESSAGE_BOX, msgBox);
- }
-
- if (msgBox != Mms.MESSAGE_BOX_INBOX) {
- // Mark all non-inbox messages read.
- finalValues.put(Mms.READ, 1);
- }
-
- if ((rowId = db.insert(table, null, finalValues)) <= 0) {
- Log.e(TAG, "MmsProvider.insert: failed! " + finalValues);
- return null;
- }
-
- res = Uri.parse(res + "/" + rowId);
-
- } else if (table.equals(TABLE_ADDR)) {
- finalValues = new ContentValues(values);
- finalValues.put(Addr.MSG_ID, uri.getPathSegments().get(0));
-
- if ((rowId = db.insert(table, null, finalValues)) <= 0) {
- Log.e(TAG, "Failed to insert address: " + finalValues);
- return null;
- }
-
- res = Uri.parse(res + "/addr/" + rowId);
- } else if (table.equals(TABLE_PART)) {
- finalValues = new ContentValues(values);
-
- if (match == MMS_MSG_PART) {
- finalValues.put(Part.MSG_ID, uri.getPathSegments().get(0));
- }
-
- // Generate the '_data' field of the part with default
- // permission settings.
- String path = getContext().getDir("parts", 0).getPath()
- + "/PART_" + System.currentTimeMillis();
-
- finalValues.put(Part._DATA, path);
-
- File partFile = new File(path);
- if (!partFile.exists()) {
- try {
- if (!partFile.createNewFile()) {
- throw new IllegalStateException(
- "Unable to create new partFile: " + path);
- }
- } catch (IOException e) {
- Log.e(TAG, "createNewFile", e);
- throw new IllegalStateException(
- "Unable to create new partFile: " + path);
- }
- }
-
- if ((rowId = db.insert(table, null, finalValues)) <= 0) {
- Log.e(TAG, "MmsProvider.insert: failed! " + finalValues);
- return null;
- }
-
- res = Uri.parse(res + "/part/" + rowId);
- } else if (table.equals(TABLE_RATE)) {
- long now = values.getAsLong(Rate.SENT_TIME);
- long oneHourAgo = now - 1000 * 60 * 60;
- // Delete all unused rows (time earlier than one hour ago).
- db.delete(table, Rate.SENT_TIME + "<=" + oneHourAgo, null);
- db.insert(table, null, values);
- } else if (table.equals(TABLE_DRM)) {
- String path = getContext().getDir("parts", 0).getPath()
- + "/PART_" + System.currentTimeMillis();
- finalValues = new ContentValues(1);
- finalValues.put("_data", path);
-
- File partFile = new File(path);
- if (!partFile.exists()) {
- try {
- if (!partFile.createNewFile()) {
- throw new IllegalStateException(
- "Unable to create new file: " + path);
- }
- } catch (IOException e) {
- Log.e(TAG, "createNewFile", e);
- throw new IllegalStateException(
- "Unable to create new file: " + path);
- }
- }
-
- if ((rowId = db.insert(table, null, finalValues)) <= 0) {
- Log.e(TAG, "MmsProvider.insert: failed! " + finalValues);
- return null;
- }
- res = Uri.parse(res + "/drm/" + rowId);
- } else {
- throw new AssertionError("Unknown table type: " + table);
- }
-
- if (notify) {
- notifyChange();
- }
- return res;
- }
-
- private int getMessageBoxByMatch(int match) {
- switch (match) {
- case MMS_INBOX_ID:
- case MMS_INBOX:
- return Mms.MESSAGE_BOX_INBOX;
- case MMS_SENT_ID:
- case MMS_SENT:
- return Mms.MESSAGE_BOX_SENT;
- case MMS_DRAFTS_ID:
- case MMS_DRAFTS:
- return Mms.MESSAGE_BOX_DRAFTS;
- case MMS_OUTBOX_ID:
- case MMS_OUTBOX:
- return Mms.MESSAGE_BOX_OUTBOX;
- default:
- throw new IllegalArgumentException("bad Arg: " + match);
- }
- }
-
- @Override
- public int delete(Uri uri, String selection,
- String[] selectionArgs) {
- int match = sURLMatcher.match(uri);
- if (LOCAL_LOGV) {
- Log.v(TAG, "Delete uri=" + uri + ", match=" + match);
- }
-
- String table, extraSelection = null;
- boolean notify = false;
-
- switch (match) {
- case MMS_ALL_ID:
- case MMS_INBOX_ID:
- case MMS_SENT_ID:
- case MMS_DRAFTS_ID:
- case MMS_OUTBOX_ID:
- notify = true;
- table = TABLE_PDU;
- extraSelection = Mms._ID + "=" + uri.getLastPathSegment();
- break;
- case MMS_ALL:
- case MMS_INBOX:
- case MMS_SENT:
- case MMS_DRAFTS:
- case MMS_OUTBOX:
- notify = true;
- table = TABLE_PDU;
- if (match != MMS_ALL) {
- int msgBox = getMessageBoxByMatch(match);
- extraSelection = Mms.MESSAGE_BOX + "=" + msgBox;
- }
- break;
- case MMS_ALL_PART:
- table = TABLE_PART;
- break;
- case MMS_MSG_PART:
- table = TABLE_PART;
- extraSelection = Part.MSG_ID + "=" + uri.getPathSegments().get(0);
- break;
- case MMS_PART_ID:
- table = TABLE_PART;
- extraSelection = Part._ID + "=" + uri.getPathSegments().get(1);
- break;
- case MMS_MSG_ADDR:
- table = TABLE_ADDR;
- extraSelection = Addr.MSG_ID + "=" + uri.getPathSegments().get(0);
- break;
- case MMS_DRM_STORAGE:
- table = TABLE_DRM;
- break;
- default:
- Log.w(TAG, "No match for URI '" + uri + "'");
- return 0;
- }
-
- String finalSelection = concatSelections(selection, extraSelection);
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int deletedRows = 0;
-
- if (TABLE_PDU.equals(table)) {
- deletedRows = deleteMessages(getContext(), db, finalSelection,
- selectionArgs, uri);
- } else if (TABLE_PART.equals(table)) {
- deletedRows = deleteParts(db, finalSelection, selectionArgs);
- } else if (TABLE_DRM.equals(table)) {
- deletedRows = deleteTempDrmData(db, finalSelection, selectionArgs);
- } else {
- deletedRows = db.delete(table, finalSelection, selectionArgs);
- }
-
- if ((deletedRows > 0) && notify) {
- notifyChange();
- }
- return deletedRows;
- }
-
- static int deleteMessages(Context context, SQLiteDatabase db,
- String selection, String[] selectionArgs, Uri uri) {
- Cursor cursor = db.query(TABLE_PDU, new String[] { Mms._ID },
- selection, selectionArgs, null, null, null);
- if (cursor == null) {
- return 0;
- }
-
- try {
- if (cursor.getCount() == 0) {
- return 0;
- }
-
- while (cursor.moveToNext()) {
- deleteParts(db, Part.MSG_ID + " = ?",
- new String[] { String.valueOf(cursor.getLong(0)) });
- }
- } finally {
- cursor.close();
- }
-
- int count = db.delete(TABLE_PDU, selection, selectionArgs);
- if (count > 0) {
- Intent intent = new Intent(Mms.Intents.CONTENT_CHANGED_ACTION);
- intent.putExtra(Mms.Intents.DELETED_CONTENTS, uri);
- if (LOCAL_LOGV) {
- Log.v(TAG, "Broadcasting intent: " + intent);
- }
- context.sendBroadcast(intent);
- }
- return count;
- }
-
- private static int deleteParts(SQLiteDatabase db, String selection,
- String[] selectionArgs) {
- return deleteDataRows(db, TABLE_PART, selection, selectionArgs);
- }
-
- private static int deleteTempDrmData(SQLiteDatabase db, String selection,
- String[] selectionArgs) {
- return deleteDataRows(db, TABLE_DRM, selection, selectionArgs);
- }
-
- private static int deleteDataRows(SQLiteDatabase db, String table,
- String selection, String[] selectionArgs) {
- Cursor cursor = db.query(table, new String[] { "_data" },
- selection, selectionArgs, null, null, null);
- if (cursor == null) {
- // FIXME: This might be an error, ignore it may cause
- // unpredictable result.
- return 0;
- }
-
- try {
- if (cursor.getCount() == 0) {
- return 0;
- }
-
- while (cursor.moveToNext()) {
- try {
- // Delete the associated files saved on file-system.
- new File(cursor.getString(0)).delete();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- }
- }
- } finally {
- cursor.close();
- }
-
- return db.delete(table, selection, selectionArgs);
- }
-
- @Override
- public int update(Uri uri, ContentValues values,
- String selection, String[] selectionArgs) {
- int match = sURLMatcher.match(uri);
- if (LOCAL_LOGV) {
- Log.v(TAG, "Update uri=" + uri + ", match=" + match);
- }
-
- boolean notify = false;
- String msgId = null;
- String table;
-
- switch (match) {
- case MMS_ALL_ID:
- case MMS_INBOX_ID:
- case MMS_SENT_ID:
- case MMS_DRAFTS_ID:
- case MMS_OUTBOX_ID:
- msgId = uri.getLastPathSegment();
- // fall-through
- case MMS_ALL:
- case MMS_INBOX:
- case MMS_SENT:
- case MMS_DRAFTS:
- case MMS_OUTBOX:
- notify = true;
- table = TABLE_PDU;
- break;
- case MMS_MSG_PART:
- case MMS_PART_ID:
- table = TABLE_PART;
- break;
- default:
- Log.w(TAG, "Update operation for '" + uri + "' not implemented.");
- return 0;
- }
-
- String extraSelection = null;
- ContentValues finalValues;
- if (table.equals(TABLE_PDU)) {
- // Filter keys that we don't support yet.
- filterUnsupportedKeys(values);
- finalValues = new ContentValues(values);
-
- if (msgId != null) {
- extraSelection = Mms._ID + "=" + msgId;
- }
- } else if (table.equals(TABLE_PART)) {
- finalValues = new ContentValues(values);
-
- switch (match) {
- case MMS_MSG_PART:
- extraSelection = Part.MSG_ID + "=" + uri.getPathSegments().get(0);
- break;
- case MMS_PART_ID:
- extraSelection = Part._ID + "=" + uri.getPathSegments().get(1);
- break;
- default:
- break;
- }
- } else {
- return 0;
- }
-
- String finalSelection = concatSelections(selection, extraSelection);
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int count = db.update(table, finalValues, finalSelection, selectionArgs);
- if (notify && (count > 0)) {
- notifyChange();
- }
- return count;
- }
-
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode)
- throws FileNotFoundException {
- return openFileHelper(uri, mode);
- }
-
- private void filterUnsupportedKeys(ContentValues values) {
- // Some columns are unsupported. They should therefore
- // neither be inserted nor updated. Filter them out.
- values.remove(Mms.DELIVERY_TIME_TOKEN);
- values.remove(Mms.SENDER_VISIBILITY);
- values.remove(Mms.REPLY_CHARGING);
- values.remove(Mms.REPLY_CHARGING_DEADLINE_TOKEN);
- values.remove(Mms.REPLY_CHARGING_DEADLINE);
- values.remove(Mms.REPLY_CHARGING_ID);
- values.remove(Mms.REPLY_CHARGING_SIZE);
- values.remove(Mms.PREVIOUSLY_SENT_BY);
- values.remove(Mms.PREVIOUSLY_SENT_DATE);
- values.remove(Mms.STORE);
- values.remove(Mms.MM_STATE);
- values.remove(Mms.MM_FLAGS_TOKEN);
- values.remove(Mms.MM_FLAGS);
- values.remove(Mms.STORE_STATUS);
- values.remove(Mms.STORE_STATUS_TEXT);
- values.remove(Mms.STORED);
- values.remove(Mms.TOTALS);
- values.remove(Mms.MBOX_TOTALS);
- values.remove(Mms.MBOX_TOTALS_TOKEN);
- values.remove(Mms.QUOTAS);
- values.remove(Mms.MBOX_QUOTAS);
- values.remove(Mms.MBOX_QUOTAS_TOKEN);
- values.remove(Mms.MESSAGE_COUNT);
- values.remove(Mms.START);
- values.remove(Mms.DISTRIBUTION_INDICATOR);
- values.remove(Mms.ELEMENT_DESCRIPTOR);
- values.remove(Mms.LIMIT);
- values.remove(Mms.RECOMMENDED_RETRIEVAL_MODE);
- values.remove(Mms.RECOMMENDED_RETRIEVAL_MODE_TEXT);
- values.remove(Mms.STATUS_TEXT);
- values.remove(Mms.APPLIC_ID);
- values.remove(Mms.REPLY_APPLIC_ID);
- values.remove(Mms.AUX_APPLIC_ID);
- values.remove(Mms.DRM_CONTENT);
- values.remove(Mms.ADAPTATION_ALLOWED);
- values.remove(Mms.REPLACE_ID);
- values.remove(Mms.CANCEL_ID);
- values.remove(Mms.CANCEL_STATUS);
-
- // Keys shouldn't be inserted or updated.
- values.remove(Mms._ID);
- }
-
- private void notifyChange() {
- getContext().getContentResolver().notifyChange(
- MmsSms.CONTENT_URI, null);
- }
-
- private final static String TAG = "MmsProvider";
- private final static String VND_ANDROID_MMS = "vnd.android/mms";
- private final static String VND_ANDROID_DIR_MMS = "vnd.android-dir/mms";
- private final static boolean DEBUG = false;
- private final static boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
- private static final int MMS_ALL = 0;
- private static final int MMS_ALL_ID = 1;
- private static final int MMS_INBOX = 2;
- private static final int MMS_INBOX_ID = 3;
- private static final int MMS_SENT = 4;
- private static final int MMS_SENT_ID = 5;
- private static final int MMS_DRAFTS = 6;
- private static final int MMS_DRAFTS_ID = 7;
- private static final int MMS_OUTBOX = 8;
- private static final int MMS_OUTBOX_ID = 9;
- private static final int MMS_ALL_PART = 10;
- private static final int MMS_MSG_PART = 11;
- private static final int MMS_PART_ID = 12;
- private static final int MMS_MSG_ADDR = 13;
- private static final int MMS_SENDING_RATE = 14;
- private static final int MMS_REPORT_STATUS = 15;
- private static final int MMS_REPORT_REQUEST = 16;
- private static final int MMS_DRM_STORAGE = 17;
- private static final int MMS_DRM_STORAGE_ID = 18;
-
- private static final UriMatcher
- sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-
- static {
- sURLMatcher.addURI("mms", null, MMS_ALL);
- sURLMatcher.addURI("mms", "#", MMS_ALL_ID);
- sURLMatcher.addURI("mms", "inbox", MMS_INBOX);
- sURLMatcher.addURI("mms", "inbox/#", MMS_INBOX_ID);
- sURLMatcher.addURI("mms", "sent", MMS_SENT);
- sURLMatcher.addURI("mms", "sent/#", MMS_SENT_ID);
- sURLMatcher.addURI("mms", "drafts", MMS_DRAFTS);
- sURLMatcher.addURI("mms", "drafts/#", MMS_DRAFTS_ID);
- sURLMatcher.addURI("mms", "outbox", MMS_OUTBOX);
- sURLMatcher.addURI("mms", "outbox/#", MMS_OUTBOX_ID);
- sURLMatcher.addURI("mms", "part", MMS_ALL_PART);
- sURLMatcher.addURI("mms", "#/part", MMS_MSG_PART);
- sURLMatcher.addURI("mms", "part/#", MMS_PART_ID);
- sURLMatcher.addURI("mms", "#/addr", MMS_MSG_ADDR);
- sURLMatcher.addURI("mms", "rate", MMS_SENDING_RATE);
- sURLMatcher.addURI("mms", "report-status/#", MMS_REPORT_STATUS);
- sURLMatcher.addURI("mms", "report-request/#", MMS_REPORT_REQUEST);
- sURLMatcher.addURI("mms", "drm", MMS_DRM_STORAGE);
- sURLMatcher.addURI("mms", "drm/#", MMS_DRM_STORAGE_ID);
- }
-
- private SQLiteOpenHelper mOpenHelper;
-
- private static String concatSelections(String selection1, String selection2) {
- if (TextUtils.isEmpty(selection1)) {
- return selection2;
- } else if (TextUtils.isEmpty(selection2)) {
- return selection1;
- } else {
- return selection1 + " AND " + selection2;
- }
- }
-}
-
diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
deleted file mode 100644
index 1644186..0000000
--- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
+++ /dev/null
@@ -1,2031 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.providers.telephony;
-
-import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_DELIVERY_IND;
-import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND;
-import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_READ_ORIG_IND;
-import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_READ_REC_IND;
-import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF;
-import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_SEND_REQ;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.provider.BaseColumns;
-import android.provider.Telephony.Mms;
-import android.provider.Telephony.MmsSms;
-import android.provider.Telephony.Sms;
-import android.provider.Telephony.Threads;
-import android.provider.Telephony.Mms.Addr;
-import android.provider.Telephony.Mms.Part;
-import android.provider.Telephony.Mms.Rate;
-import android.provider.Telephony.MmsSms.PendingMessages;
-import android.util.Log;
-
-public class MmsSmsDatabaseHelper extends SQLiteOpenHelper {
- private static final String TAG = "MmsSmsDatabaseHelper";
-
- private static final String SMS_UPDATE_THREAD_READ_BODY =
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE " + Sms.READ + " = 0" +
- " AND " + Sms.THREAD_ID + " = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new." + Sms.THREAD_ID + "; ";
-
- private static final String UPDATE_THREAD_COUNT_ON_NEW =
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = " + Sms.THREAD_ID +
- " WHERE " + Sms.THREAD_ID + " = new.thread_id" +
- " AND sms." + Sms.TYPE + " != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = " + Mms.THREAD_ID +
- " WHERE " + Mms.THREAD_ID + " = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND " + Mms.MESSAGE_BOX + " != 3) " +
- " WHERE threads._id = new.thread_id; ";
-
- private static final String UPDATE_THREAD_COUNT_ON_OLD =
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = " + Sms.THREAD_ID +
- " WHERE " + Sms.THREAD_ID + " = old.thread_id" +
- " AND sms." + Sms.TYPE + " != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = " + Mms.THREAD_ID +
- " WHERE " + Mms.THREAD_ID + " = old.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND " + Mms.MESSAGE_BOX + " != 3) " +
- " WHERE threads._id = old.thread_id; ";
-
- private static final String SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE =
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new." + Sms.BODY + ", " +
- " snippet_cs = 0" +
- " WHERE threads._id = new." + Sms.THREAD_ID + "; " +
- UPDATE_THREAD_COUNT_ON_NEW +
- SMS_UPDATE_THREAD_READ_BODY +
- "END;";
-
- private static final String PDU_UPDATE_THREAD_CONSTRAINTS =
- " WHEN new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_RETRIEVE_CONF +
- " OR new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_NOTIFICATION_IND +
- " OR new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_SEND_REQ + " ";
-
- private static final String PDU_UPDATE_THREAD_READ_BODY =
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM " + MmsProvider.TABLE_PDU +
- " WHERE " + Mms.READ + " = 0" +
- " AND " + Mms.THREAD_ID + " = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new." + Mms.THREAD_ID + "; ";
-
- private static final String PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE =
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new." + Mms.SUBJECT + ", " +
- " snippet_cs = new." + Mms.SUBJECT_CHARSET +
- " WHERE threads._id = new." + Mms.THREAD_ID + "; " +
- UPDATE_THREAD_COUNT_ON_NEW +
- PDU_UPDATE_THREAD_READ_BODY +
- "END;";
-
- private static final String UPDATE_THREAD_SNIPPET_SNIPPET_CS_ON_DELETE =
- " UPDATE threads SET snippet = " +
- " (SELECT snippet FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" +
- " UNION SELECT date, body AS snippet, thread_id FROM sms)" +
- " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = OLD.thread_id; " +
- " UPDATE threads SET snippet_cs = " +
- " (SELECT snippet_cs FROM" +
- " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" +
- " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" +
- " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = OLD.thread_id; ";
-
- private static MmsSmsDatabaseHelper mInstance = null;
-
- static final String DATABASE_NAME = "mmssms.db";
- static final int DATABASE_VERSION = 41;
-
- private MmsSmsDatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- /**
- * Return a singleton helper for the combined MMS and SMS
- * database.
- */
- /* package */ static synchronized MmsSmsDatabaseHelper getInstance(Context context) {
- if (mInstance == null) {
- mInstance = new MmsSmsDatabaseHelper(context);
- }
- return mInstance;
- }
-
- public static void updateThread(SQLiteDatabase db, long thread_id) {
- if (thread_id < 0) {
- updateAllThreads(db, null, null);
- return;
- }
-
- // Delete the row for this thread in the threads table if
- // there are no more messages attached to it in either
- // the sms or pdu tables.
- int rows = db.delete("threads",
- "_id = ? AND _id NOT IN" +
- " (SELECT thread_id FROM sms " +
- " UNION SELECT thread_id FROM pdu)",
- new String[] { String.valueOf(thread_id) });
- if (rows > 0) {
- // If this deleted a row, we have no more work to do.
- return;
- }
- // Update the message count in the threads table as the sum
- // of all messages in both the sms and pdu tables.
- db.execSQL(
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = " + Sms.THREAD_ID +
- " WHERE " + Sms.THREAD_ID + " = " + thread_id +
- " AND sms." + Sms.TYPE + " != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = " + Mms.THREAD_ID +
- " WHERE " + Mms.THREAD_ID + " = " + thread_id +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND " + Mms.MESSAGE_BOX + " != 3) " +
- " WHERE threads._id = " + thread_id + ";");
-
- // Update the date and the snippet (and its character set) in
- // the threads table to be that of the most recent message in
- // the thread.
- db.execSQL(
- " UPDATE threads" +
- " SET" +
- " date =" +
- " (SELECT date FROM" +
- " (SELECT date * 1000 AS date, thread_id FROM pdu" +
- " UNION SELECT date, thread_id FROM sms)" +
- " WHERE thread_id = " + thread_id + " ORDER BY date DESC LIMIT 1)," +
- " snippet =" +
- " (SELECT snippet FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" +
- " UNION SELECT date, body AS snippet, thread_id FROM sms)" +
- " WHERE thread_id = " + thread_id + " ORDER BY date DESC LIMIT 1)," +
- " snippet_cs =" +
- " (SELECT snippet_cs FROM" +
- " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" +
- " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" +
- " WHERE thread_id = " + thread_id + " ORDER BY date DESC LIMIT 1)" +
- " WHERE threads._id = " + thread_id + ";");
-
- // Update the error column of the thread to indicate if there
- // are any messages in it that have failed to send.
- db.execSQL(
- "UPDATE threads SET error =" +
- " (SELECT COUNT(*) FROM sms WHERE type=5" +
- " AND thread_id = " + thread_id + " LIMIT 1)" +
- " WHERE threads._id = " + thread_id + ";");
- }
-
- public static void updateAllThreads(SQLiteDatabase db, String where, String[] whereArgs) {
- if (where == null) {
- where = "";
- } else {
- where = "WHERE (" + where + ")";
- }
- String query = "SELECT _id FROM threads WHERE _id IN " +
- "(SELECT DISTINCT thread_id FROM sms " + where + ")";
- Cursor c = db.rawQuery(query, whereArgs);
- if (c != null) {
- while (c.moveToNext()) {
- updateThread(db, c.getInt(0));
- }
- c.close();
- }
- }
-
- public static int deleteOneSms(SQLiteDatabase db, int message_id) {
- int thread_id = -1;
- // Find the thread ID that the specified SMS belongs to.
- Cursor c = db.query("sms", new String[] { "thread_id" },
- "_id=" + message_id, null, null, null, null);
- if (c != null) {
- if (c.moveToFirst()) {
- thread_id = c.getInt(0);
- }
- c.close();
- }
-
- // Delete the specified message.
- int rows = db.delete("sms", "_id=" + message_id, null);
- if (thread_id > 0) {
- // Update its thread.
- updateThread(db, thread_id);
- }
- return rows;
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- createMmsTables(db);
- createSmsTables(db);
- createCommonTables(db);
- createCommonTriggers(db);
- createMmsTriggers(db);
- }
-
- private void createMmsTables(SQLiteDatabase db) {
- // N.B.: Whenever the columns here are changed, the columns in
- // {@ref MmsSmsProvider} must be changed to match.
- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_PDU + " (" +
- Mms._ID + " INTEGER PRIMARY KEY," +
- Mms.THREAD_ID + " INTEGER," +
- Mms.DATE + " INTEGER," +
- Mms.MESSAGE_BOX + " INTEGER," +
- Mms.READ + " INTEGER DEFAULT 0," +
- Mms.MESSAGE_ID + " TEXT," +
- Mms.SUBJECT + " TEXT," +
- Mms.SUBJECT_CHARSET + " INTEGER," +
- Mms.CONTENT_TYPE + " TEXT," +
- Mms.CONTENT_LOCATION + " TEXT," +
- Mms.EXPIRY + " INTEGER," +
- Mms.MESSAGE_CLASS + " TEXT," +
- Mms.MESSAGE_TYPE + " INTEGER," +
- Mms.MMS_VERSION + " INTEGER," +
- Mms.MESSAGE_SIZE + " INTEGER," +
- Mms.PRIORITY + " INTEGER," +
- Mms.READ_REPORT + " INTEGER," +
- Mms.REPORT_ALLOWED + " INTEGER," +
- Mms.RESPONSE_STATUS + " INTEGER," +
- Mms.STATUS + " INTEGER," +
- Mms.TRANSACTION_ID + " TEXT," +
- Mms.RETRIEVE_STATUS + " INTEGER," +
- Mms.RETRIEVE_TEXT + " TEXT," +
- Mms.RETRIEVE_TEXT_CHARSET + " INTEGER," +
- Mms.READ_STATUS + " INTEGER," +
- Mms.CONTENT_CLASS + " INTEGER," +
- Mms.RESPONSE_TEXT + " TEXT," +
- Mms.DELIVERY_TIME + " INTEGER," +
- Mms.DELIVERY_REPORT + " INTEGER);");
-
- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_ADDR + " (" +
- Addr._ID + " INTEGER PRIMARY KEY," +
- Addr.MSG_ID + " INTEGER," +
- Addr.CONTACT_ID + " INTEGER," +
- Addr.ADDRESS + " TEXT," +
- Addr.TYPE + " INTEGER," +
- Addr.CHARSET + " INTEGER);");
-
- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_PART + " (" +
- Part._ID + " INTEGER PRIMARY KEY," +
- Part.MSG_ID + " INTEGER," +
- Part.SEQ + " INTEGER DEFAULT 0," +
- Part.CONTENT_TYPE + " TEXT," +
- Part.NAME + " TEXT," +
- Part.CHARSET + " INTEGER," +
- Part.CONTENT_DISPOSITION + " TEXT," +
- Part.FILENAME + " TEXT," +
- Part.CONTENT_ID + " TEXT," +
- Part.CONTENT_LOCATION + " TEXT," +
- Part.CT_START + " INTEGER," +
- Part.CT_TYPE + " TEXT," +
- Part._DATA + " TEXT);");
-
- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_RATE + " (" +
- Rate.SENT_TIME + " INTEGER);");
-
- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_DRM + " (" +
- BaseColumns._ID + " INTEGER PRIMARY KEY," +
- "_data TEXT);");
- }
-
- private void createMmsTriggers(SQLiteDatabase db) {
- // Cleans up parts when a MM is deleted.
- db.execSQL("CREATE TRIGGER part_cleanup DELETE ON " + MmsProvider.TABLE_PDU + " " +
- "BEGIN " +
- " DELETE FROM " + MmsProvider.TABLE_PART +
- " WHERE " + Part.MSG_ID + "=old._id;" +
- "END;");
-
- // Cleans up address info when a MM is deleted.
- db.execSQL("CREATE TRIGGER addr_cleanup DELETE ON " + MmsProvider.TABLE_PDU + " " +
- "BEGIN " +
- " DELETE FROM " + MmsProvider.TABLE_ADDR +
- " WHERE " + Addr.MSG_ID + "=old._id;" +
- "END;");
-
- // Delete obsolete delivery-report, read-report while deleting their
- // associated Send.req.
- db.execSQL("CREATE TRIGGER cleanup_delivery_and_read_report " +
- "AFTER DELETE ON " + MmsProvider.TABLE_PDU + " " +
- "WHEN old." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_SEND_REQ + " " +
- "BEGIN " +
- " DELETE FROM " + MmsProvider.TABLE_PDU +
- " WHERE (" + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_DELIVERY_IND +
- " OR " + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_READ_ORIG_IND + ")" +
- " AND " + Mms.MESSAGE_ID + "=old." + Mms.MESSAGE_ID + "; " +
- "END;");
- }
-
- private void createSmsTables(SQLiteDatabase db) {
- // N.B.: Whenever the columns here are changed, the columns in
- // {@ref MmsSmsProvider} must be changed to match.
- db.execSQL("CREATE TABLE sms (" +
- "_id INTEGER PRIMARY KEY," +
- "thread_id INTEGER," +
- "address TEXT," +
- "person INTEGER," +
- "date INTEGER," +
- "protocol INTEGER," +
- "read INTEGER DEFAULT 0," +
- "status INTEGER DEFAULT -1," + // a TP-Status value
- // or -1 if it
- // status hasn't
- // been received
- "type INTEGER," +
- "reply_path_present INTEGER," +
- "subject TEXT," +
- "body TEXT," +
- "service_center TEXT);");
-
- /**
- * This table is used by the SMS dispatcher to hold
- * incomplete partial messages until all the parts arrive.
- */
- db.execSQL("CREATE TABLE raw (" +
- "_id INTEGER PRIMARY KEY," +
- "date INTEGER," +
- "reference_number INTEGER," + // one per full message
- "count INTEGER," + // the number of parts
- "sequence INTEGER," + // the part number of this message
- "destination_port INTEGER," +
- "address TEXT," +
- "pdu TEXT);"); // the raw PDU for this part
-
- db.execSQL("CREATE TABLE attachments (" +
- "sms_id INTEGER," +
- "content_url TEXT," +
- "offset INTEGER);");
-
- /**
- * This table is used by the SMS dispatcher to hold pending
- * delivery status report intents.
- */
- db.execSQL("CREATE TABLE sr_pending (" +
- "reference_number INTEGER," +
- "action TEXT," +
- "data TEXT);");
- }
-
- private void createCommonTables(SQLiteDatabase db) {
- // TODO Ensure that each entry is removed when the last use of
- // any address equivalent to its address is removed.
-
- /**
- * This table maps the first instance seen of any particular
- * MMS/SMS address to an ID, which is then used as its
- * canonical representation. If the same address or an
- * equivalent address (as determined by our Sqlite
- * PHONE_NUMBERS_EQUAL extension) is seen later, this same ID
- * will be used.
- */
- db.execSQL("CREATE TABLE canonical_addresses (" +
- "_id INTEGER PRIMARY KEY," +
- "address TEXT);");
-
- /**
- * This table maps the subject and an ordered set of recipient
- * IDs, separated by spaces, to a unique thread ID. The IDs
- * come from the canonical_addresses table. This works
- * because messages are considered to be part of the same
- * thread if they have the same subject (or a null subject)
- * and the same set of recipients.
- */
- db.execSQL("CREATE TABLE threads (" +
- Threads._ID + " INTEGER PRIMARY KEY," +
- Threads.DATE + " INTEGER DEFAULT 0," +
- Threads.MESSAGE_COUNT + " INTEGER DEFAULT 0," +
- Threads.RECIPIENT_IDS + " TEXT," +
- Threads.SNIPPET + " TEXT," +
- Threads.SNIPPET_CHARSET + " INTEGER DEFAULT 0," +
- Threads.READ + " INTEGER DEFAULT 1," +
- Threads.TYPE + " INTEGER DEFAULT 0," +
- Threads.ERROR + " INTEGER DEFAULT 0);");
-
- /**
- * This table stores the queue of messages to be sent/downloaded.
- */
- db.execSQL("CREATE TABLE " + MmsSmsProvider.TABLE_PENDING_MSG +" (" +
- PendingMessages._ID + " INTEGER PRIMARY KEY," +
- PendingMessages.PROTO_TYPE + " INTEGER," +
- PendingMessages.MSG_ID + " INTEGER," +
- PendingMessages.MSG_TYPE + " INTEGER," +
- PendingMessages.ERROR_TYPE + " INTEGER," +
- PendingMessages.ERROR_CODE + " INTEGER," +
- PendingMessages.RETRY_INDEX + " INTEGER NOT NULL DEFAULT 0," +
- PendingMessages.DUE_TIME + " INTEGER," +
- PendingMessages.LAST_TRY + " INTEGER);");
-
- }
-
- // TODO Check the query plans for these triggers.
- private void createCommonTriggers(SQLiteDatabase db) {
- // Updates threads table whenever a message is added to pdu.
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON " +
- MmsProvider.TABLE_PDU + " " +
- PDU_UPDATE_THREAD_CONSTRAINTS +
- PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);
-
- // Updates threads table whenever a message is added to sms.
- db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " +
- SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);
-
- // Updates threads table whenever a message in pdu is updated.
- db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF " + Mms.DATE + ", " + Mms.SUBJECT + ", " + Mms.MESSAGE_BOX +
- " ON " + MmsProvider.TABLE_PDU + " " +
- PDU_UPDATE_THREAD_CONSTRAINTS +
- PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);
-
- // Updates threads table whenever a message in sms is updated.
- db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF " + Sms.DATE + ", " + Sms.BODY + ", " + Sms.TYPE +
- " ON sms " +
- SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE);
-
- // Updates threads table whenever a message in pdu is updated.
- db.execSQL("CREATE TRIGGER pdu_update_thread_read_on_update AFTER" +
- " UPDATE OF " + Mms.READ +
- " ON " + MmsProvider.TABLE_PDU + " " +
- PDU_UPDATE_THREAD_CONSTRAINTS +
- "BEGIN " +
- PDU_UPDATE_THREAD_READ_BODY +
- "END;");
-
- // Updates threads table whenever a message in sms is updated.
- db.execSQL("CREATE TRIGGER sms_update_thread_read_on_update AFTER" +
- " UPDATE OF " + Sms.READ +
- " ON sms " +
- "BEGIN " +
- SMS_UPDATE_THREAD_READ_BODY +
- "END;");
-
- // Update threads table whenever a message in pdu is deleted
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_delete " +
- "AFTER DELETE ON pdu " +
- "BEGIN " +
- " UPDATE threads SET " +
- " date = (strftime('%s','now') * 1000)" +
- " WHERE threads._id = old." + Mms.THREAD_ID + "; " +
- UPDATE_THREAD_COUNT_ON_OLD +
- UPDATE_THREAD_SNIPPET_SNIPPET_CS_ON_DELETE +
- "END;");
-
- // When the last message in a thread is deleted, these
- // triggers ensure that the entry for its thread ID is removed
- // from the threads table.
- db.execSQL("CREATE TRIGGER delete_obsolete_threads_pdu " +
- "AFTER DELETE ON pdu " +
- "BEGIN " +
- " DELETE FROM threads " +
- " WHERE " +
- " _id = old.thread_id " +
- " AND _id NOT IN " +
- " (SELECT thread_id FROM sms " +
- " UNION SELECT thread_id from pdu); " +
- "END;");
-
- db.execSQL("CREATE TRIGGER delete_obsolete_threads_when_update_pdu " +
- "AFTER UPDATE OF " + Mms.THREAD_ID + " ON pdu " +
- "WHEN old." + Mms.THREAD_ID + " != new." + Mms.THREAD_ID + " " +
- "BEGIN " +
- " DELETE FROM threads " +
- " WHERE " +
- " _id = old.thread_id " +
- " AND _id NOT IN " +
- " (SELECT thread_id FROM sms " +
- " UNION SELECT thread_id from pdu); " +
- "END;");
- // Insert pending status for M-Notification.ind or M-ReadRec.ind
- // when they are inserted into Inbox/Outbox.
- db.execSQL("CREATE TRIGGER insert_mms_pending_on_insert " +
- "AFTER INSERT ON pdu " +
- "WHEN new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_NOTIFICATION_IND +
- " OR new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_READ_REC_IND + " " +
- "BEGIN " +
- " INSERT INTO " + MmsSmsProvider.TABLE_PENDING_MSG +
- " (" + PendingMessages.PROTO_TYPE + "," +
- " " + PendingMessages.MSG_ID + "," +
- " " + PendingMessages.MSG_TYPE + "," +
- " " + PendingMessages.ERROR_TYPE + "," +
- " " + PendingMessages.ERROR_CODE + "," +
- " " + PendingMessages.RETRY_INDEX + "," +
- " " + PendingMessages.DUE_TIME + ") " +
- " VALUES " +
- " (" + MmsSms.MMS_PROTO + "," +
- " new." + BaseColumns._ID + "," +
- " new." + Mms.MESSAGE_TYPE + ",0,0,0,0);" +
- "END;");
-
- // Insert pending status for M-Send.req when it is moved into Outbox.
- db.execSQL("CREATE TRIGGER insert_mms_pending_on_update " +
- "AFTER UPDATE ON pdu " +
- "WHEN new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_SEND_REQ +
- " AND new." + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_OUTBOX +
- " AND old." + Mms.MESSAGE_BOX + "!=" + Mms.MESSAGE_BOX_OUTBOX + " " +
- "BEGIN " +
- " INSERT INTO " + MmsSmsProvider.TABLE_PENDING_MSG +
- " (" + PendingMessages.PROTO_TYPE + "," +
- " " + PendingMessages.MSG_ID + "," +
- " " + PendingMessages.MSG_TYPE + "," +
- " " + PendingMessages.ERROR_TYPE + "," +
- " " + PendingMessages.ERROR_CODE + "," +
- " " + PendingMessages.RETRY_INDEX + "," +
- " " + PendingMessages.DUE_TIME + ") " +
- " VALUES " +
- " (" + MmsSms.MMS_PROTO + "," +
- " new." + BaseColumns._ID + "," +
- " new." + Mms.MESSAGE_TYPE + ",0,0,0,0);" +
- "END;");
-
- // When a message is moved out of Outbox, delete its pending status.
- db.execSQL("CREATE TRIGGER delete_mms_pending_on_update " +
- "AFTER UPDATE ON " + MmsProvider.TABLE_PDU + " " +
- "WHEN old." + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_OUTBOX +
- " AND new." + Mms.MESSAGE_BOX + "!=" + Mms.MESSAGE_BOX_OUTBOX + " " +
- "BEGIN " +
- " DELETE FROM " + MmsSmsProvider.TABLE_PENDING_MSG +
- " WHERE " + PendingMessages.MSG_ID + "=new._id; " +
- "END;");
-
- // Delete pending status for a message when it is deleted.
- db.execSQL("CREATE TRIGGER delete_mms_pending_on_delete " +
- "AFTER DELETE ON " + MmsProvider.TABLE_PDU + " " +
- "BEGIN " +
- " DELETE FROM " + MmsSmsProvider.TABLE_PENDING_MSG +
- " WHERE " + PendingMessages.MSG_ID + "=old._id; " +
- "END;");
-
- // TODO Add triggers for SMS retry-status management.
-
- // Update the error flag of threads when the error type of
- // a pending MM is updated.
- db.execSQL("CREATE TRIGGER update_threads_error_on_update_mms " +
- " AFTER UPDATE OF err_type ON pending_msgs " +
- " WHEN (OLD.err_type < 10 AND NEW.err_type >= 10)" +
- " OR (OLD.err_type >= 10 AND NEW.err_type < 10) " +
- "BEGIN" +
- " UPDATE threads SET error = " +
- " CASE" +
- " WHEN NEW.err_type >= 10 THEN error + 1" +
- " ELSE error - 1" +
- " END " +
- " WHERE _id =" +
- " (SELECT DISTINCT thread_id" +
- " FROM pdu" +
- " WHERE _id = NEW.msg_id); " +
- "END;");
-
- // Update the error flag of threads when delete pending message.
- db.execSQL("CREATE TRIGGER update_threads_error_on_delete_mms " +
- " BEFORE DELETE ON pdu" +
- " WHEN OLD._id IN (SELECT DISTINCT msg_id" +
- " FROM pending_msgs" +
- " WHERE err_type >= 10) " +
- "BEGIN " +
- " UPDATE threads SET error = error - 1" +
- " WHERE _id = OLD.thread_id; " +
- "END;");
-
- // Update the error flag of threads while moving an MM out of Outbox,
- // which was failed to be sent permanently.
- db.execSQL("CREATE TRIGGER update_threads_error_on_move_mms " +
- " BEFORE UPDATE OF msg_box ON pdu " +
- " WHEN (OLD.msg_box = 4 AND NEW.msg_box != 4) " +
- " AND (OLD._id IN (SELECT DISTINCT msg_id" +
- " FROM pending_msgs" +
- " WHERE err_type >= 10)) " +
- "BEGIN " +
- " UPDATE threads SET error = error - 1" +
- " WHERE _id = OLD.thread_id; " +
- "END;");
-
- // Update the error flag of threads after a text message was
- // failed to send/receive.
- db.execSQL("CREATE TRIGGER update_threads_error_on_update_sms " +
- " AFTER UPDATE OF type ON sms" +
- " WHEN (OLD.type != 5 AND NEW.type = 5)" +
- " OR (OLD.type = 5 AND NEW.type != 5) " +
- "BEGIN " +
- " UPDATE threads SET error = " +
- " CASE" +
- " WHEN NEW.type = 5 THEN error + 1" +
- " ELSE error - 1" +
- " END " +
- " WHERE _id = NEW.thread_id; " +
- "END;");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
- Log.w(TAG, "Upgrading database from version " + oldVersion
- + " to " + currentVersion + ".");
-
- switch (oldVersion) {
- case 24:
- if (currentVersion <= 24) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion25(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 25:
- if (currentVersion <= 25) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion26(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 26:
- if (currentVersion <= 26) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion27(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 27:
- if (currentVersion <= 27) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion28(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 28:
- if (currentVersion <= 28) {
- return;
- }
-
- // Test whether this database file is from TC2 branch.
- Cursor c = db.rawQuery("SELECT * FROM threads", null);
- if (c != null) {
- try {
- c.getColumnIndexOrThrow("snippet_cs");
- } catch (IllegalArgumentException e) {
- // Column 'snippet_cs' doesn't exist, which means
- // this database file was maintained by TC2 branch
- // and its version is inconsistent.
- Log.w(TAG, "Upgrade database file from TC2!!!");
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion28(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- } finally {
- c.close();
- }
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion29(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 29:
- if (currentVersion <= 29) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion30(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 30:
- if (currentVersion <= 30) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion31(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 31:
- if (currentVersion <= 31) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion32(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 32:
- if (currentVersion <= 32) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion33(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 33:
- if (currentVersion <= 33) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion34(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 34:
- if (currentVersion <= 34) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion35(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 35:
- if (currentVersion <= 35) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion36(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 36:
- if (currentVersion <= 36) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion37(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 37:
- if (currentVersion <= 37) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion38(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 38:
- if (currentVersion <= 38) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion39(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 39:
- if (currentVersion <= 39) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion40(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 40:
- if (currentVersion <= 40) {
- return;
- }
-
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion41(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break; // force to destroy all old data;
- } finally {
- db.endTransaction();
- }
- // fall-through
- case 41:
- if (currentVersion <= 41) {
- return;
- }
- db.beginTransaction();
- try {
- upgradeDatabaseToVersion42(db);
- db.setTransactionSuccessful();
- } catch (Throwable ex) {
- Log.e(TAG, ex.getMessage(), ex);
- break;
- } finally {
- db.endTransaction();
- }
- return;
- }
-
- Log.w(TAG, "Destroying all old data.");
- dropCommonTriggers(db);
- dropMmsTriggers(db);
- dropCommonTables(db);
- dropMmsTables(db);
- dropSmsTables(db);
- onCreate(db);
- }
-
- private void dropCommonTables(SQLiteDatabase db) {
- db.execSQL("DROP TABLE IF EXISTS canonical_addresses");
- db.execSQL("DROP TABLE IF EXISTS threads");
- db.execSQL("DROP TABLE IF EXISTS " + MmsSmsProvider.TABLE_PENDING_MSG);
- }
-
- private void dropCommonTriggers(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_pdu");
- db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_when_update_pdu");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_read_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_read_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS insert_mms_pending_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS insert_mms_pending_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS delete_mms_pending_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS delete_mms_pending_on_delete");
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_update_mms");
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete_mms");
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_move_mms");
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_update_sms");
- }
-
- private void dropSmsTables(SQLiteDatabase db) {
- db.execSQL("DROP TABLE IF EXISTS sms");
- db.execSQL("DROP TABLE IF EXISTS newSmsIndicator");
- db.execSQL("DROP TABLE IF EXISTS raw");
- db.execSQL("DROP TABLE IF EXISTS attachments");
- db.execSQL("DROP TABLE IF EXISTS thread_ids");
- db.execSQL("DROP TABLE IF EXISTS sr_pending");
- }
-
- private void dropMmsTables(SQLiteDatabase db) {
- db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_PDU + ";");
- db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_ADDR + ";");
- db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_PART + ";");
- db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_RATE + ";");
- db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_DRM + ";");
- }
-
- private void dropMmsTriggers(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS part_cleanup;");
- db.execSQL("DROP TRIGGER IF EXISTS addr_cleanup;");
- db.execSQL("DROP TRIGGER IF EXISTS cleanup_delivery_and_read_report;");
- }
-
- private void upgradeDatabaseToVersion25(SQLiteDatabase db) {
- db.execSQL("ALTER TABLE threads " +
- "ADD COLUMN type INTEGER NOT NULL DEFAULT 0;");
- }
-
- private void upgradeDatabaseToVersion26(SQLiteDatabase db) {
- db.execSQL("ALTER TABLE threads " +
- "ADD COLUMN error INTEGER DEFAULT 0;");
-
- // Do NOT use defined symbols when upgrading database
- // because they may be changed and cannot be applied
- // to old database.
- db.execSQL("UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" +
- " ON pdu.thread_id = pending_msgs.msg_id" +
- " WHERE proto_type = 1 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" +
- " ON sms.thread_id = pending_msgs.msg_id" +
- " WHERE proto_type = 0 AND err_type >= 10" +
- " GROUP BY thread_id); ");
-
- db.execSQL("CREATE TRIGGER update_threads_error_on_update " +
- " AFTER UPDATE OF err_type ON pending_msgs " +
- "BEGIN " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" +
- " ON pdu.thread_id = pending_msgs.msg_id" +
- " WHERE proto_type = 1 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" +
- " ON sms.thread_id = pending_msgs.msg_id" +
- " WHERE proto_type = 0 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "END;");
-
- db.execSQL("CREATE TRIGGER update_threads_error_on_delete " +
- " AFTER DELETE ON pending_msgs " +
- "BEGIN " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" +
- " ON pdu.thread_id = pending_msgs.msg_id" +
- " WHERE proto_type = 1 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" +
- " ON sms.thread_id = pending_msgs.msg_id" +
- " WHERE proto_type = 0 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion27(SQLiteDatabase db) {
- db.execSQL("UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" +
- " ON pdu._id = pending_msgs.msg_id" +
- " WHERE proto_type = 1 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" +
- " ON sms._id = pending_msgs.msg_id" +
- " WHERE proto_type = 0 AND err_type >= 10" +
- " GROUP BY thread_id); ");
-
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete");
-
- db.execSQL("CREATE TRIGGER update_threads_error_on_update " +
- " AFTER UPDATE OF err_type ON pending_msgs " +
- "BEGIN " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" +
- " ON pdu._id = pending_msgs.msg_id" +
- " WHERE proto_type = 1 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" +
- " ON sms._id = pending_msgs.msg_id" +
- " WHERE proto_type = 0 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "END;");
-
- db.execSQL("CREATE TRIGGER update_threads_error_on_delete " +
- " AFTER DELETE ON pending_msgs " +
- "BEGIN " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" +
- " ON pdu._id = pending_msgs.msg_id" +
- " WHERE proto_type = 1 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "UPDATE threads SET error = 1 WHERE _id IN" +
- " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" +
- " ON sms._id = pending_msgs.msg_id" +
- " WHERE proto_type = 0 AND err_type >= 10" +
- " GROUP BY thread_id); " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion28(SQLiteDatabase db) {
- db.execSQL("ALTER TABLE threads " +
- "ADD COLUMN snippet_cs INTEGER NOT NULL DEFAULT 0;");
-
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_read_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " +
- " WHEN new.msg_box!=5 AND new.msg_box!=3" +
- " AND (new.m_type=132 OR new.m_type=130 OR new.m_type=128) " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, sub, msg_box ON pdu " +
- " WHEN new.msg_box!=5 AND new.msg_box!=3" +
- " AND (new.m_type=132 OR new.m_type=130 OR new.m_type=128) " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_read_on_update AFTER" +
- " UPDATE OF read ON pdu " +
- " WHEN new.msg_box!=5 AND new.msg_box!=3" +
- " AND (new.m_type=132 OR new.m_type=130 OR new.m_type=128) " +
- "BEGIN " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_on_delete " +
- "AFTER DELETE ON sms " +
- "BEGIN " +
- " UPDATE threads SET " +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = (SELECT body FROM SMS ORDER BY date DESC LIMIT 1)" +
- " WHERE threads._id = old.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion29(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_read_on_update");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, sub, msg_box ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_read_on_update AFTER" +
- " UPDATE OF read ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion30(SQLiteDatabase db) {
- // Since SQLite doesn't support altering constraints
- // of an existing table, I have to create a new table
- // with updated constraints, copy old data into this
- // table, drop old table and then rename the new table
- // to 'threads'.
- db.execSQL("CREATE TABLE temp_threads (" +
- "_id INTEGER PRIMARY KEY," +
- "date INTEGER DEFAULT 0," +
- "subject TEXT," +
- "recipient_ids TEXT," +
- "snippet TEXT," +
- "snippet_cs INTEGER DEFAULT 0," +
- "read INTEGER DEFAULT 1," +
- "type INTEGER DEFAULT 0," +
- "error INTEGER DEFAULT 0);");
- db.execSQL("INSERT INTO temp_threads SELECT * FROM threads;");
- db.execSQL("DROP TABLE IF EXISTS threads;");
- db.execSQL("ALTER TABLE temp_threads RENAME TO threads;");
- }
-
- private void upgradeDatabaseToVersion31(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete");
-
- // Update threads table whenever a message in sms is deleted
- // (Usually an abandoned draft.)
- db.execSQL("CREATE TRIGGER sms_update_thread_on_delete " +
- "AFTER DELETE ON sms " +
- "BEGIN " +
- " UPDATE threads SET " +
- " date = (strftime('%s','now') * 1000) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET" +
- " snippet = (SELECT snippet FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet," +
- " sub_cs AS snippet_cs FROM pdu" +
- " UNION SELECT date, body AS snippet, NULL AS snippet_cs" +
- " FROM sms) ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET" +
- " snippet_cs = (SELECT snippet_cs FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet," +
- " sub_cs AS snippet_cs FROM pdu" +
- " UNION SELECT date, body AS snippet, NULL AS snippet_cs" +
- " FROM sms) ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = old.thread_id; " +
- "END;");
-
- // Update threads table whenever a message in pdu is deleted
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_delete " +
- "AFTER DELETE ON pdu " +
- "BEGIN " +
- " UPDATE threads SET " +
- " date = (strftime('%s','now') * 1000)" +
- " WHERE threads._id = old.thread_id;" +
- " UPDATE threads SET" +
- " snippet = (SELECT snippet FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet," +
- " sub_cs AS snippet_cs FROM pdu" +
- " UNION SELECT date, body AS snippet, NULL AS snippet_cs" +
- " FROM sms) ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET" +
- " snippet_cs = (SELECT snippet_cs FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet," +
- " sub_cs AS snippet_cs FROM pdu" +
- " UNION SELECT date, body AS snippet, NULL AS snippet_cs" +
- " FROM sms) ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = old.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion32(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE IF NOT EXISTS rate (sent_time INTEGER);");
- }
-
- private void upgradeDatabaseToVersion33(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete");
-
- db.execSQL("CREATE TRIGGER update_threads_error_on_update_mms " +
- " AFTER UPDATE OF err_type ON pending_msgs " +
- " WHEN (OLD.err_type < 10 AND NEW.err_type >= 10)" +
- " OR (OLD.err_type >= 10 AND NEW.err_type < 10) " +
- "BEGIN" +
- " UPDATE threads SET error = " +
- " CASE" +
- " WHEN NEW.err_type >= 10 THEN error + 1" +
- " ELSE error - 1" +
- " END " +
- " WHERE _id =" +
- " (SELECT DISTINCT thread_id" +
- " FROM pdu" +
- " WHERE _id = NEW.msg_id); " +
- "END;");
-
- db.execSQL("CREATE TRIGGER update_threads_error_on_delete_mms " +
- " BEFORE DELETE ON pdu" +
- " WHEN OLD._id IN (SELECT DISTINCT msg_id" +
- " FROM pending_msgs" +
- " WHERE err_type >= 10) " +
- "BEGIN " +
- " UPDATE threads SET error = error - 1" +
- " WHERE _id = OLD.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER update_threads_error_on_update_sms " +
- " AFTER UPDATE OF type ON sms" +
- " WHEN (OLD.type != 5 AND NEW.type = 5)" +
- " OR (OLD.type = 5 AND NEW.type != 5) " +
- "BEGIN " +
- " UPDATE threads SET error = " +
- " CASE" +
- " WHEN NEW.type = 5 THEN error + 1" +
- " ELSE error - 1" +
- " END " +
- " WHERE _id = NEW.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER update_threads_error_on_delete_sms " +
- " AFTER DELETE ON sms" +
- " WHEN (OLD.type = 5) " +
- "BEGIN " +
- " UPDATE threads SET error = error - 1" +
- " WHERE _id = OLD.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion34(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.body," +
- " snippet_cs = 0" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE read = 0" +
- " AND thread_id = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, body, msg_box" +
- " ON sms " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.body," +
- " snippet_cs = 0" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE read = 0" +
- " AND thread_id = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion35(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE temp_threads (" +
- "_id INTEGER PRIMARY KEY," +
- "date INTEGER DEFAULT 0," +
- "message_count INTEGER DEFAULT 0," +
- "recipient_ids TEXT," +
- "snippet TEXT," +
- "snippet_cs INTEGER DEFAULT 0," +
- "read INTEGER DEFAULT 1," +
- "type INTEGER DEFAULT 0," +
- "error INTEGER DEFAULT 0);");
- db.execSQL("INSERT INTO temp_threads " +
- "SELECT _id, date, 0 AS message_count, recipient_ids," +
- " snippet, snippet_cs, read, type, error " +
- "FROM threads;");
- db.execSQL("DROP TABLE IF EXISTS threads;");
- db.execSQL("ALTER TABLE temp_threads RENAME TO threads;");
-
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_delete");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.body," +
- " snippet_cs = 0" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE read = 0" +
- " AND thread_id = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_on_delete " +
- "AFTER DELETE ON sms " +
- "BEGIN " +
- " UPDATE threads SET " +
- " date = (strftime('%s','now') * 1000) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = old.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = old.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET" +
- " snippet = (SELECT snippet FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet," +
- " sub_cs AS snippet_cs FROM pdu" +
- " UNION SELECT date, body AS snippet, NULL AS snippet_cs" +
- " FROM sms) ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET" +
- " snippet_cs = (SELECT snippet_cs FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet," +
- " sub_cs AS snippet_cs FROM pdu" +
- " UNION SELECT date, body AS snippet, NULL AS snippet_cs" +
- " FROM sms) ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = old.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_delete " +
- "AFTER DELETE ON pdu " +
- "BEGIN " +
- " UPDATE threads SET " +
- " date = (strftime('%s','now') * 1000)" +
- " WHERE threads._id = old.thread_id;" +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = old.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = old.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET" +
- " snippet = (SELECT snippet FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet," +
- " sub_cs AS snippet_cs FROM pdu" +
- " UNION SELECT date, body AS snippet, NULL AS snippet_cs" +
- " FROM sms) ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET" +
- " snippet_cs = (SELECT snippet_cs FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet," +
- " sub_cs AS snippet_cs FROM pdu" +
- " UNION SELECT date, body AS snippet, NULL AS snippet_cs" +
- " FROM sms) ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = old.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, body, type" +
- " ON sms " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.body," +
- " snippet_cs = 0" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE read = 0" +
- " AND thread_id = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, sub, msg_box ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion36(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE IF NOT EXISTS drm (_id INTEGER PRIMARY KEY, _data TEXT);");
- db.execSQL("CREATE TRIGGER IF NOT EXISTS drm_file_cleanup DELETE ON drm " +
- "BEGIN SELECT _DELETE_FILE(old._data); END;");
- }
-
- private void upgradeDatabaseToVersion37(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_delete");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_on_delete " +
- "AFTER DELETE ON sms " +
- "BEGIN " +
- " UPDATE threads SET " +
- " date = (strftime('%s','now') * 1000) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = old.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = old.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET snippet = " +
- " (SELECT snippet FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" +
- " UNION SELECT date, body AS snippet, thread_id FROM sms)" +
- " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = OLD.thread_id; " +
- " UPDATE threads SET snippet_cs = " +
- " (SELECT snippet_cs FROM" +
- " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" +
- " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" +
- " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = OLD.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_delete " +
- "AFTER DELETE ON pdu " +
- "BEGIN " +
- " UPDATE threads SET " +
- " date = (strftime('%s','now') * 1000)" +
- " WHERE threads._id = old.thread_id;" +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = old.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = old.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = old.thread_id; " +
- " UPDATE threads SET snippet = " +
- " (SELECT snippet FROM" +
- " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" +
- " UNION SELECT date, body AS snippet, thread_id FROM sms)" +
- " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = OLD.thread_id; " +
- " UPDATE threads SET snippet_cs = " +
- " (SELECT snippet_cs FROM" +
- " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" +
- " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" +
- " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " +
- " WHERE threads._id = OLD.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TABLE temp_part (" +
- "_id INTEGER PRIMARY KEY," +
- "mid INTEGER," +
- "seq INTEGER DEFAULT 0," +
- "ct TEXT," +
- "name TEXT," +
- "chset INTEGER," +
- "cd TEXT," +
- "fn TEXT," +
- "cid TEXT," +
- "cl TEXT," +
- "ctt_s INTEGER," +
- "ctt_t TEXT," +
- "_data TEXT);");
- db.execSQL("INSERT INTO temp_part SELECT * FROM part;");
- db.execSQL("UPDATE temp_part SET seq='0';");
- db.execSQL("UPDATE temp_part SET seq='-1' WHERE ct='application/smil';");
- db.execSQL("DROP TABLE IF EXISTS part;");
- db.execSQL("ALTER TABLE temp_part RENAME TO part;");
- }
-
- private void upgradeDatabaseToVersion38(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS part_file_cleanup;");
- db.execSQL("DROP TRIGGER IF EXISTS drm_file_cleanup;");
- }
-
- private void upgradeDatabaseToVersion39(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.body," +
- " snippet_cs = 0" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3 " +
- " AND pdu.m_id is NULL) + " +
- " (SELECT COUNT(DISTINCT pdu.m_id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3 " +
- " AND pdu.m_id is not NULL) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE read = 0" +
- " AND thread_id = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, body, type" +
- " ON sms " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.body," +
- " snippet_cs = 0" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3 " +
- " AND pdu.m_id is NULL) + " +
- " (SELECT COUNT(DISTINCT pdu.m_id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3 " +
- " AND pdu.m_id is not NULL) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE read = 0" +
- " AND thread_id = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3 " +
- " AND pdu.m_id is NULL) + " +
- " (SELECT COUNT(DISTINCT pdu.m_id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3 " +
- " AND pdu.m_id is not NULL) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, sub, msg_box ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3 " +
- " AND pdu.m_id is NULL) + " +
- " (SELECT COUNT(DISTINCT pdu.m_id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3 " +
- " AND pdu.m_id is not NULL) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion40(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert");
- db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.body," +
- " snippet_cs = 0" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE read = 0" +
- " AND thread_id = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, body, type" +
- " ON sms " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.body," +
- " snippet_cs = 0" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM sms" +
- " WHERE read = 0" +
- " AND thread_id = threads._id)" +
- " WHEN 0 THEN 1" +
- " ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
-
- db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" +
- " UPDATE OF date, sub, msg_box ON pdu " +
- " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " +
- "BEGIN" +
- " UPDATE threads SET" +
- " date = (strftime('%s','now') * 1000), " +
- " snippet = new.sub, " +
- " snippet_cs = new.sub_cs" +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET message_count = " +
- " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND sms.type != 3) + " +
- " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " +
- " ON threads._id = thread_id" +
- " WHERE thread_id = new.thread_id" +
- " AND (m_type=132 OR m_type=130 OR m_type=128)" +
- " AND msg_box != 3) " +
- " WHERE threads._id = new.thread_id; " +
- " UPDATE threads SET read = " +
- " CASE (SELECT COUNT(*)" +
- " FROM pdu" +
- " WHERE read = 0 AND thread_id = threads._id)" +
- " WHEN 0 THEN 1 ELSE 0" +
- " END" +
- " WHERE threads._id = new.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion41(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_move_mms");
- db.execSQL("CREATE TRIGGER update_threads_error_on_move_mms " +
- " BEFORE UPDATE OF msg_box ON pdu " +
- " WHEN (OLD.msg_box = 4 AND NEW.msg_box != 4) " +
- " AND (OLD._id IN (SELECT DISTINCT msg_id" +
- " FROM pending_msgs" +
- " WHERE err_type >= 10)) " +
- "BEGIN " +
- " UPDATE threads SET error = error - 1" +
- " WHERE _id = OLD.thread_id; " +
- "END;");
- }
-
- private void upgradeDatabaseToVersion42(SQLiteDatabase db) {
- db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete");
- db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_sms");
- db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete_sms");
- }
-}
diff --git a/src/com/android/providers/telephony/MmsSmsProvider.java b/src/com/android/providers/telephony/MmsSmsProvider.java
deleted file mode 100644
index b27e332..0000000
--- a/src/com/android/providers/telephony/MmsSmsProvider.java
+++ /dev/null
@@ -1,1019 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.providers.telephony;
-
-import com.google.android.mms.pdu.PduHeaders;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.provider.BaseColumns;
-import android.provider.Telephony.CanonicalAddressesColumns;
-import android.provider.Telephony.Mms;
-import android.provider.Telephony.MmsSms;
-import android.provider.Telephony.Sms;
-import android.provider.Telephony.Threads;
-import android.provider.Telephony.ThreadsColumns;
-import android.provider.Telephony.MmsSms.PendingMessages;
-import android.provider.Telephony.Sms.Conversations;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * This class provides the ability to query the MMS and SMS databases
- * at the same time, mixing messages from both in a single thread
- * (A.K.A. conversation).
- *
- * A virtual column, MmsSms.TYPE_DISCRIMINATOR_COLUMN, may be
- * requested in the projection for a query. Its value is either "mms"
- * or "sms", depending on whether the message represented by the row
- * is an MMS message or an SMS message, respectively.
- *
- * This class also provides the ability to find out what addresses
- * participated in a particular thread. It doesn't support updates
- * for either of these.
- *
- * This class provides a way to allocate and retrieve thread IDs.
- * This is done atomically through a query. There is no insert URI
- * for this.
- *
- * Finally, this class provides a way to delete or update all messages
- * in a thread.
- */
-public class MmsSmsProvider extends ContentProvider {
- private static final UriMatcher URI_MATCHER =
- new UriMatcher(UriMatcher.NO_MATCH);
- private static final String LOG_TAG = "MmsSmsProvider";
-
- private static final String NO_DELETES_INSERTS_OR_UPDATES =
- "MmsSmsProvider does not support deletes, inserts, or updates for this URI.";
- private static final int URI_CONVERSATIONS = 0;
- private static final int URI_CONVERSATIONS_MESSAGES = 1;
- private static final int URI_CONVERSATIONS_RECIPIENTS = 2;
- private static final int URI_MESSAGES_BY_PHONE = 3;
- private static final int URI_THREAD_ID = 4;
- private static final int URI_CANONICAL_ADDRESS = 5;
- private static final int URI_PENDING_MSG = 6;
- private static final int URI_COMPLETE_CONVERSATIONS = 7;
- private static final int URI_UNDELIVERED_MSG = 8;
- private static final int URI_CONVERSATIONS_SUBJECT = 9;
- private static final int URI_NOTIFICATIONS = 10;
- private static final int URI_OBSOLETE_THREADS = 11;
- private static final int URI_DRAFT = 12;
-
- /**
- * the name of the table that is used to store the queue of
- * messages(both MMS and SMS) to be sent/downloaded.
- */
- public static final String TABLE_PENDING_MSG = "pending_msgs";
-
- // These constants are used to construct union queries across the
- // MMS and SMS base tables.
-
- // These are the columns that appear in both the MMS ("pdu") and
- // SMS ("sms") message tables.
- private static final String[] MMS_SMS_COLUMNS =
- { BaseColumns._ID, Mms.DATE, Mms.READ, Mms.THREAD_ID };
-
- // These are the columns that appear only in the MMS message
- // table.
- private static final String[] MMS_ONLY_COLUMNS = {
- Mms.CONTENT_CLASS, Mms.CONTENT_LOCATION, Mms.CONTENT_TYPE,
- Mms.DELIVERY_REPORT, Mms.EXPIRY, Mms.MESSAGE_CLASS, Mms.MESSAGE_ID,
- Mms.MESSAGE_SIZE, Mms.MESSAGE_TYPE, Mms.MESSAGE_BOX, Mms.PRIORITY,
- Mms.READ_STATUS, Mms.RESPONSE_STATUS, Mms.RESPONSE_TEXT,
- Mms.RETRIEVE_STATUS, Mms.RETRIEVE_TEXT_CHARSET, Mms.REPORT_ALLOWED,
- Mms.READ_REPORT, Mms.STATUS, Mms.SUBJECT, Mms.SUBJECT_CHARSET,
- Mms.TRANSACTION_ID, Mms.MMS_VERSION };
-
- // These are the columns that appear only in the SMS message
- // table.
- private static final String[] SMS_ONLY_COLUMNS =
- { "address", "body", "person", "reply_path_present",
- "service_center", "status", "subject", "type" };
-
- // These are all the columns that appear in the "threads" table.
- private static final String[] THREADS_COLUMNS = {
- BaseColumns._ID,
- ThreadsColumns.DATE,
- ThreadsColumns.RECIPIENT_IDS,
- ThreadsColumns.MESSAGE_COUNT
- };
-
- // These are all the columns that appear in the MMS and SMS
- // message tables.
- private static final String[] UNION_COLUMNS =
- new String[MMS_SMS_COLUMNS.length
- + MMS_ONLY_COLUMNS.length
- + SMS_ONLY_COLUMNS.length];
-
- // These are all the columns that appear in the MMS table.
- private static final Set<String> MMS_COLUMNS = new HashSet<String>();
-
- // These are all the columns that appear in the SMS table.
- private static final Set<String> SMS_COLUMNS = new HashSet<String>();
-
- private static final String VND_ANDROID_DIR_MMS_SMS =
- "vnd.android-dir/mms-sms";
-
- private static final String[] ID_PROJECTION = { BaseColumns._ID };
-
- private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
- private static final String SMS_CONVERSATION_CONSTRAINT = "(" +
- Sms.TYPE + " != " + Sms.MESSAGE_TYPE_DRAFT + ")";
-
- private static final String MMS_CONVERSATION_CONSTRAINT = "(" +
- Mms.MESSAGE_BOX + " != " + Mms.MESSAGE_BOX_DRAFTS + " AND (" +
- Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_SEND_REQ + " OR " +
- Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF + " OR " +
- Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND + "))";
-
- private static final String AUTHORITY = "mms-sms";
-
- static {
- URI_MATCHER.addURI(AUTHORITY, "conversations", URI_CONVERSATIONS);
- URI_MATCHER.addURI(AUTHORITY, "complete-conversations", URI_COMPLETE_CONVERSATIONS);
-
- // In these patterns, "#" is the thread ID.
- URI_MATCHER.addURI(
- AUTHORITY, "conversations/#", URI_CONVERSATIONS_MESSAGES);
- URI_MATCHER.addURI(
- AUTHORITY, "conversations/#/recipients",
- URI_CONVERSATIONS_RECIPIENTS);
-
- URI_MATCHER.addURI(
- AUTHORITY, "conversations/#/subject",
- URI_CONVERSATIONS_SUBJECT);
-
- // URI for deleting obsolete threads.
- URI_MATCHER.addURI(AUTHORITY, "conversations/obsolete", URI_OBSOLETE_THREADS);
-
- URI_MATCHER.addURI(
- AUTHORITY, "messages/byphone/*",
- URI_MESSAGES_BY_PHONE);
-
- // In this pattern, two query parameter names are expected:
- // "subject" and "recipient." Multiple "recipient" parameters
- // may be present.
- URI_MATCHER.addURI(AUTHORITY, "threadID", URI_THREAD_ID);
-
- // Use this pattern to query the canonical address by given ID.
- URI_MATCHER.addURI(AUTHORITY, "canonical-address/#", URI_CANONICAL_ADDRESS);
-
- // In this pattern, two query parameters may be supplied:
- // "protocol" and "message." For example:
- // content://mms-sms/pending?
- // -> Return all pending messages;
- // content://mms-sms/pending?protocol=sms
- // -> Only return pending SMs;
- // content://mms-sms/pending?protocol=mms&message=1
- // -> Return the the pending MM which ID equals '1'.
- //
- URI_MATCHER.addURI(AUTHORITY, "pending", URI_PENDING_MSG);
-
- // Use this pattern to get a list of undelivered messages.
- URI_MATCHER.addURI(AUTHORITY, "undelivered", URI_UNDELIVERED_MSG);
-
- // Use this pattern to see what delivery status reports (for
- // both MMS and SMS) have not been delivered to the user.
- URI_MATCHER.addURI(AUTHORITY, "notifications", URI_NOTIFICATIONS);
-
- URI_MATCHER.addURI(AUTHORITY, "draft", URI_DRAFT);
- initializeColumnSets();
- }
-
- private SQLiteOpenHelper mOpenHelper;
-
- @Override
- public boolean onCreate() {
- mOpenHelper = MmsSmsDatabaseHelper.getInstance(getContext());
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- Cursor cursor = null;
-
- switch(URI_MATCHER.match(uri)) {
- case URI_COMPLETE_CONVERSATIONS:
- cursor = getCompleteConversations(
- projection, selection, selectionArgs, sortOrder);
- break;
- case URI_CONVERSATIONS:
- String simple = uri.getQueryParameter("simple");
- if ((simple != null) && simple.equals("true")) {
- String threadType = uri.getQueryParameter("thread_type");
- if (!TextUtils.isEmpty(threadType)) {
- selection = concatSelections(
- selection, Threads.TYPE + "=" + threadType);
- }
- cursor = getSimpleConversations(
- projection, selection, selectionArgs, sortOrder);
- } else {
- cursor = getConversations(
- projection, selection, selectionArgs, sortOrder);
- }
- break;
- case URI_CONVERSATIONS_MESSAGES:
- cursor = getConversationMessages(
- uri.getPathSegments().get(1), projection, selection,
- selectionArgs, sortOrder);
- break;
- case URI_CONVERSATIONS_RECIPIENTS:
- cursor = getConversationById(
- uri.getPathSegments().get(1), projection, selection,
- selectionArgs, sortOrder);
- break;
- case URI_CONVERSATIONS_SUBJECT:
- cursor = getConversationById(
- uri.getPathSegments().get(1), projection, selection,
- selectionArgs, sortOrder);
- break;
- case URI_MESSAGES_BY_PHONE:
- cursor = getMessagesByPhoneNumber(
- uri.getPathSegments().get(2), projection, selection,
- selectionArgs, sortOrder);
- break;
- case URI_THREAD_ID:
- List<String> recipients = uri.getQueryParameters("recipient");
-
- cursor = getThreadId(recipients);
- break;
- case URI_CANONICAL_ADDRESS: {
- String extraSelection = "_id=" + uri.getPathSegments().get(1);
- String finalSelection = TextUtils.isEmpty(selection)
- ? extraSelection : extraSelection + " AND " + selection;
- cursor = db.query("canonical_addresses",
- new String[] {"address"}, finalSelection, selectionArgs,
- null, null, sortOrder);
- break;
- }
- case URI_PENDING_MSG: {
- String protoName = uri.getQueryParameter("protocol");
- String msgId = uri.getQueryParameter("message");
- int proto = TextUtils.isEmpty(protoName) ? -1
- : (protoName.equals("sms") ? MmsSms.SMS_PROTO : MmsSms.MMS_PROTO);
-
- String extraSelection = (proto != -1) ?
- (PendingMessages.PROTO_TYPE + "=" + proto) : " 0=0 ";
- if (!TextUtils.isEmpty(msgId)) {
- extraSelection += " AND " + PendingMessages.MSG_ID + "=" + msgId;
- }
-
- String finalSelection = TextUtils.isEmpty(selection)
- ? extraSelection : ("(" + extraSelection + ") AND " + selection);
- String finalOrder = TextUtils.isEmpty(sortOrder)
- ? PendingMessages.DUE_TIME : sortOrder;
- cursor = db.query(TABLE_PENDING_MSG, null,
- finalSelection, selectionArgs, null, null, finalOrder);
- break;
- }
- case URI_UNDELIVERED_MSG: {
- cursor = getUndeliveredMessages(projection, selection,
- selectionArgs, sortOrder);
- break;
- }
- case URI_DRAFT: {
- cursor = getDraftThread(projection, selection, selectionArgs, sortOrder);
- break;
- }
- default:
- throw new IllegalStateException("Unrecognized URI:" + uri);
- }
-
- cursor.setNotificationUri(getContext().getContentResolver(), MmsSms.CONTENT_URI);
- return cursor;
- }
-
- /**
- * Return the canonical address ID for this address.
- */
- private long getSingleAddressId(String address) {
- boolean isEmail = Mms.isEmailAddress(address);
- String refinedAddress = isEmail ? address.toLowerCase() : address;
- String selection =
- isEmail
- ? "address = ?"
- : "PHONE_NUMBERS_EQUAL(address, ?)";
- String[] selectionArgs = new String[] { refinedAddress };
- Cursor cursor = null;
-
- try {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- cursor = db.query(
- "canonical_addresses", ID_PROJECTION,
- selection, selectionArgs, null, null, null);
-
- if (cursor.getCount() == 0) {
- ContentValues contentValues = new ContentValues(1);
- contentValues.put(CanonicalAddressesColumns.ADDRESS, refinedAddress);
-
- db = mOpenHelper.getWritableDatabase();
- return db.insert("canonical_addresses",
- CanonicalAddressesColumns.ADDRESS, contentValues);
- }
-
- if (cursor.moveToFirst()) {
- return cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID));
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
-
- return -1L;
- }
-
- /**
- * Return the canonical address IDs for these addresses.
- */
- private Set<Long> getAddressIds(List<String> addresses) {
- Set<Long> result = new HashSet<Long>(addresses.size());
-
- for (String address : addresses) {
- if (!address.equals(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
- long id = getSingleAddressId(address);
- if (id != -1L) {
- result.add(id);
- } else {
- Log.e(LOG_TAG, "Address ID not found for: " + address);
- }
- }
- }
- return result;
- }
-
- /**
- * Return a sorted array of the given Set of Longs.
- */
- private long[] getSortedSet(Set<Long> numbers) {
- int size = numbers.size();
- long[] result = new long[size];
- int i = 0;
-
- for (Long number : numbers) {
- result[i++] = number;
- }
- Arrays.sort(result);
- return result;
- }
-
- /**
- * Return a String of the numbers in the given array, in order,
- * separated by spaces.
- */
- private String getSpaceSeparatedNumbers(long[] numbers) {
- int size = numbers.length;
- StringBuilder buffer = new StringBuilder();
-
- for (int i = 0; i < size; i++) {
- if (i != 0) {
- buffer.append(' ');
- }
- buffer.append(numbers[i]);
- }
- return buffer.toString();
- }
-
- /**
- * Insert a record for a new thread.
- */
- private void insertThread(String recipientIds, int numberOfRecipients) {
- ContentValues values = new ContentValues(4);
-
- long date = System.currentTimeMillis();
- values.put(ThreadsColumns.DATE, date - date % 1000);
- values.put(ThreadsColumns.RECIPIENT_IDS, recipientIds);
- if (numberOfRecipients > 1) {
- values.put(Threads.TYPE, Threads.BROADCAST_THREAD);
- }
- values.put(ThreadsColumns.MESSAGE_COUNT, 0);
-
- mOpenHelper.getWritableDatabase().insert("threads", null, values);
- getContext().getContentResolver().notifyChange(MmsSms.CONTENT_URI, null);
- }
-
- /**
- * Return the thread ID for this list of
- * recipients IDs. If no thread exists with this ID, create
- * one and return it. Callers should always use
- * Threads.getThreadId to access this information.
- */
- private synchronized Cursor getThreadId(List<String> recipients) {
- String recipientIds =
- getSpaceSeparatedNumbers(
- getSortedSet(getAddressIds(recipients)));
- String THREAD_QUERY = "SELECT _id FROM threads " +
- "WHERE recipient_ids = ?";
-
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- Cursor cursor = db.rawQuery(THREAD_QUERY, new String[] { recipientIds });
-
- if (cursor.getCount() == 0) {
- cursor.close();
- insertThread(recipientIds, recipients.size());
- db = mOpenHelper.getReadableDatabase(); // In case insertThread closed it
- cursor = db.rawQuery(THREAD_QUERY, new String[] { recipientIds });
- }
-
- return cursor;
- }
-
- private static String concatSelections(String selection1, String selection2) {
- if (TextUtils.isEmpty(selection1)) {
- return selection2;
- } else if (TextUtils.isEmpty(selection2)) {
- return selection1;
- } else {
- return selection1 + " AND " + selection2;
- }
- }
-
- /**
- * If a null projection is given, return the union of all columns
- * in both the MMS and SMS messages tables. Otherwise, return the
- * given projection.
- */
- private static String[] handleNullMessageProjection(
- String[] projection) {
- return projection == null ? UNION_COLUMNS : projection;
- }
-
- /**
- * If a null projection is given, return the set of all columns in
- * the threads table. Otherwise, return the given projection.
- */
- private static String[] handleNullThreadsProjection(
- String[] projection) {
- return projection == null ? THREADS_COLUMNS : projection;
- }
-
- /**
- * If a null sort order is given, return "normalized_date ASC".
- * Otherwise, return the given sort order.
- */
- private static String handleNullSortOrder (String sortOrder) {
- return sortOrder == null ? "normalized_date ASC" : sortOrder;
- }
-
- /**
- * Return existing threads in the database.
- */
- private Cursor getSimpleConversations(String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- return mOpenHelper.getReadableDatabase().query("threads", projection,
- selection, selectionArgs, null, null, " date DESC");
- }
-
- /**
- * Return the thread which has draft in both MMS and SMS.
- *
- * Use this query:
- *
- * SELECT ...
- * FROM (SELECT _id, thread_id, ...
- * FROM pdu
- * WHERE msg_box = 3 AND ...
- * UNION
- * SELECT _id, thread_id, ...
- * FROM sms
- * WHERE type = 3 AND ...
- * )
- * ;
- */
- private Cursor getDraftThread(String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- String[] innerProjection = new String[] {BaseColumns._ID, Conversations.THREAD_ID};
- SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
- SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
-
- mmsQueryBuilder.setTables(MmsProvider.TABLE_PDU);
- smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
-
- String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerProjection,
- MMS_COLUMNS, 1, "mms",
- concatSelections(selection, Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_DRAFTS),
- selectionArgs, null, null);
- String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerProjection,
- SMS_COLUMNS, 1, "sms",
- concatSelections(selection, Sms.TYPE + "=" + Sms.MESSAGE_TYPE_DRAFT),
- selectionArgs, null, null);
- SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
-
- unionQueryBuilder.setDistinct(true);
-
- String unionQuery = unionQueryBuilder.buildUnionQuery(
- new String[] { mmsSubQuery, smsSubQuery }, null, null);
-
- SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
-
- outerQueryBuilder.setTables("(" + unionQuery + ")");
-
- String outerQuery = outerQueryBuilder.buildQuery(
- projection, null, null, null, null, sortOrder, null);
-
- return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY);
- }
-
- /**
- * Return the most recent message in each conversation in both MMS
- * and SMS.
- *
- * Use this query:
- *
- * SELECT ...
- * FROM (SELECT thread_id AS tid, date * 1000 AS normalized_date, ...
- * FROM pdu
- * WHERE msg_box != 3 AND ...
- * GROUP BY thread_id
- * HAVING date = MAX(date)
- * UNION
- * SELECT thread_id AS tid, date AS normalized_date, ...
- * FROM sms
- * WHERE ...
- * GROUP BY thread_id
- * HAVING date = MAX(date))
- * GROUP BY tid
- * HAVING normalized_date = MAX(normalized_date);
- *
- * The msg_box != 3 comparisons ensure that we don't include draft
- * messages.
- */
- private Cursor getConversations(String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
- SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
-
- mmsQueryBuilder.setTables(MmsProvider.TABLE_PDU);
- smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
-
- String[] columns = handleNullMessageProjection(projection);
- String[] innerMmsProjection = makeProjectionWithDateAndThreadId(
- UNION_COLUMNS, 1000);
- String[] innerSmsProjection = makeProjectionWithDateAndThreadId(
- UNION_COLUMNS, 1);
- String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection,
- MMS_COLUMNS, 1, "mms",
- concatSelections(selection, MMS_CONVERSATION_CONSTRAINT), selectionArgs,
- "thread_id", "date = MAX(date)");
- String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection,
- SMS_COLUMNS, 1, "sms",
- concatSelections(selection, SMS_CONVERSATION_CONSTRAINT), selectionArgs,
- "thread_id", "date = MAX(date)");
- SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
-
- unionQueryBuilder.setDistinct(true);
-
- String unionQuery = unionQueryBuilder.buildUnionQuery(
- new String[] { mmsSubQuery, smsSubQuery }, null, null);
-
- SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
-
- outerQueryBuilder.setTables("(" + unionQuery + ")");
-
- String outerQuery = outerQueryBuilder.buildQuery(
- columns, null, null, "tid",
- "normalized_date = MAX(normalized_date)", sortOrder, null);
-
- return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY);
- }
-
- /**
- * Return every message in each conversation in both MMS
- * and SMS.
- */
- private Cursor getCompleteConversations(String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
- String unionQuery = buildConversationQuery(
- projection, selection, selectionArgs, sortOrder);
-
- return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY);
- }
-
- /**
- * Add normalized date and thread_id to the list of columns for an
- * inner projection. This is necessary so that the outer query
- * can have access to these columns even if the caller hasn't
- * requested them in the result.
- */
- private String[] makeProjectionWithDateAndThreadId(
- String[] projection, int dateMultiple) {
- int projectionSize = projection.length;
- String[] result = new String[projectionSize + 2];
-
- result[0] = "thread_id AS tid";
- result[1] = "date * " + dateMultiple + " AS normalized_date";
- for (int i = 0; i < projectionSize; i++) {
- result[i + 2] = projection[i];
- }
- return result;
- }
-
- /**
- * Return the union of MMS and SMS messages for this thread ID.
- */
- private Cursor getConversationMessages(
- String threadIdString, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- try {
- Long.parseLong(threadIdString);
- } catch (NumberFormatException exception) {
- Log.e(LOG_TAG, "Thread ID must be a Long.");
- return null;
- }
-
- String finalSelection = concatSelections(
- selection, "thread_id = " + threadIdString);
- String unionQuery = buildConversationQuery(
- projection, finalSelection, selectionArgs, sortOrder);
-
- return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY);
- }
-
- /**
- * Return the union of MMS and SMS messages whose recipients
- * included this phone number.
- *
- * Use this query:
- *
- * SELECT ...
- * FROM pdu, (SELECT _id AS address_id
- * FROM addr
- * WHERE PHONE_NUMBERS_EQUAL(addr.address, '<phoneNumber>'))
- * AS matching_addresses
- * WHERE pdu._id = matching_addresses.address_id
- * UNION
- * SELECT ...
- * FROM sms
- * WHERE PHONE_NUMBERS_EQUAL(sms.address, '<phoneNumber>');
- */
- private Cursor getMessagesByPhoneNumber(
- String phoneNumber, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- String escapedPhoneNumber = DatabaseUtils.sqlEscapeString(phoneNumber);
- String finalMmsSelection =
- concatSelections(
- selection,
- "pdu._id = matching_addresses.address_id");
- String finalSmsSelection =
- concatSelections(
- selection,
- "PHONE_NUMBERS_EQUAL(address, " +
- escapedPhoneNumber + ")");
- SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
- SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
-
- mmsQueryBuilder.setDistinct(true);
- smsQueryBuilder.setDistinct(true);
- mmsQueryBuilder.setTables(
- MmsProvider.TABLE_PDU +
- ", (SELECT _id AS address_id " +
- "FROM addr WHERE PHONE_NUMBERS_EQUAL(addr.address, " +
- escapedPhoneNumber + ")) " +
- "AS matching_addresses");
- smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
-
- String[] columns = handleNullMessageProjection(projection);
- String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, columns, MMS_COLUMNS,
- 0, "mms", finalMmsSelection, selectionArgs, null, null);
- String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, columns, SMS_COLUMNS,
- 0, "sms", finalSmsSelection, selectionArgs, null, null);
- SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
-
- unionQueryBuilder.setDistinct(true);
-
- String unionQuery = unionQueryBuilder.buildUnionQuery(
- new String[] { mmsSubQuery, smsSubQuery }, sortOrder, null);
-
- return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY);
- }
-
- /**
- * Return the conversation of certain thread ID.
- */
- private Cursor getConversationById(
- String threadIdString, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- try {
- Long.parseLong(threadIdString);
- } catch (NumberFormatException exception) {
- Log.e(LOG_TAG, "Thread ID must be a Long.");
- return null;
- }
-
- String extraSelection = "_id=" + threadIdString;
- String finalSelection = concatSelections(selection, extraSelection);
- SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
- String[] columns = handleNullThreadsProjection(projection);
-
- queryBuilder.setDistinct(true);
- queryBuilder.setTables("threads");
- return queryBuilder.query(
- mOpenHelper.getReadableDatabase(), columns, finalSelection,
- selectionArgs, sortOrder, null, null);
- }
-
- private static String joinPduAndPendingMsgTables() {
- return MmsProvider.TABLE_PDU + " LEFT JOIN " + TABLE_PENDING_MSG
- + " ON pdu._id = pending_msgs.msg_id";
- }
-
- private static String[] createMmsProjection(String[] old) {
- String[] newProjection = new String[old.length];
- for (int i = 0; i < old.length; i++) {
- if (old[i].equals(BaseColumns._ID)) {
- newProjection[i] = "pdu._id";
- } else {
- newProjection[i] = old[i];
- }
- }
- return newProjection;
- }
-
- private Cursor getUndeliveredMessages(
- String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- String[] mmsProjection = createMmsProjection(projection);
-
- SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
- SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
-
- mmsQueryBuilder.setTables(joinPduAndPendingMsgTables());
- smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
-
- String finalMmsSelection = concatSelections(
- selection, Mms.MESSAGE_BOX + " = " + Mms.MESSAGE_BOX_OUTBOX);
- String finalSmsSelection = concatSelections(
- selection, "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_OUTBOX
- + " OR " + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_FAILED
- + " OR " + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_QUEUED + ")");
-
- String[] smsColumns = handleNullMessageProjection(projection);
- String[] mmsColumns = handleNullMessageProjection(mmsProjection);
- String[] innerMmsProjection = makeProjectionWithDateAndThreadId(
- mmsColumns, 1000);
- String[] innerSmsProjection = makeProjectionWithDateAndThreadId(
- smsColumns, 1);
-
- Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS);
- columnsPresentInTable.add("pdu._id");
- columnsPresentInTable.add(PendingMessages.ERROR_TYPE);
- String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection,
- columnsPresentInTable, 1, "mms", finalMmsSelection, selectionArgs,
- null, null);
- String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection,
- SMS_COLUMNS, 1, "sms", finalSmsSelection, selectionArgs,
- null, null);
- SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
-
- unionQueryBuilder.setDistinct(true);
-
- String unionQuery = unionQueryBuilder.buildUnionQuery(
- new String[] { smsSubQuery, mmsSubQuery }, null, null);
-
- SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
-
- outerQueryBuilder.setTables("(" + unionQuery + ")");
-
- String outerQuery = outerQueryBuilder.buildQuery(
- smsColumns, null, null, null, null, sortOrder, null);
-
- return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY);
- }
-
- /**
- * Add normalized date to the list of columns for an inner
- * projection.
- */
- private static String[] makeProjectionWithNormalizedDate(
- String[] projection, int dateMultiple) {
- int projectionSize = projection.length;
- String[] result = new String[projectionSize + 1];
-
- result[0] = "date * " + dateMultiple + " AS normalized_date";
- System.arraycopy(projection, 0, result, 1, projectionSize);
- return result;
- }
-
- private static String buildConversationQuery(String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
- String[] mmsProjection = createMmsProjection(projection);
-
- SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
- SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
-
- mmsQueryBuilder.setDistinct(true);
- smsQueryBuilder.setDistinct(true);
- mmsQueryBuilder.setTables(joinPduAndPendingMsgTables());
- smsQueryBuilder.setTables(SmsProvider.TABLE_SMS);
-
- String[] smsColumns = handleNullMessageProjection(projection);
- String[] mmsColumns = handleNullMessageProjection(mmsProjection);
- String[] innerMmsProjection = makeProjectionWithNormalizedDate(mmsColumns, 1000);
- String[] innerSmsProjection = makeProjectionWithNormalizedDate(smsColumns, 1);
-
- Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS);
- columnsPresentInTable.add("pdu._id");
- columnsPresentInTable.add(PendingMessages.ERROR_TYPE);
-
- String mmsSelection = concatSelections(selection,
- Mms.MESSAGE_BOX + " != " + Mms.MESSAGE_BOX_DRAFTS);
- String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection,
- columnsPresentInTable, 0, "mms",
- concatSelections(mmsSelection, MMS_CONVERSATION_CONSTRAINT),
- selectionArgs, null, null);
- String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
- MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, SMS_COLUMNS,
- 0, "sms", concatSelections(selection, SMS_CONVERSATION_CONSTRAINT),
- selectionArgs, null, null);
- SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
-
- unionQueryBuilder.setDistinct(true);
-
- String unionQuery = unionQueryBuilder.buildUnionQuery(
- new String[] { smsSubQuery, mmsSubQuery },
- handleNullSortOrder(sortOrder), null);
-
- SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
-
- outerQueryBuilder.setTables("(" + unionQuery + ")");
-
- return outerQueryBuilder.buildQuery(
- smsColumns, null, null, null, null, sortOrder, null);
- }
-
- @Override
- public String getType(Uri uri) {
- return VND_ANDROID_DIR_MMS_SMS;
- }
-
- @Override
- public int delete(Uri uri, String selection,
- String[] selectionArgs) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- Context context = getContext();
- int affectedRows = 0;
-
- switch(URI_MATCHER.match(uri)) {
- case URI_CONVERSATIONS_MESSAGES:
- long threadId;
- try {
- threadId = Long.parseLong(uri.getLastPathSegment());
- } catch (NumberFormatException e) {
- Log.e(LOG_TAG, "Thread ID must be a long.");
- break;
- }
- affectedRows = deleteConversation(uri, selection, selectionArgs);
- MmsSmsDatabaseHelper.updateThread(db, threadId);
- break;
- case URI_CONVERSATIONS:
- affectedRows = MmsProvider.deleteMessages(context, db,
- selection, selectionArgs, uri)
- + db.delete("sms", selection, selectionArgs);
- MmsSmsDatabaseHelper.updateAllThreads(db, selection, selectionArgs);
- break;
- case URI_OBSOLETE_THREADS:
- affectedRows = db.delete("threads",
- "_id NOT IN (SELECT DISTINCT thread_id FROM sms " +
- "UNION SELECT DISTINCT thread_id FROM pdu)", null);
- break;
- default:
- throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES);
- }
-
- if (affectedRows > 0) {
- context.getContentResolver().notifyChange(MmsSms.CONTENT_URI, null);
- }
- return affectedRows;
- }
-
- /**
- * Delete the conversation with the given thread ID.
- */
- private int deleteConversation(Uri uri, String selection, String[] selectionArgs) {
- String threadId = uri.getLastPathSegment();
-
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String finalSelection = concatSelections(selection, "thread_id = " + threadId);
- return MmsProvider.deleteMessages(getContext(), db, finalSelection,
- selectionArgs, uri)
- + db.delete("sms", finalSelection, selectionArgs);
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES);
- }
-
- @Override
- public int update(Uri uri, ContentValues values,
- String selection, String[] selectionArgs) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int affectedRows = 0;
- switch(URI_MATCHER.match(uri)) {
- case URI_CONVERSATIONS_MESSAGES:
- String threadIdString = uri.getPathSegments().get(1);
- affectedRows = updateConversation(threadIdString, values,
- selection, selectionArgs);
- break;
- case URI_PENDING_MSG:
- affectedRows = db.update(TABLE_PENDING_MSG, values, selection, null);
- break;
- default:
- throw new UnsupportedOperationException(
- NO_DELETES_INSERTS_OR_UPDATES);
- }
-
- if (affectedRows > 0) {
- getContext().getContentResolver().notifyChange(
- MmsSms.CONTENT_URI, null);
- }
- return affectedRows;
- }
-
- private int updateConversation(
- String threadIdString, ContentValues values, String selection,
- String[] selectionArgs) {
- try {
- Long.parseLong(threadIdString);
- } catch (NumberFormatException exception) {
- Log.e(LOG_TAG, "Thread ID must be a Long.");
- return 0;
- }
-
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String finalSelection = concatSelections(selection, "thread_id=" + threadIdString);
- return db.update(MmsProvider.TABLE_PDU, values, finalSelection, selectionArgs)
- + db.update("sms", values, finalSelection, selectionArgs);
- }
-
- /**
- * Construct Sets of Strings containing exactly the columns
- * present in each table. We will use this when constructing
- * UNION queries across the MMS and SMS tables.
- */
- private static void initializeColumnSets() {
- int commonColumnCount = MMS_SMS_COLUMNS.length;
- int mmsOnlyColumnCount = MMS_ONLY_COLUMNS.length;
- int smsOnlyColumnCount = SMS_ONLY_COLUMNS.length;
- Set<String> unionColumns = new HashSet<String>();
-
- for (int i = 0; i < commonColumnCount; i++) {
- MMS_COLUMNS.add(MMS_SMS_COLUMNS[i]);
- SMS_COLUMNS.add(MMS_SMS_COLUMNS[i]);
- unionColumns.add(MMS_SMS_COLUMNS[i]);
- }
- for (int i = 0; i < mmsOnlyColumnCount; i++) {
- MMS_COLUMNS.add(MMS_ONLY_COLUMNS[i]);
- unionColumns.add(MMS_ONLY_COLUMNS[i]);
- }
- for (int i = 0; i < smsOnlyColumnCount; i++) {
- SMS_COLUMNS.add(SMS_ONLY_COLUMNS[i]);
- unionColumns.add(SMS_ONLY_COLUMNS[i]);
- }
-
- int i = 0;
- for (String columnName : unionColumns) {
- UNION_COLUMNS[i++] = columnName;
- }
- }
-}
diff --git a/src/com/android/providers/telephony/SmsProvider.java b/src/com/android/providers/telephony/SmsProvider.java
deleted file mode 100644
index 56b39de..0000000
--- a/src/com/android/providers/telephony/SmsProvider.java
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.providers.telephony;
-
-import android.content.ContentProvider;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.UriMatcher;
-import com.android.internal.database.ArrayListCursor;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.provider.Contacts;
-import android.provider.Telephony.Mms;
-import android.provider.Telephony.MmsSms;
-import android.provider.Telephony.Sms;
-import android.provider.Telephony.TextBasedSmsColumns;
-import android.provider.Telephony.Threads;
-import android.telephony.gsm.SmsManager;
-import android.telephony.gsm.SmsMessage;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class SmsProvider extends ContentProvider {
- private static final Uri NOTIFICATION_URI = Uri.parse("content://sms");
- private static final Uri SIM_URI = Uri.parse("content://sms/sim");
- static final String TABLE_SMS = "sms";
-
- private static final Integer ONE = Integer.valueOf(1);
-
- /**
- * These are the columns that are available when reading SMS
- * messages from the SIM. Columns whose names begin with "is_"
- * have either "true" or "false" as their values.
- */
- private final static String[] SIM_COLUMNS = new String[] {
- // N.B.: These columns must appear in the same order as the
- // calls to add appear in convertSimToSms.
- "service_center_address", // getServiceCenterAddress
- "address", // getDisplayOriginatingAddress
- "message_class", // getMessageClass
- "body", // getDisplayMessageBody
- "date", // getTimestampMillis
- "status", // getStatusOnSim
- "index_on_sim", // getIndexOnSim
- "is_status_report", // isStatusReportMessage
- "transport_type", // Always "sms".
- "type" // Always MESSAGE_TYPE_ALL.
- };
-
- @Override
- public boolean onCreate() {
- mOpenHelper = MmsSmsDatabaseHelper.getInstance(getContext());
- return true;
- }
-
- @Override
- public Cursor query(Uri url, String[] projectionIn, String selection,
- String[] selectionArgs, String sort) {
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
- // Generate the body of the query.
- int match = sURLMatcher.match(url);
- switch (match) {
- case SMS_ALL:
- constructQueryForBox(qb, Sms.MESSAGE_TYPE_ALL);
- break;
-
- case SMS_UNDELIVERED:
- constructQueryForUndelivered(qb);
- break;
-
- case SMS_FAILED:
- constructQueryForBox(qb, Sms.MESSAGE_TYPE_FAILED);
- break;
-
- case SMS_QUEUED:
- constructQueryForBox(qb, Sms.MESSAGE_TYPE_QUEUED);
- break;
-
- case SMS_INBOX:
- constructQueryForBox(qb, Sms.MESSAGE_TYPE_INBOX);
- break;
-
- case SMS_SENT:
- constructQueryForBox(qb, Sms.MESSAGE_TYPE_SENT);
- break;
-
- case SMS_DRAFT:
- constructQueryForBox(qb, Sms.MESSAGE_TYPE_DRAFT);
- break;
-
- case SMS_OUTBOX:
- constructQueryForBox(qb, Sms.MESSAGE_TYPE_OUTBOX);
- break;
-
- case SMS_ALL_ID:
- qb.setTables(TABLE_SMS);
- qb.appendWhere("(_id = " + url.getPathSegments().get(0) + ")");
- break;
-
- case SMS_INBOX_ID:
- case SMS_FAILED_ID:
- case SMS_SENT_ID:
- case SMS_DRAFT_ID:
- case SMS_OUTBOX_ID:
- qb.setTables(TABLE_SMS);
- qb.appendWhere("(_id = " + url.getPathSegments().get(1) + ")");
- break;
-
- case SMS_CONVERSATIONS_ID:
- int threadID;
-
- try {
- threadID = Integer.parseInt(url.getPathSegments().get(1));
- if (Config.LOGD) {
- Log.d(TAG, "query conversations: threadID=" + threadID);
- }
- }
- catch (Exception ex) {
- Log.e(TAG,
- "Bad conversation thread id: "
- + url.getPathSegments().get(1));
- return null;
- }
-
- qb.setTables(TABLE_SMS);
- qb.appendWhere("thread_id = " + threadID);
- break;
-
- case SMS_CONVERSATIONS:
- qb.setTables("sms, (SELECT thread_id AS group_thread_id, MAX(date) AS group_date, COUNT(*) AS msg_count FROM sms GROUP BY thread_id) AS groups");
- qb.appendWhere("sms.thread_id = groups.group_thread_id AND sms.date = groups.group_date");
- qb.setProjectionMap(sConversationProjectionMap);
- break;
-
- case SMS_RAW_MESSAGE:
- qb.setTables("raw");
- break;
-
- case SMS_STATUS_PENDING:
- qb.setTables("sr_pending");
- break;
-
- case SMS_ATTACHMENT:
- qb.setTables("attachments");
- break;
-
- case SMS_ATTACHMENT_ID:
- qb.setTables("attachments");
- qb.appendWhere(
- "(sms_id = " + url.getPathSegments().get(1) + ")");
- break;
-
- case SMS_QUERY_THREAD_ID:
- qb.setTables("canonical_addresses");
- if (projectionIn == null) {
- projectionIn = sIDProjection;
- }
- break;
-
- case SMS_STATUS_ID:
- qb.setTables(TABLE_SMS);
- qb.appendWhere("(_id = " + url.getPathSegments().get(1) + ")");
- break;
-
- case SMS_ALL_SIM:
- return getAllMessagesFromSim();
-
- case SMS_SIM:
- String messageIndexString = url.getPathSegments().get(1);
-
- return getSingleMessageFromSim(messageIndexString);
-
- default:
- Log.e(TAG, "Invalid request: " + url);
- return null;
- }
-
- String orderBy = null;
-
- if (!TextUtils.isEmpty(sort)) {
- orderBy = sort;
- } else if (qb.getTables().equals(TABLE_SMS)) {
- orderBy = Sms.DEFAULT_SORT_ORDER;
- }
-
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- Cursor ret = qb.query(db, projectionIn, selection, selectionArgs,
- null, null, orderBy);
-
- // TODO: Since the URLs are a mess, always use content://sms
- ret.setNotificationUri(getContext().getContentResolver(),
- NOTIFICATION_URI);
- return ret;
- }
-
- private ArrayList<String> convertSimToSms(SmsMessage message) {
- ArrayList result = new ArrayList();
-
- // N.B.: These calls must appear in the same order as the
- // columns appear in SIM_COLUMNS.
- result.add(message.getServiceCenterAddress());
- result.add(message.getDisplayOriginatingAddress());
- result.add(message.getMessageClass().toString());
- result.add(message.getDisplayMessageBody());
- result.add(message.getTimestampMillis());
- result.add(Sms.STATUS_NONE);
- result.add(message.getIndexOnSim());
- result.add(message.isStatusReportMessage());
- result.add("sms");
- result.add(TextBasedSmsColumns.MESSAGE_TYPE_ALL);
- return result;
- }
-
- /**
- * Return a Cursor containing just one message from the SIM.
- */
- private Cursor getSingleMessageFromSim(String messageIndexString) {
- try {
- int messageIndex = Integer.parseInt(messageIndexString);
- SmsManager smsManager = SmsManager.getDefault();
- ArrayList<SmsMessage> messages = smsManager.getAllMessagesFromSim();
- ArrayList<ArrayList> singleRow = new ArrayList<ArrayList>();
-
- singleRow.add(convertSimToSms(messages.get(messageIndex)));
- return withSimNotificationUri(
- new ArrayListCursor(SIM_COLUMNS, singleRow));
- } catch (NumberFormatException exception) {
- throw new IllegalArgumentException(
- "Bad SMS SIM ID: " + messageIndexString);
- }
- }
-
- /**
- * Return a Cursor listing all the messages stored on the SIM.
- */
- private Cursor getAllMessagesFromSim() {
- SmsManager smsManager = SmsManager.getDefault();
- ArrayList<SmsMessage> messages = smsManager.getAllMessagesFromSim();
- ArrayList<ArrayList> rows = new ArrayList<ArrayList>();
-
- for (int count = messages.size(), i = 0; i < count; i++) {
- rows.add(convertSimToSms(messages.get(i)));
- }
- return withSimNotificationUri(new ArrayListCursor(SIM_COLUMNS, rows));
- }
-
- private Cursor withSimNotificationUri(Cursor cursor) {
- cursor.setNotificationUri(getContext().getContentResolver(),
- SIM_URI);
- return cursor;
- }
-
- private void constructQueryForBox(SQLiteQueryBuilder qb, int type) {
- qb.setTables(TABLE_SMS);
-
- if (type != Sms.MESSAGE_TYPE_ALL) {
- qb.appendWhere("type=" + type);
- }
- }
-
- private void constructQueryForUndelivered(SQLiteQueryBuilder qb) {
- qb.setTables(TABLE_SMS);
-
- qb.appendWhere("(type=" + Sms.MESSAGE_TYPE_OUTBOX +
- " OR type=" + Sms.MESSAGE_TYPE_FAILED +
- " OR type=" + Sms.MESSAGE_TYPE_QUEUED + ")");
- }
-
- @Override
- public String getType(Uri url) {
- switch (url.getPathSegments().size()) {
- case 0:
- return VND_ANDROID_DIR_SMS;
- case 1:
- try {
- Integer.parseInt(url.getPathSegments().get(0));
- return VND_ANDROID_SMS;
- } catch (NumberFormatException ex) {
- return VND_ANDROID_DIR_SMS;
- }
- case 2:
- // TODO: What about "threadID"?
- if (url.getPathSegments().get(0).equals("conversations")) {
- return VND_ANDROID_SMSCHAT;
- } else {
- return VND_ANDROID_SMS;
- }
- }
- return null;
- }
-
- @Override
- public Uri insert(Uri url, ContentValues initialValues) {
- ContentValues values;
- long rowID;
- int type = Sms.MESSAGE_TYPE_ALL;
-
- int match = sURLMatcher.match(url);
- if (Config.LOGD) {
- Log.d(TAG, "insert url=" + url + ", match=" + match);
- }
-
- String table = TABLE_SMS;
-
- switch (match) {
- case SMS_ALL:
- Integer typeObj = initialValues.getAsInteger(Sms.TYPE);
- if (typeObj != null) {
- type = typeObj.intValue();
- } else {
- // default to inbox
- type = Sms.MESSAGE_TYPE_INBOX;
- }
- break;
-
- case SMS_INBOX:
- type = Sms.MESSAGE_TYPE_INBOX;
- break;
-
- case SMS_FAILED:
- type = Sms.MESSAGE_TYPE_FAILED;
- break;
-
- case SMS_QUEUED:
- type = Sms.MESSAGE_TYPE_QUEUED;
- break;
-
- case SMS_SENT:
- type = Sms.MESSAGE_TYPE_SENT;
- break;
-
- case SMS_DRAFT:
- type = Sms.MESSAGE_TYPE_DRAFT;
- break;
-
- case SMS_OUTBOX:
- type = Sms.MESSAGE_TYPE_OUTBOX;
- break;
-
- case SMS_RAW_MESSAGE:
- table = "raw";
- break;
-
- case SMS_STATUS_PENDING:
- table = "sr_pending";
- break;
-
- case SMS_ATTACHMENT:
- table = "attachments";
- break;
-
- case SMS_NEW_THREAD_ID:
- table = "canonical_addresses";
- break;
-
- default:
- Log.e(TAG, "Invalid request: " + url);
- return null;
- }
-
- if (table.equals(TABLE_SMS)) {
- boolean addDate = false;
- boolean addType = false;
-
- // Make sure that the date and type are set
- if (initialValues == null) {
- values = new ContentValues(1);
- addDate = true;
- addType = true;
- } else {
- values = new ContentValues(initialValues);
-
- if (!initialValues.containsKey(Sms.DATE)) {
- addDate = true;
- }
-
- if (!initialValues.containsKey(Sms.TYPE)) {
- addType = true;
- }
- }
-
- if (addDate) {
- values.put(Sms.DATE, new Long(System.currentTimeMillis()));
- }
-
- if (addType && (type != Sms.MESSAGE_TYPE_ALL)) {
- values.put(Sms.TYPE, Integer.valueOf(type));
- }
-
- // thread_id
- Long threadId = values.getAsLong(Sms.THREAD_ID);
- String address = values.getAsString(Sms.ADDRESS);
-
- if (((threadId == null) || (threadId == 0)) && (address != null)) {
- values.put(Sms.THREAD_ID, Threads.getOrCreateThreadId(
- getContext(), address));
- }
-
- if (type == Sms.MESSAGE_TYPE_INBOX) {
- // Look up the person if not already filled in.
- if ((values.getAsLong(Sms.PERSON) == null)
- && (!TextUtils.isEmpty(address))) {
- Cursor cursor = getContext().getContentResolver().query(
- Uri.withAppendedPath(
- Contacts.Phones.CONTENT_FILTER_URL, address),
- new String[] { Contacts.Phones.PERSON_ID },
- null, null, null);
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- cursor.moveToFirst();
- Long id = Long.valueOf(cursor.getLong(0));
- values.put(Sms.PERSON, id);
- }
- cursor.deactivate();
- }
- }
- } else {
- // Mark all non-inbox messages read.
- values.put(Sms.READ, ONE);
- }
- } else {
- if (initialValues == null) {
- values = new ContentValues(1);
- } else {
- values = initialValues;
- }
- }
-
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- rowID = db.insert(table, "body", values);
- if (rowID > 0) {
- Uri uri = Uri.parse("content://" + table + "/" + rowID);
- notifyChange(uri);
- return uri;
- } else {
- Log.e(TAG,
- "SmsProvider.insert: failed! " + values.toString());
- }
-
- return null;
- }
-
- @Override
- public int delete(Uri url, String where, String[] whereArgs) {
- int count;
- int match = sURLMatcher.match(url);
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- switch (match) {
- case SMS_ALL:
- count = db.delete(TABLE_SMS, where, whereArgs);
- if (count != 0) {
- // Don't update threads unless something changed.
- MmsSmsDatabaseHelper.updateAllThreads(db, where, whereArgs);
- }
- break;
-
- case SMS_ALL_ID:
- try {
- int message_id = Integer.parseInt(url.getPathSegments().get(0));
- count = MmsSmsDatabaseHelper.deleteOneSms(db, message_id);
- } catch (Exception e) {
- throw new IllegalArgumentException(
- "Bad message id: " + url.getPathSegments().get(0));
- }
- break;
-
- case SMS_CONVERSATIONS_ID:
- int threadID;
-
- try {
- threadID = Integer.parseInt(url.getPathSegments().get(1));
- } catch (Exception ex) {
- throw new IllegalArgumentException(
- "Bad conversation thread id: "
- + url.getPathSegments().get(1));
- }
-
- // delete the messages from the sms table
- where = DatabaseUtils.concatenateWhere("thread_id=" + threadID, where);
- count = db.delete(TABLE_SMS, where, whereArgs);
- MmsSmsDatabaseHelper.updateThread(db, threadID);
- break;
-
- case SMS_RAW_MESSAGE:
- count = db.delete("raw", where, whereArgs);
- break;
-
- case SMS_STATUS_PENDING:
- count = db.delete("sr_pending", where, whereArgs);
- break;
-
- case SMS_SIM:
- String messageIndexString = url.getPathSegments().get(1);
-
- return deleteMessageFromSim(messageIndexString);
-
- default:
- throw new IllegalArgumentException("Unknown URL");
- }
-
- if (count > 0) {
- notifyChange(url);
- }
- return count;
- }
-
- /**
- * Delete the message at index from SIM. Return true iff
- * successful.
- */
- private int deleteMessageFromSim(String messageIndexString) {
- SmsManager smsManager = SmsManager.getDefault();
-
- try {
- return smsManager.deleteMessageFromSim(
- Integer.parseInt(messageIndexString))
- ? 1 : 0;
- } catch (NumberFormatException exception) {
- throw new IllegalArgumentException(
- "Bad SMS SIM ID: " + messageIndexString);
- } finally {
- ContentResolver cr = getContext().getContentResolver();
-
- cr.notifyChange(SIM_URI, null);
- }
- }
-
- @Override
- public int update(
- Uri url, ContentValues values, String where, String[] whereArgs) {
- int count = 0;
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- switch (sURLMatcher.match(url)) {
- case SMS_RAW_MESSAGE:
- count = db.update("raw", values, where, whereArgs);
- break;
-
- case SMS_STATUS_PENDING:
- count = db.update("sr_pending", values, where, whereArgs);
- break;
-
- case SMS_ALL:
- case SMS_FAILED:
- case SMS_QUEUED:
- case SMS_INBOX:
- case SMS_SENT:
- case SMS_DRAFT:
- case SMS_OUTBOX:
- case SMS_CONVERSATIONS:
- count = db.update(
- TABLE_SMS, values, where, whereArgs);
- break;
-
- case SMS_ALL_ID:
- if (where != null) {
- throw new UnsupportedOperationException(
- "WHERE not supported");
- }
- count = db.update(TABLE_SMS, values, "_id="
- + url.getPathSegments().get(0), null);
- break;
-
- case SMS_INBOX_ID:
- case SMS_FAILED_ID:
- case SMS_SENT_ID:
- case SMS_DRAFT_ID:
- case SMS_OUTBOX_ID:
- if (where != null) {
- throw new UnsupportedOperationException(
- "WHERE not supported for this URI");
- }
- count = db.update(TABLE_SMS, values, "_id="
- + url.getPathSegments().get(1), null);
- break;
-
- case SMS_CONVERSATIONS_ID: {
- int threadId;
-
- try {
- threadId = Integer.parseInt(url.getPathSegments().get(1));
- } catch (Exception ex) {
- Log.e(TAG, "Bad conversation thread id: "
- + url.getPathSegments().get(1));
- count = 0;
- break;
- }
-
- if (where != null) {
- throw new UnsupportedOperationException(
- "WHERE not supported for this URI");
- }
- count = db.update(
- TABLE_SMS, values, "thread_id = " + threadId,
- null);
- break;
- }
-
- case SMS_STATUS_ID:
- String idString = url.getPathSegments().get(1);
-
- count = db.update(TABLE_SMS, values, "_id=" + idString, null);
- break;
-
- default:
- throw new UnsupportedOperationException(
- "URI " + url + " not supported");
- }
-
- if (count > 0) {
- notifyChange(url);
- }
- return count;
- }
-
- private void notifyChange(Uri uri) {
- ContentResolver cr = getContext().getContentResolver();
- cr.notifyChange(uri, null);
- cr.notifyChange(MmsSms.CONTENT_URI, null);
- cr.notifyChange(Uri.parse("content://mms-sms/conversations/"), null);
- }
-
- private SQLiteOpenHelper mOpenHelper;
-
- private final static String TAG = "SmsProvider";
- private final static String VND_ANDROID_SMS = "vnd.android.cursor.item/sms";
- private final static String VND_ANDROID_SMSCHAT =
- "vnd.android.cursor.item/sms-chat";
- private final static String VND_ANDROID_DIR_SMS =
- "vnd.android.cursor.dir/sms";
-
- private static final HashMap<String, String> sConversationProjectionMap =
- new HashMap<String, String>();
- private static final String[] sIDProjection = new String[] { "_id" };
-
- private static final int SMS_ALL = 0;
- private static final int SMS_ALL_ID = 1;
- private static final int SMS_INBOX = 2;
- private static final int SMS_INBOX_ID = 3;
- private static final int SMS_SENT = 4;
- private static final int SMS_SENT_ID = 5;
- private static final int SMS_DRAFT = 6;
- private static final int SMS_DRAFT_ID = 7;
- private static final int SMS_OUTBOX = 8;
- private static final int SMS_OUTBOX_ID = 9;
- private static final int SMS_CONVERSATIONS = 10;
- private static final int SMS_CONVERSATIONS_ID = 11;
- private static final int SMS_RAW_MESSAGE = 15;
- private static final int SMS_ATTACHMENT = 16;
- private static final int SMS_ATTACHMENT_ID = 17;
- private static final int SMS_NEW_THREAD_ID = 18;
- private static final int SMS_QUERY_THREAD_ID = 19;
- private static final int SMS_STATUS_ID = 20;
- private static final int SMS_STATUS_PENDING = 21;
- private static final int SMS_ALL_SIM = 22;
- private static final int SMS_SIM = 23;
- private static final int SMS_FAILED = 24;
- private static final int SMS_FAILED_ID = 25;
- private static final int SMS_QUEUED = 26;
- private static final int SMS_UNDELIVERED = 27;
-
- private static final UriMatcher sURLMatcher =
- new UriMatcher(UriMatcher.NO_MATCH);
-
- static {
- sURLMatcher.addURI("sms", null, SMS_ALL);
- sURLMatcher.addURI("sms", "#", SMS_ALL_ID);
- sURLMatcher.addURI("sms", "inbox", SMS_INBOX);
- sURLMatcher.addURI("sms", "inbox/#", SMS_INBOX_ID);
- sURLMatcher.addURI("sms", "sent", SMS_SENT);
- sURLMatcher.addURI("sms", "sent/#", SMS_SENT_ID);
- sURLMatcher.addURI("sms", "draft", SMS_DRAFT);
- sURLMatcher.addURI("sms", "draft/#", SMS_DRAFT_ID);
- sURLMatcher.addURI("sms", "outbox", SMS_OUTBOX);
- sURLMatcher.addURI("sms", "outbox/#", SMS_OUTBOX_ID);
- sURLMatcher.addURI("sms", "undelivered", SMS_UNDELIVERED);
- sURLMatcher.addURI("sms", "failed", SMS_FAILED);
- sURLMatcher.addURI("sms", "failed/#", SMS_FAILED_ID);
- sURLMatcher.addURI("sms", "queued", SMS_QUEUED);
- sURLMatcher.addURI("sms", "conversations", SMS_CONVERSATIONS);
- sURLMatcher.addURI("sms", "conversations/*", SMS_CONVERSATIONS_ID);
- sURLMatcher.addURI("sms", "raw", SMS_RAW_MESSAGE);
- sURLMatcher.addURI("sms", "attachments", SMS_ATTACHMENT);
- sURLMatcher.addURI("sms", "attachments/#", SMS_ATTACHMENT_ID);
- sURLMatcher.addURI("sms", "threadID", SMS_NEW_THREAD_ID);
- sURLMatcher.addURI("sms", "threadID/*", SMS_QUERY_THREAD_ID);
- sURLMatcher.addURI("sms", "status/#", SMS_STATUS_ID);
- sURLMatcher.addURI("sms", "sr_pending", SMS_STATUS_PENDING);
- sURLMatcher.addURI("sms", "sim", SMS_ALL_SIM);
- sURLMatcher.addURI("sms", "sim/#", SMS_SIM);
-
- sConversationProjectionMap.put(Sms.Conversations.SNIPPET,
- "body AS snippet");
- sConversationProjectionMap.put("delta", null);
- }
-}
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
deleted file mode 100644
index 95018be..0000000
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ /dev/null
@@ -1,497 +0,0 @@
-/* //device/content/providers/telephony/TelephonyProvider.java
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package com.android.providers.telephony;
-
-import android.content.*;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.Telephony;
-import android.util.Config;
-import android.util.Log;
-import android.util.Xml;
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-
-public class TelephonyProvider extends ContentProvider
-{
- private static final String DATABASE_NAME = "telephony.db";
- // DATABASE_VERSION needs to be in-sync with version in apns.xml.
- private static final int DATABASE_VERSION = 4 << 16;
- private static final int URL_TELEPHONY = 1;
- private static final int URL_CURRENT = 2;
- private static final int URL_ID = 3;
-
- private static final String TAG = "TelephonyProvider";
- private static final String CARRIERS_TABLE = "carriers";
- private static final String PARTNER_APNS_PATH = "etc/apns-conf.xml";
-
- private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-
- private static final ContentValues s_currentNullMap;
- private static final ContentValues s_currentSetMap;
-
- static {
- s_urlMatcher.addURI("telephony", "carriers", URL_TELEPHONY);
- s_urlMatcher.addURI("telephony", "carriers/current", URL_CURRENT);
- s_urlMatcher.addURI("telephony", "carriers/#", URL_ID);
-
- s_currentNullMap = new ContentValues(1);
- s_currentNullMap.put("current", (Long) null);
-
- s_currentSetMap = new ContentValues(1);
- s_currentSetMap.put("current", "1");
- }
-
- private static class DatabaseHelper extends SQLiteOpenHelper {
- // Context to access resources with
- private Context mContext;
-
- /**
- * DatabaseHelper helper class for loading apns into a database.
- *
- * @param parser the system-default parser for apns.xml
- * @param confidential an optional parser for confidential APNS (stored separately)
- */
- public DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, getVersion(context));
- mContext = context;
- }
-
- private static int getVersion(Context context) {
- // Get the database version, combining a static schema version and the XML version
- Resources r = context.getResources();
- XmlResourceParser parser = r.getXml(com.android.internal.R.xml.apns);
- try {
- XmlUtils.beginDocument(parser, "apns");
- int publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
- return DATABASE_VERSION | publicversion;
- } catch (Exception e) {
- Log.e(TAG, "Can't get version of APN database", e);
- return DATABASE_VERSION;
- } finally {
- parser.close();
- }
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- // Set up the database schema
- db.execSQL("CREATE TABLE " + CARRIERS_TABLE +
- "(_id INTEGER PRIMARY KEY," +
- "name TEXT," +
- "numeric TEXT," +
- "mcc TEXT," +
- "mnc TEXT," +
- "apn TEXT," +
- "user TEXT," +
- "server TEXT," +
- "password TEXT," +
- "proxy TEXT," +
- "port TEXT," +
- "mmsproxy TEXT," +
- "mmsport TEXT," +
- "mmsc TEXT," +
- "type TEXT," +
- "current INTEGER);");
-
- // Read internal APNS data
- Resources r = mContext.getResources();
- XmlResourceParser parser = r.getXml(com.android.internal.R.xml.apns);
- int publicversion = -1;
- try {
- XmlUtils.beginDocument(parser, "apns");
- publicversion = Integer.parseInt(parser.getAttributeValue(null, "version"));
- loadApns(db, parser);
- } catch (Exception e) {
- Log.e(TAG, "Got execption while loading APN database.", e);
- } finally {
- parser.close();
- }
-
- // Read external APNS data (partner-provided)
- XmlPullParser confparser = null;
- // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
- File confFile = new File(Environment.getRootDirectory(), PARTNER_APNS_PATH);
- FileReader confreader = null;
- try {
- confreader = new FileReader(confFile);
- confparser = Xml.newPullParser();
- confparser.setInput(confreader);
- XmlUtils.beginDocument(confparser, "apns");
-
- // Sanity check. Force internal version and confidential versions to agree
- int confversion = Integer.parseInt(confparser.getAttributeValue(null, "version"));
- if (publicversion != confversion) {
- throw new IllegalStateException("Internal APNS file version doesn't match "
- + confFile.getAbsolutePath());
- }
-
- loadApns(db, confparser);
- } catch (FileNotFoundException e) {
- // It's ok if the file isn't found. It means there isn't a confidential file
- // Log.e(TAG, "File not found: '" + confFile.getAbsolutePath() + "'");
- } catch (Exception e) {
- Log.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
- } finally {
- try { if (confreader != null) confreader.close(); } catch (IOException e) { }
- }
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXISTS " + CARRIERS_TABLE + ";");
- onCreate(db);
- }
-
- /**
- * Gets the next row of apn values.
- *
- * @param parser the parser
- * @return the row or null if it's not an apn
- */
- private ContentValues getRow(XmlPullParser parser) {
- if (!"apn".equals(parser.getName())) {
- return null;
- }
-
- ContentValues map = new ContentValues();
-
- String mcc = parser.getAttributeValue(null, "mcc");
- String mnc = parser.getAttributeValue(null, "mnc");
- String numeric = mcc + mnc;
-
- map.put(Telephony.Carriers.NUMERIC,numeric);
- map.put(Telephony.Carriers.MCC, mcc);
- map.put(Telephony.Carriers.MNC, mnc);
- map.put(Telephony.Carriers.NAME, parser.getAttributeValue(null, "carrier"));
- map.put(Telephony.Carriers.APN, parser.getAttributeValue(null, "apn"));
- map.put(Telephony.Carriers.USER, parser.getAttributeValue(null, "user"));
- map.put(Telephony.Carriers.SERVER, parser.getAttributeValue(null, "server"));
- map.put(Telephony.Carriers.PASSWORD, parser.getAttributeValue(null, "password"));
-
- // do not add NULL to the map so that insert() will set the default value
- String proxy = parser.getAttributeValue(null, "proxy");
- if (proxy != null) {
- map.put(Telephony.Carriers.PROXY, proxy);
- }
- String port = parser.getAttributeValue(null, "port");
- if (port != null) {
- map.put(Telephony.Carriers.PORT, port);
- }
- String mmsproxy = parser.getAttributeValue(null, "mmsproxy");
- if (mmsproxy != null) {
- map.put(Telephony.Carriers.MMSPROXY, mmsproxy);
- }
- String mmsport = parser.getAttributeValue(null, "mmsport");
- if (mmsport != null) {
- map.put(Telephony.Carriers.MMSPORT, mmsport);
- }
- map.put(Telephony.Carriers.MMSC, parser.getAttributeValue(null, "mmsc"));
- String type = parser.getAttributeValue(null, "type");
- if (type != null) {
- map.put(Telephony.Carriers.TYPE, type);
- }
-
- return map;
- }
-
- /*
- * Loads apns from xml file into the database
- *
- * @param db the sqlite database to write to
- * @param parser the xml parser
- *
- */
- private void loadApns(SQLiteDatabase db, XmlPullParser parser) {
- if (parser != null) {
- try {
- while (true) {
- XmlUtils.nextElement(parser);
- ContentValues row = getRow(parser);
- if (row != null) {
- db.insert(CARRIERS_TABLE, null, row);
- } else {
- break; // do we really want to skip the rest of the file?
- }
- }
- } catch (XmlPullParserException e) {
- Log.e(TAG, "Got execption while getting perferred time zone.", e);
- } catch (IOException e) {
- Log.e(TAG, "Got execption while getting perferred time zone.", e);
- }
- }
- }
- }
-
- @Override
- public boolean onCreate() {
- mOpenHelper = new DatabaseHelper(getContext());
- return true;
- }
-
- @Override
- public Cursor query(Uri url, String[] projectionIn, String selection,
- String[] selectionArgs, String sort) {
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
- qb.setTables("carriers");
-
- int match = s_urlMatcher.match(url);
- switch (match) {
- // do nothing
- case URL_TELEPHONY: {
- break;
- }
-
-
- case URL_CURRENT: {
- qb.appendWhere("current IS NOT NULL");
- break;
- }
-
- case URL_ID: {
- qb.appendWhere("_id = " + url.getPathSegments().get(1));
- break;
- }
-
- default: {
- return null;
- }
- }
-
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- Cursor ret = qb.query(db, projectionIn, selection, selectionArgs, null, null, sort);
- ret.setNotificationUri(getContext().getContentResolver(), url);
- return ret;
- }
-
- @Override
- public String getType(Uri url)
- {
- switch (s_urlMatcher.match(url)) {
- case URL_TELEPHONY:
- return "vnd.android.cursor.dir/telephony-carrier";
-
- case URL_ID:
- return "vnd.android.cursor.item/telephony-carrier";
-
- default:
- throw new IllegalArgumentException("Unknown URL " + url);
- }
- }
-
- @Override
- public Uri insert(Uri url, ContentValues initialValues)
- {
- Uri result = null;
-
- checkPermission();
-
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int match = s_urlMatcher.match(url);
- boolean notify = false;
- switch (match)
- {
- case URL_TELEPHONY:
- {
- ContentValues values;
- if (initialValues != null) {
- values = new ContentValues(initialValues);
- } else {
- values = new ContentValues();
- }
-
- // TODO Review this. This code should probably not bet here.
- // It is valid for the database to return a null string.
- if (values.containsKey(Telephony.Carriers.NAME) == false) {
- values.put(Telephony.Carriers.NAME, "");
- }
- if (values.containsKey(Telephony.Carriers.APN) == false) {
- values.put(Telephony.Carriers.APN, "");
- }
- if (values.containsKey(Telephony.Carriers.PORT) == false) {
- values.put(Telephony.Carriers.PORT, "");
- }
- if (values.containsKey(Telephony.Carriers.PROXY) == false) {
- values.put(Telephony.Carriers.PROXY, "");
- }
- if (values.containsKey(Telephony.Carriers.USER) == false) {
- values.put(Telephony.Carriers.USER, "");
- }
- if (values.containsKey(Telephony.Carriers.SERVER) == false) {
- values.put(Telephony.Carriers.SERVER, "");
- }
- if (values.containsKey(Telephony.Carriers.PASSWORD) == false) {
- values.put(Telephony.Carriers.PASSWORD, "");
- }
- if (values.containsKey(Telephony.Carriers.MMSPORT) == false) {
- values.put(Telephony.Carriers.MMSPORT, "");
- }
- if (values.containsKey(Telephony.Carriers.MMSPROXY) == false) {
- values.put(Telephony.Carriers.MMSPROXY, "");
- }
-
- long rowID = db.insert(CARRIERS_TABLE, null, values);
- if (rowID > 0)
- {
- result = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, rowID);
- notify = true;
- }
-
- if (Config.LOGD) Log.d(TAG, "inserted " + values.toString() + " rowID = " + rowID);
- break;
- }
-
- case URL_CURRENT:
- {
- // null out the previous operator
- db.update("carriers", s_currentNullMap, "current IS NOT NULL", null);
-
- String numeric = initialValues.getAsString("numeric");
- int updated = db.update("carriers", s_currentSetMap,
- "numeric = '" + numeric + "'", null);
-
- if (updated > 0)
- {
- if (Config.LOGD) {
- Log.d(TAG, "Setting numeric '" + numeric + "' to be the current operator");
- }
- }
- else
- {
- Log.e(TAG, "Failed setting numeric '" + numeric + "' to the current operator");
- }
- break;
- }
- }
-
- if (notify) {
- getContext().getContentResolver().notifyChange(Telephony.Carriers.CONTENT_URI, null);
- }
-
- return result;
- }
-
- @Override
- public int delete(Uri url, String where, String[] whereArgs)
- {
- int count;
-
- checkPermission();
-
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int match = s_urlMatcher.match(url);
- switch (match)
- {
- case URL_TELEPHONY:
- {
- count = db.delete(CARRIERS_TABLE, where, whereArgs);
- break;
- }
-
- case URL_CURRENT:
- {
- count = db.delete(CARRIERS_TABLE, where, whereArgs);
- break;
- }
-
- case URL_ID:
- {
- count = db.delete(CARRIERS_TABLE, Telephony.Carriers._ID + "=?",
- new String[] { url.getLastPathSegment() });
- break;
- }
-
- default: {
- throw new UnsupportedOperationException("Cannot delete that URL: " + url);
- }
- }
-
- if (count > 0) {
- getContext().getContentResolver().notifyChange(Telephony.Carriers.CONTENT_URI, null);
- }
-
- return count;
- }
-
- @Override
- public int update(Uri url, ContentValues values, String where, String[] whereArgs)
- {
- int count;
-
- checkPermission();
-
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int match = s_urlMatcher.match(url);
- switch (match)
- {
- case URL_TELEPHONY:
- {
- count = db.update(CARRIERS_TABLE, values, where, whereArgs);
- break;
- }
-
- case URL_CURRENT:
- {
- count = db.update(CARRIERS_TABLE, values, where, whereArgs);
- break;
- }
-
- case URL_ID:
- {
- if (where != null || whereArgs != null) {
- throw new UnsupportedOperationException(
- "Cannot update URL " + url + " with a where clause");
- }
- count = db.update(CARRIERS_TABLE, values, Telephony.Carriers._ID + "=?",
- new String[] { url.getLastPathSegment() });
- break;
- }
-
- default: {
- throw new UnsupportedOperationException("Cannot update that URL: " + url);
- }
- }
-
- if (count > 0) {
- getContext().getContentResolver().notifyChange(Telephony.Carriers.CONTENT_URI, null);
- }
-
- return count;
- }
-
- private void checkPermission() {
- // Check the permissions
- getContext().enforceCallingOrSelfPermission("android.permission.WRITE_APN_SETTINGS",
- "No permission to write APN settings");
- }
-
- private SQLiteOpenHelper mOpenHelper;
-}