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
20f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport static android.provider.Telephony.Sms.Intents.WAP_PUSH_RECEIVED_ACTION;
21f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_DELIVERY_IND;
22f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND;
23f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_READ_ORIG_IND;
2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
253b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafssonimport com.android.mms.MmsConfig;
26f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.ContentType;
27f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.MmsException;
28f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.DeliveryInd;
29f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.GenericPdu;
30f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.NotificationInd;
31f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduHeaders;
32f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduParser;
33f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister;
34f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.ReadOrigInd;
35fd644551e8506266aad2b76463b51b44154ed62fTom Taylorimport android.database.sqlite.SqliteWrapper;
3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.BroadcastReceiver;
3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver;
3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentValues;
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent;
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.DatabaseUtils;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.AsyncTask;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.PowerManager;
47f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms;
48f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms.Inbox;
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/**
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Receives Intent.WAP_PUSH_RECEIVED_ACTION intents and starts the
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * TransactionService by passing the push-data to it.
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class PushReceiver extends BroadcastReceiver {
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final String TAG = "PushReceiver";
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final boolean DEBUG = false;
58150c4179995cc0a75f934ef194372f9295957ca2Joe Onorato    private static final boolean LOCAL_LOGV = false;
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
60836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project    private class ReceivePushTask extends AsyncTask<Intent,Void,Void> {
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        private Context mContext;
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public ReceivePushTask(Context context) {
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mContext = context;
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        @Override
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        protected Void doInBackground(Intent... intents) {
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent intent = intents[0];
696be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Get raw PDU push-data from the message and parse it
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            byte[] pushData = intent.getByteArrayExtra("data");
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            PduParser parser = new PduParser(pushData);
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            GenericPdu pdu = parser.parse();
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (null == pdu) {
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Log.e(TAG, "Invalid PUSH data");
7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return null;
7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            PduPersister p = PduPersister.getPduPersister(mContext);
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ContentResolver cr = mContext.getContentResolver();
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int type = pdu.getMessageType();
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            long threadId = -1;
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            try {
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                switch (type) {
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    case MESSAGE_TYPE_DELIVERY_IND:
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    case MESSAGE_TYPE_READ_ORIG_IND: {
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        threadId = findThreadId(mContext, pdu, type);
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        if (threadId == -1) {
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            // The associated SendReq isn't found, therefore skip
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            // processing this PDU.
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            break;
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Uri uri = p.persist(pdu, Inbox.CONTENT_URI);
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        // Update thread ID for ReadOrigInd & DeliveryInd.
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        ContentValues values = new ContentValues(1);
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        values.put(Mms.THREAD_ID, threadId);
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        SqliteWrapper.update(mContext, cr, uri, values, null, null);
10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    case MESSAGE_TYPE_NOTIFICATION_IND: {
10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        NotificationInd nInd = (NotificationInd) pdu;
1053b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson
1063b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                        if (MmsConfig.getTransIdEnabled()) {
1073b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                            byte [] contentLocation = nInd.getContentLocation();
1083b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                            if ('=' == contentLocation[contentLocation.length - 1]) {
1093b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                                byte [] transactionId = nInd.getTransactionId();
1103b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                                byte [] contentLocationWithId = new byte [contentLocation.length
1113b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                                                                          + transactionId.length];
1123b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                                System.arraycopy(contentLocation, 0, contentLocationWithId,
1133b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                                        0, contentLocation.length);
1143b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                                System.arraycopy(transactionId, 0, contentLocationWithId,
1153b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                                        contentLocation.length, transactionId.length);
1163b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                                nInd.setContentLocation(contentLocationWithId);
1173b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                            }
1183b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson                        }
1193b9acf897f4bdd4d76cbcf10d7bd2728c941c7d5Christian Gustafsson
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        if (!isDuplicateNotification(mContext, nInd)) {
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            Uri uri = p.persist(pdu, Inbox.CONTENT_URI);
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            // Start service to finish the notification transaction.
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            Intent svc = new Intent(mContext, TransactionService.class);
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            svc.putExtra(TransactionBundle.URI, uri.toString());
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            svc.putExtra(TransactionBundle.TRANSACTION_TYPE,
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    Transaction.NOTIFICATION_TRANSACTION);
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            mContext.startService(svc);
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        } else if (LOCAL_LOGV) {
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            Log.v(TAG, "Skip downloading duplicate message: "
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    + new String(nInd.getContentLocation()));
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    default:
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Log.e(TAG, "Received unrecognized PDU.");
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } catch (MmsException e) {
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Log.e(TAG, "Failed to save the data from PUSH: type=" + type, e);
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } catch (RuntimeException e) {
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Log.e(TAG, "Unexpected RuntimeException.", e);
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (LOCAL_LOGV) {
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Log.v(TAG, "PUSH Intent processed.");
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return null;
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
1506be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onReceive(Context context, Intent intent) {
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (intent.getAction().equals(WAP_PUSH_RECEIVED_ACTION)
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                && ContentType.MMS_MESSAGE.equals(intent.getType())) {
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (LOCAL_LOGV) {
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Log.v(TAG, "Received PUSH Intent: " + intent);
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
1586be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor
159836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            // Hold a wake lock for 5 seconds, enough to give any
160836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            // services we start time to take their own wake locks.
161836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
162836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
163836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project                                            "MMS PushReceiver");
164836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            wl.acquire(5000);
16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            new ReceivePushTask(context).execute(intent);
16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static long findThreadId(Context context, GenericPdu pdu, int type) {
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String messageId;
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (type == MESSAGE_TYPE_DELIVERY_IND) {
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            messageId = new String(((DeliveryInd) pdu).getMessageId());
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            messageId = new String(((ReadOrigInd) pdu).getMessageId());
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder sb = new StringBuilder('(');
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        sb.append(Mms.MESSAGE_ID);
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        sb.append('=');
18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        sb.append(DatabaseUtils.sqlEscapeString(messageId));
18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        sb.append(" AND ");
18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        sb.append(Mms.MESSAGE_TYPE);
18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        sb.append('=');
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        sb.append(PduHeaders.MESSAGE_TYPE_SEND_REQ);
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // TODO ContentResolver.query() appends closing ')' to the selection argument
18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // sb.append(')');
18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            Mms.CONTENT_URI, new String[] { Mms.THREAD_ID },
19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            sb.toString(), null, null);
19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (cursor != null) {
19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            try {
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if ((cursor.getCount() == 1) && cursor.moveToFirst()) {
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return cursor.getLong(0);
19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } finally {
19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                cursor.close();
19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return -1;
20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static boolean isDuplicateNotification(
20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Context context, NotificationInd nInd) {
20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        byte[] rawLocation = nInd.getContentLocation();
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (rawLocation != null) {
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String location = new String(rawLocation);
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String selection = Mms.CONTENT_LOCATION + " = ?";
21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String[] selectionArgs = new String[] { location };
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Cursor cursor = SqliteWrapper.query(
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context, context.getContentResolver(),
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Mms.CONTENT_URI, new String[] { Mms._ID },
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    selection, selectionArgs, null);
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (cursor != null) {
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (cursor.getCount() > 0) {
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        // We already received the same notification before.
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        return true;
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } finally {
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    cursor.close();
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
230