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 20161c9154aa7aafa397332caee40b2776db988bf7Christian Gustafssonimport com.android.mms.MmsConfig; 2113dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huangimport com.android.mms.ui.MessageUtils; 2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.DownloadManager; 233239889e9a417617b755d4cde22070843e5c070bTom Taylorimport com.android.mms.util.Recycler; 24f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.MmsException; 25f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.AcknowledgeInd; 26f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduComposer; 27f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduHeaders; 28f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduParser; 29f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister; 30f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.RetrieveConf; 31f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.EncodedStringValue; 32fd644551e8506266aad2b76463b51b44154ed62fTom Taylorimport android.database.sqlite.SqliteWrapper; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentValues; 3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 38f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms; 39f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms.Inbox; 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.IOException; 4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * The RetrieveTransaction is responsible for retrieving multimedia 4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * messages (M-Retrieve.conf) from the MMSC server. It: 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <ul> 4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>Sends a GET request to the MMSC server. 5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>Retrieves the binary M-Retrieve.conf data and parses it. 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>Persists the retrieve multimedia message. 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>Determines whether an acknowledgement is required. 5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>Creates appropriate M-Acknowledge.ind and sends it to MMSC server. 5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>Notifies the TransactionService about succesful completion. 5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * </ul> 5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class RetrieveTransaction extends Transaction implements Runnable { 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "RetrieveTransaction"; 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final boolean DEBUG = false; 60150c4179995cc0a75f934ef194372f9295957ca2Joe Onorato private static final boolean LOCAL_LOGV = false; 6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final Uri mUri; 633b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson private final String mContentLocation; 64864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor private boolean mLocked; 65864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor 66864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor static final String[] PROJECTION = new String[] { 67864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor Mms.CONTENT_LOCATION, 68864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor Mms.LOCKED 69864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor }; 70864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor 71864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor // The indexes of the columns which must be consistent with above PROJECTION. 72864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor static final int COLUMN_CONTENT_LOCATION = 0; 73864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor static final int COLUMN_LOCKED = 1; 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public RetrieveTransaction(Context context, int serviceId, 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionSettings connectionSettings, String uri) 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throws MmsException { 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(context, serviceId, connectionSettings); 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (uri.startsWith("content://")) { 8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mUri = Uri.parse(uri); // The Uri of the M-Notification.ind 8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mId = mContentLocation = getContentLocation(context, mUri); 8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "X-Mms-Content-Location: " + mContentLocation); 8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throw new IllegalArgumentException( 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "Initializing from X-Mms-Content-Location is abandoned!"); 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Attach the transaction to the instance of RetryScheduler. 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project attach(RetryScheduler.getInstance(context)); 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 95864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor private String getContentLocation(Context context, Uri uri) 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throws MmsException { 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(), 98864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor uri, PROJECTION, null, null, null); 99864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor mLocked = false; 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor != null) { 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((cursor.getCount() == 1) && cursor.moveToFirst()) { 104864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor // Get the locked flag from the M-Notification.ind so it can be transferred 105864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor // to the real message after the download. 106864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor mLocked = cursor.getInt(COLUMN_LOCKED) == 1; 107864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor return cursor.getString(COLUMN_CONTENT_LOCATION); 10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.close(); 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throw new MmsException("Cannot get X-Mms-Content-Location from: " + uri); 11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * (non-Javadoc) 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @see com.android.mms.transaction.Transaction#process() 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void process() { 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project new Thread(this).start(); 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void run() { 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Change the downloading state of the M-Notification.ind. 12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project DownloadManager.getInstance().markState( 13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mUri, DownloadManager.STATE_DOWNLOADING); 13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Send GET request to MMSC and retrieve the response data. 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project byte[] resp = getPdu(mContentLocation); 13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Parse M-Retrieve.conf 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project RetrieveConf retrieveConf = (RetrieveConf) new PduParser(resp).parse(); 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (null == retrieveConf) { 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throw new MmsException("Invalid M-Retrieve.conf PDU."); 13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 141512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor Uri msgUri = null; 14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isDuplicateMessage(mContext, retrieveConf)) { 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Mark this transaction as failed to prevent duplicate 14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // notification to user. 14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTransactionState.setState(TransactionState.FAILED); 14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTransactionState.setContentUri(mUri); 14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Store M-Retrieve.conf into Inbox 14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PduPersister persister = PduPersister.getPduPersister(mContext); 150512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor msgUri = persister.persist(retrieveConf, Inbox.CONTENT_URI); 15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 15269481afff1b27e1d8b31e1450430aeb8bc6a2d07Matthias Thomae // Use local time instead of PDU time 15369481afff1b27e1d8b31e1450430aeb8bc6a2d07Matthias Thomae ContentValues values = new ContentValues(1); 15469481afff1b27e1d8b31e1450430aeb8bc6a2d07Matthias Thomae values.put(Mms.DATE, System.currentTimeMillis() / 1000L); 15569481afff1b27e1d8b31e1450430aeb8bc6a2d07Matthias Thomae SqliteWrapper.update(mContext, mContext.getContentResolver(), 15669481afff1b27e1d8b31e1450430aeb8bc6a2d07Matthias Thomae msgUri, values, null, null); 15769481afff1b27e1d8b31e1450430aeb8bc6a2d07Matthias Thomae 15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // The M-Retrieve.conf has been successfully downloaded. 15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTransactionState.setState(TransactionState.SUCCESS); 160512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor mTransactionState.setContentUri(msgUri); 16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Remember the location the message was downloaded from. 16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Since it's not critical, it won't fail the transaction. 163864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor // Copy over the locked flag from the M-Notification.ind in case 164864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor // the user locked the message before activating the download. 165864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor updateContentLocation(mContext, msgUri, mContentLocation, mLocked); 16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Delete the corresponding M-Notification.ind. 16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SqliteWrapper.delete(mContext, mContext.getContentResolver(), 17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mUri, null, null); 17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 172512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor if (msgUri != null) { 173512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor // Have to delete messages over limit *after* the delete above. Otherwise, 174512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor // it would be counted as part of the total. 175512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor Recycler.getMmsRecycler().deleteOldMessagesInSameThreadAsMessage(mContext, msgUri); 176512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor } 177512681a5702e1ba6df0b7298c7737598a4e9aa8eTom Taylor 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Send ACK to the Proxy-Relay to indicate we have fetched the 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // MM successfully. 18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Don't mark the transaction as failed if we failed to send it. 18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendAcknowledgeInd(retrieveConf); 182591d17e9a51bb9f829d6860dc7aa0bad25062cd5The Android Open Source Project } catch (Throwable t) { 183591d17e9a51bb9f829d6860dc7aa0bad25062cd5The Android Open Source Project Log.e(TAG, Log.getStackTraceString(t)); 18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mTransactionState.getState() != TransactionState.SUCCESS) { 18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTransactionState.setState(TransactionState.FAILED); 18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mTransactionState.setContentUri(mUri); 18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Retrieval failed."); 18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notifyObservers(); 19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static boolean isDuplicateMessage(Context context, RetrieveConf rc) { 19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project byte[] rawMessageId = rc.getMessageId(); 19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (rawMessageId != null) { 19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String messageId = new String(rawMessageId); 19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String selection = "(" + Mms.MESSAGE_ID + " = ? AND " 19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + Mms.MESSAGE_TYPE + " = ?)"; 20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String[] selectionArgs = new String[] { messageId, 20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String.valueOf(PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) }; 20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = SqliteWrapper.query( 20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, context.getContentResolver(), 20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.CONTENT_URI, new String[] { Mms._ID }, 20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project selection, selectionArgs, null); 20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor != null) { 20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor.getCount() > 0) { 20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // We already received the same message before. 21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.close(); 21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return false; 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22013dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huang private void sendAcknowledgeInd(RetrieveConf rc) throws MmsException, IOException { 22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Send M-Acknowledge.ind to MMSC if required. 22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // If the Transaction-ID isn't set in the M-Retrieve.conf, it means 22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // the MMS proxy-relay doesn't require an ACK. 22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project byte[] tranId = rc.getTransactionId(); 22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (tranId != null) { 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Create M-Acknowledge.ind 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project AcknowledgeInd acknowledgeInd = new AcknowledgeInd( 22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PduHeaders.CURRENT_MMS_VERSION, tranId); 22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 23013dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huang // insert the 'from' address per spec 23113dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huang String lineNumber = MessageUtils.getLocalNumber(); 23213dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huang acknowledgeInd.setFrom(new EncodedStringValue(lineNumber)); 23313dbe96fc54f9b7190fd415d737f9a56dc409d10Wei Huang 23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Pack M-Acknowledge.ind and send it 235161c9154aa7aafa397332caee40b2776db988bf7Christian Gustafsson if(MmsConfig.getNotifyWapMMSC()) { 236161c9154aa7aafa397332caee40b2776db988bf7Christian Gustafsson sendPdu(new PduComposer(mContext, acknowledgeInd).make(), mContentLocation); 237161c9154aa7aafa397332caee40b2776db988bf7Christian Gustafsson } else { 238161c9154aa7aafa397332caee40b2776db988bf7Christian Gustafsson sendPdu(new PduComposer(mContext, acknowledgeInd).make()); 239161c9154aa7aafa397332caee40b2776db988bf7Christian Gustafsson } 24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static void updateContentLocation(Context context, Uri uri, 244864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor String contentLocation, 245864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor boolean locked) { 246864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor ContentValues values = new ContentValues(2); 24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project values.put(Mms.CONTENT_LOCATION, contentLocation); 248864d15179e4b6987e9cf97930d1033ffc2faa228Tom Taylor values.put(Mms.LOCKED, locked); // preserve the state of the M-Notification.ind lock. 24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SqliteWrapper.update(context, context.getContentResolver(), 25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project uri, values, null, null); 25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int getType() { 25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return RETRIEVE_TRANSACTION; 25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 258