107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor/*
207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * Copyright (C) 2012 The Android Open Source Project
307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor *
407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * Licensed under the Apache License, Version 2.0 (the "License");
507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * you may not use this file except in compliance with the License.
607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * You may obtain a copy of the License at
707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor *
807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor *      http://www.apache.org/licenses/LICENSE-2.0
907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor *
1007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * Unless required by applicable law or agreed to in writing, software
1107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * distributed under the License is distributed on an "AS IS" BASIS,
1207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * See the License for the specific language governing permissions and
1407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * limitations under the License.
1507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor */
1607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
1707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorpackage com.android.mms.transaction;
1807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
1907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.app.IntentService;
2007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.content.ContentUris;
2107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.content.ContentValues;
2207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.content.Context;
2307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.content.Intent;
2407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.database.Cursor;
2507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.database.sqlite.SqliteWrapper;
2607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.net.Uri;
2707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.provider.Telephony.Sms;
2807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.provider.Telephony.Sms.Inbox;
2907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.telephony.SmsMessage;
3007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorimport android.util.Log;
3107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
32d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.LogTag;
33d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chen
3407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor/**
3507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * Service that gets started by the MessageStatusReceiver when a message status report is
3607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor * received.
3707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor */
3807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylorpublic class MessageStatusService extends IntentService {
3907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    private static final String[] ID_PROJECTION = new String[] { Sms._ID };
4007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    private static final String LOG_TAG = "MessageStatusReceiver";
4107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    private static final Uri STATUS_URI = Uri.parse("content://sms/status");
4207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
4307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    public MessageStatusService() {
4407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        // Class name will be the thread name.
4507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        super(MessageStatusService.class.getName());
4607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
4707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        // Intent should be redelivered if the process gets killed before completing the job.
4807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        setIntentRedelivery(true);
4907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    }
5007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
5107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    @Override
5207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    protected void onHandleIntent(Intent intent) {
5307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        // This method is called on a worker thread.
5407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
5507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        Uri messageUri = intent.getData();
5607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        byte[] pdu = intent.getByteArrayExtra("pdu");
5707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        String format = intent.getStringExtra("format");
5807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
5907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        SmsMessage message = updateMessageStatus(this, messageUri, pdu, format);
6007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
61c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev        // Called on a background thread, so it's OK to block.
62c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev        if (message != null && message.getStatus() < Sms.STATUS_PENDING) {
63c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev            MessagingNotification.blockingUpdateNewMessageIndicator(this,
64c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev                    MessagingNotification.THREAD_NONE, message.isStatusReportMessage());
65c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev        }
6607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    }
6707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
6807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    private SmsMessage updateMessageStatus(Context context, Uri messageUri, byte[] pdu,
6907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor            String format) {
7007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        SmsMessage message = SmsMessage.createFromPdu(pdu, format);
7107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        if (message == null) {
7207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor            return null;
7307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        }
7407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        // Create a "status/#" URL and use it to update the
7507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        // message's status in the database.
7607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
7707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                            messageUri, ID_PROJECTION, null, null, null);
7807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
7907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        try {
8007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor            if (cursor.moveToFirst()) {
8107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                int messageId = cursor.getInt(0);
8207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
8307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                Uri updateUri = ContentUris.withAppendedId(STATUS_URI, messageId);
8407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                int status = message.getStatus();
8507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                boolean isStatusReport = message.isStatusReportMessage();
8607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                ContentValues contentValues = new ContentValues(2);
8707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
8807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                if (Log.isLoggable(LogTag.TAG, Log.DEBUG)) {
8907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                    log("updateMessageStatus: msgUrl=" + messageUri + ", status=" + status +
9007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                            ", isStatusReport=" + isStatusReport);
9107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                }
9207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
9307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                contentValues.put(Sms.STATUS, status);
9407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                contentValues.put(Inbox.DATE_SENT, System.currentTimeMillis());
9507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                SqliteWrapper.update(context, context.getContentResolver(),
9607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                                    updateUri, contentValues, null, null);
9707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor            } else {
9807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor                error("Can't find message for status update: " + messageUri);
9907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor            }
10007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        } finally {
10107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor            cursor.close();
10207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        }
10307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        return message;
10407ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    }
10507ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
10607ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    private void error(String message) {
10707ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        Log.e(LOG_TAG, "[MessageStatusReceiver] " + message);
10807ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    }
10907ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor
11007ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    private void log(String message) {
11107ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor        Log.d(LOG_TAG, "[MessageStatusReceiver] " + message);
11207ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor    }
11307ddb5c577a10e5aa3b4442426a055f3b95d5202Tom Taylor}
114