172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/*
272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG.
372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 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
200d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddomimport com.android.mms.R;
21ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huangimport com.android.mms.LogTag;
2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.DownloadManager;
23f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduHeaders;
24f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister;
25fd644551e8506266aad2b76463b51b44154ed62fTom Taylorimport android.database.sqlite.SqliteWrapper;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.AlarmManager;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.PendingIntent;
2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver;
3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris;
3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentValues;
3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent;
3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor;
3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.ConnectivityManager;
3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.NetworkInfo;
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
38f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms;
39f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.MmsSms;
40f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms;
41f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.MmsSms.PendingMessages;
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.format.DateFormat;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class RetryScheduler implements Observer {
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final String TAG = "RetryScheduler";
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final boolean DEBUG = false;
48150c4179995cc0a75f934ef194372f9295957ca2Joe Onorato    private static final boolean LOCAL_LOGV = false;
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final Context mContext;
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final ContentResolver mContentResolver;
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private RetryScheduler(Context context) {
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mContext = context;
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mContentResolver = context.getContentResolver();
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static RetryScheduler sInstance;
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static RetryScheduler getInstance(Context context) {
6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (sInstance == null) {
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            sInstance = new RetryScheduler(context);
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return sInstance;
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean isConnected() {
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ConnectivityManager mConnMgr = (ConnectivityManager)
684485565b0141038f65f8f1de5cccc2bafc55dcfaRobert Greenwalt                mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
69a09cb112aa037fb0b71a8602fcbb12a1559470e0Robert Greenwalt        NetworkInfo ni = mConnMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_MMS);
70a09cb112aa037fb0b71a8602fcbb12a1559470e0Robert Greenwalt        return (ni == null ? false : ni.isConnected());
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void update(Observable observable) {
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Transaction t = (Transaction) observable;
76ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang
77ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang            if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
78ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang                Log.v(TAG, "[RetryScheduler] update " + observable);
79ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang            }
8001b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // We are only supposed to handle M-Notification.ind, M-Send.req
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // and M-ReadRec.ind.
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if ((t instanceof NotificationTransaction)
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    || (t instanceof RetrieveTransaction)
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    || (t instanceof ReadRecTransaction)
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    || (t instanceof SendTransaction)) {
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    TransactionState state = t.getState();
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (state.getState() == TransactionState.FAILED) {
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Uri uri = state.getContentUri();
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        if (uri != null) {
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            scheduleRetry(uri);
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } finally {
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    t.detach(this);
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } finally {
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (isConnected()) {
10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                setRetryAlarm(mContext);
10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void scheduleRetry(Uri uri) {
10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        long msgId = ContentUris.parseId(uri);
10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon();
11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        uriBuilder.appendQueryParameter("protocol", "mms");
11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        uriBuilder.appendQueryParameter("message", String.valueOf(msgId));
11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Cursor cursor = SqliteWrapper.query(mContext, mContentResolver,
11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                uriBuilder.build(), null, null, null, null);
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (cursor != null) {
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            try {
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if ((cursor.getCount() == 1) && cursor.moveToFirst()) {
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    int msgType = cursor.getInt(cursor.getColumnIndexOrThrow(
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            PendingMessages.MSG_TYPE));
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    int retryIndex = cursor.getInt(cursor.getColumnIndexOrThrow(
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            PendingMessages.RETRY_INDEX)) + 1; // Count this time.
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // TODO Should exactly understand what was happened.
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    int errorType = MmsSms.ERR_TYPE_GENERIC;
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
128e995b84b783c4a430bf3899372a337cc9c896b38Ficus Kirkpatrick                    DefaultRetryScheme scheme = new DefaultRetryScheme(mContext, retryIndex);
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    ContentValues values = new ContentValues(4);
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    long current = System.currentTimeMillis();
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    boolean isRetryDownloading =
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            (msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND);
1340d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom                    boolean retry = true;
1350d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom                    int respStatus = getResponseStatus(msgId);
13601b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                    int errorString = 0;
13701b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                    switch (respStatus) {
13801b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                        case PduHeaders.RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED:
13901b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                            errorString = R.string.invalid_destination;
14001b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                            break;
14101b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor
142406292d188e17345c4d9373ce9c2e96fd1e6b017Tom Taylor                        case PduHeaders.RESPONSE_STATUS_ERROR_SERVICE_DENIED:
14301b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                        case PduHeaders.RESPONSE_STATUS_ERROR_PERMANENT_SERVICE_DENIED:
14401b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                            errorString = R.string.service_not_activated;
14501b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                            break;
1467a71ae40edcfcfda9bbc07ef00562af86a277174Tom Taylor
14722c80259e32726d07236f03b5cd05be37b3b5281Tom Taylor                        case PduHeaders.RESPONSE_STATUS_ERROR_NETWORK_PROBLEM:
14822c80259e32726d07236f03b5cd05be37b3b5281Tom Taylor                            errorString = R.string.service_network_problem;
14922c80259e32726d07236f03b5cd05be37b3b5281Tom Taylor                            break;
15022c80259e32726d07236f03b5cd05be37b3b5281Tom Taylor
1517a71ae40edcfcfda9bbc07ef00562af86a277174Tom Taylor                        case PduHeaders.RESPONSE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND:
1527a71ae40edcfcfda9bbc07ef00562af86a277174Tom Taylor                        case PduHeaders.RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND:
1537a71ae40edcfcfda9bbc07ef00562af86a277174Tom Taylor                            errorString = R.string.service_message_not_found;
1547a71ae40edcfcfda9bbc07ef00562af86a277174Tom Taylor                            break;
15501b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                    }
15601b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                    if (errorString != 0) {
15701b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor                        DownloadManager.getInstance().showErrorCodeToast(errorString);
1580d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom                        retry = false;
1590d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom                    }
1600d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom
1610d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom                    if ((retryIndex < scheme.getRetryLimit()) && retry) {
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        long retryAt = current + scheme.getWaitingInterval();
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
164ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang                        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
165ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang                            Log.v(TAG, "scheduleRetry: retry for " + uri + " is scheduled at "
166ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang                                    + (retryAt - System.currentTimeMillis()) + "ms from now");
16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        values.put(PendingMessages.DUE_TIME, retryAt);
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        if (isRetryDownloading) {
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            // Downloading process is transiently failed.
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            DownloadManager.getInstance().markState(
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    uri, DownloadManager.STATE_TRANSIENT_FAILURE);
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    } else {
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        errorType = MmsSms.ERR_TYPE_GENERIC_PERMANENT;
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        if (isRetryDownloading) {
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            Cursor c = SqliteWrapper.query(mContext, mContext.getContentResolver(), uri,
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    new String[] { Mms.THREAD_ID }, null, null, null);
18101b383fd51fdb3787ba5cd730b47495ff9c8c079Tom Taylor
18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            long threadId = -1;
18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            if (c != null) {
18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                try {
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    if (c.moveToFirst()) {
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                        threadId = c.getLong(0);
18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    }
18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                } finally {
18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    c.close();
19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                }
19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            }
19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            if (threadId != -1) {
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                // Downloading process is permanently failed.
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                MessagingNotification.notifyDownloadFailed(mContext, threadId);
19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            }
19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            DownloadManager.getInstance().markState(
19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    uri, DownloadManager.STATE_PERMANENT_FAILURE);
20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        } else {
20143ca4f260568dbaea2f1997677958b303678d1eaFicus Kirkpatrick                            // Mark the failed message as unread.
20243ca4f260568dbaea2f1997677958b303678d1eaFicus Kirkpatrick                            ContentValues readValues = new ContentValues(1);
20343ca4f260568dbaea2f1997677958b303678d1eaFicus Kirkpatrick                            readValues.put(Mms.READ, 0);
20443ca4f260568dbaea2f1997677958b303678d1eaFicus Kirkpatrick                            SqliteWrapper.update(mContext, mContext.getContentResolver(),
20543ca4f260568dbaea2f1997677958b303678d1eaFicus Kirkpatrick                                    uri, readValues, null, null);
206b3cb9bbf929f70cb4855f03e4bfbed749022cf1bFicus Kirkpatrick                            MessagingNotification.notifySendFailed(mContext, true);
20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    values.put(PendingMessages.ERROR_TYPE,  errorType);
21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    values.put(PendingMessages.RETRY_INDEX, retryIndex);
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    values.put(PendingMessages.LAST_TRY,    current);
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    int columnIndex = cursor.getColumnIndexOrThrow(
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            PendingMessages._ID);
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    long id = cursor.getLong(columnIndex);
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    SqliteWrapper.update(mContext, mContentResolver,
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            PendingMessages.CONTENT_URI,
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            values, PendingMessages._ID + "=" + id, null);
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else if (LOCAL_LOGV) {
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.v(TAG, "Cannot found correct pending status for: " + msgId);
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } finally {
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                cursor.close();
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2290d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom    private int getResponseStatus(long msgID) {
2300d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom        int respStatus = 0;
2310d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom        Cursor cursor = SqliteWrapper.query(mContext, mContentResolver,
2328f68b0ab5ea9d44f99226ad344dfa7e49f443f81Satish Roddom                Mms.Outbox.CONTENT_URI, null, Mms._ID + "=" + msgID, null, null);
2330d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom        try {
2340d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom            if (cursor.moveToFirst()) {
2350d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom                respStatus = cursor.getInt(cursor.getColumnIndexOrThrow(Mms.RESPONSE_STATUS));
2360d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom            }
2370d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom        } finally {
2380d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom            cursor.close();
2390d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom        }
2400d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom        if (respStatus != 0) {
2410d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom            Log.e(TAG, "Response status is: " + respStatus);
2420d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom        }
2430d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom        return respStatus;
2440d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom    }
2450d35c9dd276d09d00169f5b01a3dff81794928ddSatish Roddom
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void setRetryAlarm(Context context) {
24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Cursor cursor = PduPersister.getPduPersister(context).getPendingMessages(
24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Long.MAX_VALUE);
24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (cursor != null) {
25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            try {
25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (cursor.moveToFirst()) {
25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // The result of getPendingMessages() is order by due time.
25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    long retryAt = cursor.getLong(cursor.getColumnIndexOrThrow(
25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            PendingMessages.DUE_TIME));
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Intent service = new Intent(TransactionService.ACTION_ONALARM,
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                        null, context, TransactionService.class);
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    PendingIntent operation = PendingIntent.getService(
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            context, 0, service, PendingIntent.FLAG_ONE_SHOT);
26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    AlarmManager am = (AlarmManager) context.getSystemService(
26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            Context.ALARM_SERVICE);
26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    am.set(AlarmManager.RTC, retryAt, operation);
26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
264ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang                    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
265ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang                        Log.v(TAG, "Next retry is scheduled at"
266ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang                                + (retryAt - System.currentTimeMillis()) + "ms from now");
26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } finally {
27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                cursor.close();
27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
275