172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/* 272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 Esmertec AG. 372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 The Android Open Source Project 472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License. 772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at 872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and 1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License. 1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.transaction; 1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static android.content.Intent.ACTION_BOOT_COMPLETED; 21009ad1b491c876feadb50964645c38e002a114a1David Braunimport static android.provider.Telephony.Sms.Intents.SMS_DELIVER_ACTION; 2237321876549776417f035118f157d9531f73de6bWink Saville 2304db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylorimport java.util.Calendar; 2404db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylorimport java.util.GregorianCalendar; 2504db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Activity; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Service; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver; 2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentValues; 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 33cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylorimport android.content.IntentFilter; 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 35d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.database.sqlite.SqliteWrapper; 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.HandlerThread; 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.IBinder; 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Looper; 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Message; 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Process; 43f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms; 44f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms.Inbox; 45f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms.Intents; 46f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms.Outbox; 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.telephony.ServiceState; 4837321876549776417f035118f157d9531f73de6bWink Savilleimport android.telephony.SmsManager; 4937321876549776417f035118f157d9531f73de6bWink Savilleimport android.telephony.SmsMessage; 506a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kallaimport android.text.TextUtils; 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Toast; 5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 54f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.internal.telephony.TelephonyIntents; 55812391ad832f3fdac054ad3a50af563da16e99b5Wei Huangimport com.android.mms.LogTag; 569dc65e65a3968cfdca8d4611eba93cf2e0a1df05David Braunimport com.android.mms.MmsConfig; 57d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.R; 58d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Contact; 59d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Conversation; 60d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.ui.ClassZeroActivity; 61d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.Recycler; 62d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.SendingProgressTokenManager; 63d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.widget.MmsWidgetProvider; 64d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.MmsException; 6537321876549776417f035118f157d9531f73de6bWink Saville 6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This service essentially plays the role of a "worker thread", allowing us to store 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * incoming messages to the database, update notifications, etc. without blocking the 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * main thread that SmsReceiver runs on. 7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SmsReceiverService extends Service { 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "SmsReceiverService"; 7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ServiceHandler mServiceHandler; 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Looper mServiceLooper; 7652b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao private boolean mSending; 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String MESSAGE_SENT_ACTION = 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "com.android.mms.transaction.MESSAGE_SENT"; 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8152b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao // Indicates next message can be picked up and sent out. 8252b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao public static final String EXTRA_MESSAGE_SENT_SEND_NEXT ="SendNextMsg"; 8352b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao 8452b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao public static final String ACTION_SEND_MESSAGE = 85087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen "com.android.mms.transaction.SEND_MESSAGE"; 86087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen public static final String ACTION_SEND_INACTIVE_MESSAGE = 87087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen "com.android.mms.transaction.SEND_INACTIVE_MESSAGE"; 8852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must match the column IDs below. 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String[] SEND_PROJECTION = new String[] { 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms._ID, //0 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.THREAD_ID, //1 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.ADDRESS, //2 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.BODY, //3 9552b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao Sms.STATUS, //4 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 99f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor public Handler mToastHandler = new Handler(); 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must match SEND_PROJECTION. 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int SEND_COLUMN_ID = 0; 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int SEND_COLUMN_THREAD_ID = 1; 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int SEND_COLUMN_ADDRESS = 2; 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int SEND_COLUMN_BODY = 3; 10652b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao private static final int SEND_COLUMN_STATUS = 4; 10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private int mResultCode; 109f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onCreate() { 112f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor // Temporarily removed for this duplicate message track down. 113c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor// if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 114f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor// Log.v(TAG, "onCreate"); 115f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor// } 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Start up the thread running the service. Note that we create a 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // separate thread because the service normally runs in the process's 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // main thread, which we don't want to block. 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND); 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project thread.start(); 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceLooper = thread.getLooper(); 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler = new ServiceHandler(mServiceLooper); 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 12835de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor public int onStartCommand(Intent intent, int flags, int startId) { 129f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor // Temporarily removed for this duplicate message track down. 13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1312c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor mResultCode = intent != null ? intent.getIntExtra("result", 0) : 0; 13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13368be4f572123274aa67e13544482ca4d99e7b235Tom Taylor if (mResultCode != 0) { 1340856dec418d9838e09b1609439279e248355e0c4Tom Taylor Log.v(TAG, "onStart: #" + startId + " mResultCode: " + mResultCode + 1350856dec418d9838e09b1609439279e248355e0c4Tom Taylor " = " + translateResultCode(mResultCode)); 1360856dec418d9838e09b1609439279e248355e0c4Tom Taylor } 1370856dec418d9838e09b1609439279e248355e0c4Tom Taylor 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Message msg = mServiceHandler.obtainMessage(); 13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project msg.arg1 = startId; 14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project msg.obj = intent; 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.sendMessage(msg); 14235de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor return Service.START_NOT_STICKY; 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1450856dec418d9838e09b1609439279e248355e0c4Tom Taylor private static String translateResultCode(int resultCode) { 1460856dec418d9838e09b1609439279e248355e0c4Tom Taylor switch (resultCode) { 1470856dec418d9838e09b1609439279e248355e0c4Tom Taylor case Activity.RESULT_OK: 1480856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "Activity.RESULT_OK"; 1490856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 1500856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_GENERIC_FAILURE"; 1510856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_RADIO_OFF: 1520856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_RADIO_OFF"; 1530856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_NULL_PDU: 1540856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_NULL_PDU"; 1550856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_NO_SERVICE: 1560856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_NO_SERVICE"; 1570856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_LIMIT_EXCEEDED: 1580856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_LIMIT_EXCEEDED"; 1590856dec418d9838e09b1609439279e248355e0c4Tom Taylor case SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE: 1600856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE"; 1610856dec418d9838e09b1609439279e248355e0c4Tom Taylor default: 1620856dec418d9838e09b1609439279e248355e0c4Tom Taylor return "Unknown error code"; 1630856dec418d9838e09b1609439279e248355e0c4Tom Taylor } 1640856dec418d9838e09b1609439279e248355e0c4Tom Taylor } 1650856dec418d9838e09b1609439279e248355e0c4Tom Taylor 16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onDestroy() { 168f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor // Temporarily removed for this duplicate message track down. 169c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor// if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 170f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor// Log.v(TAG, "onDestroy"); 171f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor// } 17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceLooper.quit(); 17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public IBinder onBind(Intent intent) { 17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final class ServiceHandler extends Handler { 18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public ServiceHandler(Looper looper) { 18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(looper); 18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Handle incoming transaction requests. 1870d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang * The incoming requests are initiated by the MMSC Server or by the MMS Client itself. 18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void handleMessage(Message msg) { 19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int serviceId = msg.arg1; 19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent intent = (Intent)msg.obj; 1930856dec418d9838e09b1609439279e248355e0c4Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 1940d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor Log.v(TAG, "handleMessage serviceId: " + serviceId + " intent: " + intent); 1950d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor } 1969dc65e65a3968cfdca8d4611eba93cf2e0a1df05David Braun if (intent != null && MmsConfig.isSmsEnabled(getApplicationContext())) { 1972c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor String action = intent.getAction(); 1982c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor 199161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor int error = intent.getIntExtra("errorCode", 0); 200161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor 2010856dec418d9838e09b1609439279e248355e0c4Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2020d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor Log.v(TAG, "handleMessage action: " + action + " error: " + error); 2030d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor } 2040d2c0042be90f42635e3bc301f2a2e37460e6344Tom Taylor 2052c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor if (MESSAGE_SENT_ACTION.equals(intent.getAction())) { 206161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor handleSmsSent(intent, error); 207009ad1b491c876feadb50964645c38e002a114a1David Braun } else if (SMS_DELIVER_ACTION.equals(action)) { 208161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor handleSmsReceived(intent, error); 2092c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor } else if (ACTION_BOOT_COMPLETED.equals(action)) { 2102c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor handleBootCompleted(); 211f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylor } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) { 2122c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor handleServiceStateChanged(intent); 21352b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } else if (ACTION_SEND_MESSAGE.endsWith(action)) { 21452b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao handleSendMessage(); 215087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen } else if (ACTION_SEND_INACTIVE_MESSAGE.equals(action)) { 216087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen handleSendInactiveMessage(); 2172c77f17bc77af92e57c82cc1bfa44de2979e505aTom Taylor } 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // NOTE: We MUST not call stopSelf() directly, since we need to 22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // make sure the wake lock acquired by AlertReceiver is released. 22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsReceiver.finishStartingService(SmsReceiverService.this, serviceId); 22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void handleServiceStateChanged(Intent intent) { 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // If service just returned, start sending out the queued messages 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras()); 22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) { 22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendFirstQueuedMessage(); 23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 23352b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao private void handleSendMessage() { 23452b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao if (!mSending) { 23552b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao sendFirstQueuedMessage(); 23652b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } 23752b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } 23852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao 239087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen private void handleSendInactiveMessage() { 240087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen // Inactive messages includes all messages in outbox and queued box. 241087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen moveOutboxMessagesToQueuedBox(); 242087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen sendFirstQueuedMessage(); 243087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen } 244087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen 24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void sendFirstQueuedMessage() { 246cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor boolean success = true; 24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // get all the queued messages from the database 24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project final Uri uri = Uri.parse("content://sms/queued"); 24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = getContentResolver(); 25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor c = SqliteWrapper.query(this, resolver, uri, 25123142979f43786098655229416cf1d07c5f78e09Tom Taylor SEND_PROJECTION, null, null, "date ASC"); // date ASC so we send out in 25223142979f43786098655229416cf1d07c5f78e09Tom Taylor // same order the user tried 25323142979f43786098655229416cf1d07c5f78e09Tom Taylor // to send messages. 25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (c != null) { 25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (c.moveToFirst()) { 25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String msgText = c.getString(SEND_COLUMN_BODY); 25852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao String address = c.getString(SEND_COLUMN_ADDRESS); 25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int threadId = c.getInt(SEND_COLUMN_THREAD_ID); 26052b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao int status = c.getInt(SEND_COLUMN_STATUS); 26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2620d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang int msgId = c.getInt(SEND_COLUMN_ID); 2630d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang Uri msgUri = ContentUris.withAppendedId(Sms.CONTENT_URI, msgId); 2640d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang 2654020be563f457ed2251b43928f14770246c886a2Tom Taylor SmsMessageSender sender = new SmsSingleRecipientSender(this, 2664020be563f457ed2251b43928f14770246c886a2Tom Taylor address, msgText, threadId, status == Sms.STATUS_PENDING, 2674020be563f457ed2251b43928f14770246c886a2Tom Taylor msgUri); 2684020be563f457ed2251b43928f14770246c886a2Tom Taylor 269a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor if (LogTag.DEBUG_SEND || 270a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor LogTag.VERBOSE || 271a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2724020be563f457ed2251b43928f14770246c886a2Tom Taylor Log.v(TAG, "sendFirstQueuedMessage " + msgUri + 2730d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang ", address: " + address + 274858d59e9f4b0839ee014e52e0744ea910d9830ffWei Huang ", threadId: " + threadId); 2750d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang } 276858d59e9f4b0839ee014e52e0744ea910d9830ffWei Huang 27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 27852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao sender.sendMessage(SendingProgressTokenManager.NO_TOKEN);; 27952b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao mSending = true; 28067ec6c54e11c19caf894b4ffce7250fb3fd96d30Wei Huang } catch (MmsException e) { 28167ec6c54e11c19caf894b4ffce7250fb3fd96d30Wei Huang Log.e(TAG, "sendFirstQueuedMessage: failed to send message " + msgUri 28267ec6c54e11c19caf894b4ffce7250fb3fd96d30Wei Huang + ", caught ", e); 28313848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor mSending = false; 28413848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor messageFailedToSend(msgUri, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 285cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor success = false; 286ddd2fdd5e80aa9d689c9ed982e1e003028fa8628Bin Li // Sending current message fails. Try to send more pending messages 287ddd2fdd5e80aa9d689c9ed982e1e003028fa8628Bin Li // if there is any. 288ddd2fdd5e80aa9d689c9ed982e1e003028fa8628Bin Li sendBroadcast(new Intent(SmsReceiverService.ACTION_SEND_MESSAGE, 289ddd2fdd5e80aa9d689c9ed982e1e003028fa8628Bin Li null, 290ddd2fdd5e80aa9d689c9ed982e1e003028fa8628Bin Li this, 291ddd2fdd5e80aa9d689c9ed982e1e003028fa8628Bin Li SmsReceiver.class)); 29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project c.close(); 29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 298cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor if (success) { 299cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // We successfully sent all the messages in the queue. We don't need to 300cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // be notified of any service changes any longer. 301cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor unRegisterForServiceStateChanges(); 302cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 305161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor private void handleSmsSent(Intent intent, int error) { 30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri uri = intent.getData(); 30752b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao mSending = false; 30852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao boolean sendNextMsg = intent.getBooleanExtra(EXTRA_MESSAGE_SENT_SEND_NEXT, false); 30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 310c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (LogTag.DEBUG_SEND) { 311a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor Log.v(TAG, "handleSmsSent uri: " + uri + " sendNextMsg: " + sendNextMsg + 312a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor " mResultCode: " + mResultCode + 313a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor " = " + translateResultCode(mResultCode) + " error: " + error); 314c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor } 315c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor 31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mResultCode == Activity.RESULT_OK) { 317a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor if (LogTag.DEBUG_SEND || Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 318a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor Log.v(TAG, "handleSmsSent move message to sent folder uri: " + uri); 319f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor } 320161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor if (!Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_SENT, error)) { 3210d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang Log.e(TAG, "handleSmsSent: failed to move message " + uri + " to sent folder"); 3220d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang } 32352b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao if (sendNextMsg) { 32452b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao sendFirstQueuedMessage(); 32552b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } 32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3270d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang // Update the notification for failed messages since they may be deleted. 328b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor MessagingNotification.nonBlockingUpdateSendFailedNotification(this); 32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if ((mResultCode == SmsManager.RESULT_ERROR_RADIO_OFF) || 33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project (mResultCode == SmsManager.RESULT_ERROR_NO_SERVICE)) { 331f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 332f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor Log.v(TAG, "handleSmsSent: no service, queuing message w/ uri: " + uri); 333f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor } 334cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // We got an error with no service or no radio. Register for state changes so 335cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // when the status of the connection/radio changes, we can try to send the 336cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // queued up messages. 337cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor registerForServiceStateChanges(); 338cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // We couldn't send the message, put in the queue to retry later. 339161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_QUEUED, error); 340f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor mToastHandler.post(new Runnable() { 341f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor public void run() { 342f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor Toast.makeText(SmsReceiverService.this, getString(R.string.message_queued), 343f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor Toast.LENGTH_SHORT).show(); 344f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor } 345f31df323b2dc4b668d91b24dd3a5d34f5ccbb14cTom Taylor }); 346f97cdd928bbc1953d422466d62807f07ae66119eNaveen Kalla } else if (mResultCode == SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE) { 34748aacaa96f6864172ac7657380f4fcb17ba24431Jeevaka Badrappan messageFailedToSend(uri, mResultCode); 3483c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project mToastHandler.post(new Runnable() { 3493c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project public void run() { 3503c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project Toast.makeText(SmsReceiverService.this, getString(R.string.fdn_check_failure), 3513c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project Toast.LENGTH_SHORT).show(); 3523c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project } 3533c6eacd7f75aef4109f6ba8f1fbf2c957bd58ae2The Android Open Source Project }); 35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 35513848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor messageFailedToSend(uri, error); 35652b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao if (sendNextMsg) { 35752b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao sendFirstQueuedMessage(); 35852b0fc717011d84dd25c1e88998eaae97c8161a8Bai Tao } 35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 36213848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor private void messageFailedToSend(Uri uri, int error) { 363c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 364c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor Log.v(TAG, "messageFailedToSend msg failed uri: " + uri + " error: " + error); 36513848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor } 36613848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_FAILED, error); 36713848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor MessagingNotification.notifySendFailed(getApplicationContext(), true); 36813848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor } 36913848bd88f29a358d13c2ce49f5c90c5858296f2Tom Taylor 370161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor private void handleSmsReceived(Intent intent, int error) { 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsMessage[] msgs = Intents.getMessagesFromIntent(intent); 372104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor String format = intent.getStringExtra("format"); 373104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor Uri messageUri = insertMessage(this, msgs, error, format); 37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 375c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 3760d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang SmsMessage sms = msgs[0]; 3770d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang Log.v(TAG, "handleSmsReceived" + (sms.isReplace() ? "(replace)" : "") + 37823142979f43786098655229416cf1d07c5f78e09Tom Taylor " messageUri: " + messageUri + 3790d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang ", address: " + sms.getOriginatingAddress() + 3800d798c0853ead129b245ac7e8700f3a4aba92ecbWei Huang ", body: " + sms.getMessageBody()); 381f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor } 382f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor 38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (messageUri != null) { 384c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev long threadId = MessagingNotification.getSmsThreadId(this, messageUri); 3853b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // Called off of the UI thread so ok to block. 386d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor Log.d(TAG, "handleSmsReceived messageUri: " + messageUri + " threadId: " + threadId); 387c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MessagingNotification.blockingUpdateNewMessageIndicator(this, threadId, false); 38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void handleBootCompleted() { 3927015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // Some messages may get stuck in the outbox. At this point, they're probably irrelevant 3937015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // to the user, so mark them as failed and notify the user, who can then decide whether to 3947015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // resend them manually. 3957015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev int numMoved = moveOutboxMessagesToFailedBox(); 3967015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev if (numMoved > 0) { 3977015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev MessagingNotification.notifySendFailed(getApplicationContext(), true); 3987015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev } 3997015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev 4007015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev // Send any queued messages that were waiting from before the reboot. 40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendFirstQueuedMessage(); 4023b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor 4033b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // Called off of the UI thread so ok to block. 404c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MessagingNotification.blockingUpdateNewMessageIndicator( 405c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev this, MessagingNotification.THREAD_ALL, false); 40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 4087015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev /** 409087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen * Move all messages that are in the outbox to the queued state 410087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen * @return The number of messages that were actually moved 411087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen */ 412087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen private int moveOutboxMessagesToQueuedBox() { 413087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen ContentValues values = new ContentValues(1); 414087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen 415087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen values.put(Sms.TYPE, Sms.MESSAGE_TYPE_QUEUED); 416087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen 417087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen int messageCount = SqliteWrapper.update( 418087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen getApplicationContext(), getContentResolver(), Outbox.CONTENT_URI, 419087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen values, "type = " + Sms.MESSAGE_TYPE_OUTBOX, null); 420087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 421087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen Log.v(TAG, "moveOutboxMessagesToQueuedBox messageCount: " + messageCount); 422087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen } 423087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen return messageCount; 424087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen } 425087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen 426087ef9de80082cd001e75c15e1f93cc65d50ed27Roger Chen /** 4277015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * Move all messages that are in the outbox to the failed state and set them to unread. 4287015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev * @return The number of messages that were actually moved 4297015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev */ 4307015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev private int moveOutboxMessagesToFailedBox() { 4317015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev ContentValues values = new ContentValues(3); 43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 4337015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev values.put(Sms.TYPE, Sms.MESSAGE_TYPE_FAILED); 4347015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev values.put(Sms.ERROR_CODE, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 4357015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev values.put(Sms.READ, Integer.valueOf(0)); 43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 437a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor int messageCount = SqliteWrapper.update( 43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project getApplicationContext(), getContentResolver(), Outbox.CONTENT_URI, 43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values, "type = " + Sms.MESSAGE_TYPE_OUTBOX, null); 440a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 4417015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev Log.v(TAG, "moveOutboxMessagesToFailedBox messageCount: " + messageCount); 442a0bda6a838d0c9bff996aa39d4f9750faa00addaTom Taylor } 4437015fa3f96383fa8a34d6b9e28f61d228e234d7eTodor Kalaydjiev return messageCount; 44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String CLASS_ZERO_BODY_KEY = "CLASS_ZERO_BODY"; 44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must match the column IDs below. 44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final static String[] REPLACE_PROJECTION = new String[] { 45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms._ID, 45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.ADDRESS, 45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.PROTOCOL 45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This must match REPLACE_PROJECTION. 45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int REPLACE_COLUMN_ID = 0; 45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * If the message is a class-zero message, display it immediately 46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * and return null. Otherwise, store it using the 46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <code>ContentResolver</code> and return the 46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <code>Uri</code> of the thread containing this message 46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * so that we can use it for notification. 46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 465104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor private Uri insertMessage(Context context, SmsMessage[] msgs, int error, String format) { 46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Build the helper classes to parse the messages. 46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsMessage sms = msgs[0]; 46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (sms.getMessageClass() == SmsMessage.MessageClass.CLASS_0) { 470104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor displayClassZeroMessage(context, sms, format); 47172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (sms.isReplace()) { 473161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor return replaceMessage(context, msgs, error); 47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 475161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor return storeMessage(context, msgs, error); 47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This method is used if this is a "replace short message" SMS. 48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * We find any existing message that matches the incoming 48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * message's originating address and protocol identifier. If 48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * there is one, we replace its fields with those of the new 48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * message. Otherwise, we store the new message as usual. 48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See TS 23.040 9.2.3.9. 48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 488161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor private Uri replaceMessage(Context context, SmsMessage[] msgs, int error) { 48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsMessage sms = msgs[0]; 49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentValues values = extractContentValues(sms); 491161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor values.put(Sms.ERROR_CODE, error); 492dc0014f123be2c475bdeed2aef09566b5127e2a2bi int pduCount = msgs.length; 493dc0014f123be2c475bdeed2aef09566b5127e2a2bi 494dc0014f123be2c475bdeed2aef09566b5127e2a2bi if (pduCount == 1) { 495dc0014f123be2c475bdeed2aef09566b5127e2a2bi // There is only one part, so grab the body directly. 496dc0014f123be2c475bdeed2aef09566b5127e2a2bi values.put(Inbox.BODY, replaceFormFeeds(sms.getDisplayMessageBody())); 497dc0014f123be2c475bdeed2aef09566b5127e2a2bi } else { 498dc0014f123be2c475bdeed2aef09566b5127e2a2bi // Build up the body from the parts. 499dc0014f123be2c475bdeed2aef09566b5127e2a2bi StringBuilder body = new StringBuilder(); 500dc0014f123be2c475bdeed2aef09566b5127e2a2bi for (int i = 0; i < pduCount; i++) { 501dc0014f123be2c475bdeed2aef09566b5127e2a2bi sms = msgs[i]; 502dc0014f123be2c475bdeed2aef09566b5127e2a2bi if (sms.mWrappedSmsMessage != null) { 503dc0014f123be2c475bdeed2aef09566b5127e2a2bi body.append(sms.getDisplayMessageBody()); 504dc0014f123be2c475bdeed2aef09566b5127e2a2bi } 505dc0014f123be2c475bdeed2aef09566b5127e2a2bi } 506dc0014f123be2c475bdeed2aef09566b5127e2a2bi values.put(Inbox.BODY, replaceFormFeeds(body.toString())); 507dc0014f123be2c475bdeed2aef09566b5127e2a2bi } 50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String originatingAddress = sms.getOriginatingAddress(); 51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int protocolIdentifier = sms.getProtocolIdentifier(); 51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String selection = 51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.ADDRESS + " = ? AND " + 51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.PROTOCOL + " = ?"; 51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String[] selectionArgs = new String[] { 51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project originatingAddress, Integer.toString(protocolIdentifier) 51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, resolver, Inbox.CONTENT_URI, 52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project REPLACE_PROJECTION, selection, selectionArgs, null); 52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor != null) { 52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor.moveToFirst()) { 52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long messageId = cursor.getLong(REPLACE_COLUMN_ID); 52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri messageUri = ContentUris.withAppendedId( 52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Sms.CONTENT_URI, messageId); 52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SqliteWrapper.update(context, resolver, messageUri, 53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values, null, null); 53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return messageUri; 53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.close(); 53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 537161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor return storeMessage(context, msgs, error); 53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 540beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor public static String replaceFormFeeds(String s) { 541beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor // Some providers send formfeeds in their messages. Convert those formfeeds to newlines. 5424c6c7c65a1033d5cc0d87cc8b0e07a69db1842e8Tom Taylor return s == null ? "" : s.replace('\f', '\n'); 543beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor } 544beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor 5456ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// private static int count = 0; 5466ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor 547161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor private Uri storeMessage(Context context, SmsMessage[] msgs, int error) { 54872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmsMessage sms = msgs[0]; 54972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 55072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Store the message in the content provider. 55172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentValues values = extractContentValues(sms); 552161375d2c4eff31add607fc0befa5c781c6fd7f1Tom Taylor values.put(Sms.ERROR_CODE, error); 55372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int pduCount = msgs.length; 55472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 55572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (pduCount == 1) { 55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // There is only one part, so grab the body directly. 557beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor values.put(Inbox.BODY, replaceFormFeeds(sms.getDisplayMessageBody())); 55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Build up the body from the parts. 56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project StringBuilder body = new StringBuilder(); 56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < pduCount; i++) { 56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sms = msgs[i]; 563dca923722b6eb0bb3cd8ca1d4d7b478c2fa4352bTom Taylor if (sms.mWrappedSmsMessage != null) { 564dca923722b6eb0bb3cd8ca1d4d7b478c2fa4352bTom Taylor body.append(sms.getDisplayMessageBody()); 565dca923722b6eb0bb3cd8ca1d4d7b478c2fa4352bTom Taylor } 56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 567beb7834e73f6bc94938cb448522df19edb60d8c8Tom Taylor values.put(Inbox.BODY, replaceFormFeeds(body.toString())); 56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 569f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor 57023da10700b189ccca64b8e729631763572a0f15fTom Taylor // Make sure we've got a thread id so after the insert we'll be able to delete 57123da10700b189ccca64b8e729631763572a0f15fTom Taylor // excess messages. 57223da10700b189ccca64b8e729631763572a0f15fTom Taylor Long threadId = values.getAsLong(Sms.THREAD_ID); 57323da10700b189ccca64b8e729631763572a0f15fTom Taylor String address = values.getAsString(Sms.ADDRESS); 5746ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor 5756ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor // Code for debugging and easy injection of short codes, non email addresses, etc. 5766ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor // See Contact.isAlphaNumber() for further comments and results. 5776ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// switch (count++ % 8) { 5786ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 0: address = "AB12"; break; 5796ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 1: address = "12"; break; 5806ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 2: address = "Jello123"; break; 5816ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 3: address = "T-Mobile"; break; 5826ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 4: address = "Mobile1"; break; 5836ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 5: address = "Dogs77"; break; 5846ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 6: address = "****1"; break; 5856ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// case 7: address = "#4#5#6#"; break; 5866ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor// } 5876ac26ca62ba1e4252bf93672abd370966d3fb7c3Tom Taylor 5886a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla if (!TextUtils.isEmpty(address)) { 5896a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla Contact cacheContact = Contact.get(address,true); 5906a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla if (cacheContact != null) { 5916a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla address = cacheContact.getNumber(); 5926a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla } 5936a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla } else { 5946a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla address = getString(R.string.unknown_sender); 5956a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla values.put(Sms.ADDRESS, address); 596baf7fec7d1a5b8d52ae7be04865f9e869742c261repo sync } 59723da10700b189ccca64b8e729631763572a0f15fTom Taylor 59823da10700b189ccca64b8e729631763572a0f15fTom Taylor if (((threadId == null) || (threadId == 0)) && (address != null)) { 5996bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor threadId = Conversation.getOrCreateThreadId(context, address); 600627007213deb59ef938c80353c8f3598b01478b3Wei Huang values.put(Sms.THREAD_ID, threadId); 60123da10700b189ccca64b8e729631763572a0f15fTom Taylor } 60272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 60372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentResolver resolver = context.getContentResolver(); 60472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 60523da10700b189ccca64b8e729631763572a0f15fTom Taylor Uri insertedUri = SqliteWrapper.insert(context, resolver, Inbox.CONTENT_URI, values); 606f3d4a23a76a4bbe0d48503ad7abf5d8f4fc38c31Tom Taylor 60723da10700b189ccca64b8e729631763572a0f15fTom Taylor // Now make sure we're not over the limit in stored messages 608c7aa632be8e7d3ebe71f236f534ea2f0af71e04aTom Taylor Recycler.getSmsRecycler().deleteOldMessagesByThreadId(context, threadId); 609c7aa632be8e7d3ebe71f236f534ea2f0af71e04aTom Taylor MmsWidgetProvider.notifyDatasetChanged(context); 61023da10700b189ccca64b8e729631763572a0f15fTom Taylor 61123da10700b189ccca64b8e729631763572a0f15fTom Taylor return insertedUri; 61272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 61372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 61472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Extract all the content values except the body from an SMS 61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * message. 61772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ContentValues extractContentValues(SmsMessage sms) { 61972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Store the message in the content provider. 62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContentValues values = new ContentValues(); 62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 62272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.ADDRESS, sms.getDisplayOriginatingAddress()); 62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Use now for the timestamp to avoid confusion with clock 62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // drift between the handset and the SMSC. 62604db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor // Check to make sure the system is giving us a non-bogus time. 62704db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor Calendar buildDate = new GregorianCalendar(2011, 8, 18); // 18 Sep 2011 62804db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor Calendar nowDate = new GregorianCalendar(); 62904db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor long now = System.currentTimeMillis(); 63004db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor nowDate.setTimeInMillis(now); 63104db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor 63204db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor if (nowDate.before(buildDate)) { 63304db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor // It looks like our system clock isn't set yet because the current time right now 63404db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor // is before an arbitrary time we made this build. Instead of inserting a bogus 63504db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor // receive time in this case, use the timestamp of when the message was sent. 63604db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor now = sms.getTimestampMillis(); 63704db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor } 63804db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor 63904db56904da453ac04f9f9d05fe1c2ce7a3d952fTom Taylor values.put(Inbox.DATE, new Long(now)); 64054711acb7191269e0a4723320bd74f29dd2c9223Fredrik Roubert values.put(Inbox.DATE_SENT, Long.valueOf(sms.getTimestampMillis())); 64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.PROTOCOL, sms.getProtocolIdentifier()); 642627007213deb59ef938c80353c8f3598b01478b3Wei Huang values.put(Inbox.READ, 0); 643627007213deb59ef938c80353c8f3598b01478b3Wei Huang values.put(Inbox.SEEN, 0); 64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (sms.getPseudoSubject().length() > 0) { 64572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.SUBJECT, sms.getPseudoSubject()); 64672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 64772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.REPLY_PATH_PRESENT, sms.isReplyPathPresent() ? 1 : 0); 64872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Inbox.SERVICE_CENTER, sms.getServiceCenterAddress()); 64972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return values; 65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 65272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Displays a class-zero message immediately in a pop-up window 65472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * with the number from where it received the Notification with 65572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * the body of the message 65672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 658104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor private void displayClassZeroMessage(Context context, SmsMessage sms, String format) { 65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Using NEW_TASK here is necessary because we're calling 66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // startActivity from outside an activity. 66172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent smsDialogIntent = new Intent(context, ClassZeroActivity.class) 6624da6513065fbcfbf7fee9a18176ce62d2f62c825Yong Liu .putExtra("pdu", sms.getPdu()) 663104d391ddcc251c4c26975c093d2df5dea9b15c1Tom Taylor .putExtra("format", format) 66472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 66572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 66672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 66772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context.startActivity(smsDialogIntent); 66872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 670cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor private void registerForServiceStateChanges() { 671cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor Context context = getApplicationContext(); 672cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor unRegisterForServiceStateChanges(); 673cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor 674cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor IntentFilter intentFilter = new IntentFilter(); 675f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylor intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 676c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 677cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor Log.v(TAG, "registerForServiceStateChanges"); 678cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 679cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor 680cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor context.registerReceiver(SmsReceiver.getInstance(), intentFilter); 681cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 682cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor 683cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor private void unRegisterForServiceStateChanges() { 684c33ee154b6fd872439fd24a073f947339bbe4d22Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) { 685cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor Log.v(TAG, "unRegisterForServiceStateChanges"); 686cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 687cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor try { 688cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor Context context = getApplicationContext(); 689cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor context.unregisterReceiver(SmsReceiver.getInstance()); 690cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } catch (IllegalArgumentException e) { 691cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor // Allow un-matched register-unregister calls 692cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 693cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor } 69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 69537321876549776417f035118f157d9531f73de6bWink Saville 69637321876549776417f035118f157d9531f73de6bWink Saville 697