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