GsmSMSDispatcher.java revision c99dab56e20222b28cbc6238645feac938f1c333
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/* 2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 The Android Open Source Project 3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License. 6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at 7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * http://www.apache.org/licenses/LICENSE-2.0 9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software 11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and 14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License. 15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony.gsm; 18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 19c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.Activity; 208d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wangimport android.app.AppOpsManager; 21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent; 22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.app.PendingIntent.CanceledException; 238d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wangimport android.content.BroadcastReceiver; 248d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wangimport android.content.ComponentName; 258d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wangimport android.content.Context; 26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Intent; 27c99dab56e20222b28cbc6238645feac938f1c333Ye Wenimport android.net.Uri; 28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult; 29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message; 30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Telephony.Sms; 31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.provider.Telephony.Sms.Intents; 32ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 33c99dab56e20222b28cbc6238645feac938f1c333Ye Wenimport android.telephony.SubscriptionManager; 34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.GsmAlphabet; 36ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowaimport com.android.internal.telephony.ImsSMSDispatcher; 37ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowaimport com.android.internal.telephony.InboundSmsHandler; 38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.PhoneBase; 39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SMSDispatcher; 400d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.SmsConstants; 41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SmsHeader; 42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SmsUsageMonitor; 431260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.uicc.IccRecords; 44d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils; 451260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.uicc.UiccCardApplication; 461260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport com.android.internal.telephony.uicc.UiccController; 47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.HashMap; 49c99dab56e20222b28cbc6238645feac938f1c333Ye Wenimport java.util.concurrent.atomic.AtomicBoolean; 50c99dab56e20222b28cbc6238645feac938f1c333Ye Wenimport java.util.concurrent.atomic.AtomicInteger; 511260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowaimport java.util.concurrent.atomic.AtomicReference; 52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic final class GsmSMSDispatcher extends SMSDispatcher { 54cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville private static final String TAG = "GsmSMSDispatcher"; 551260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa private static final boolean VDBG = false; 561260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa protected UiccController mUiccController = null; 571260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa private AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>(); 581260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa private AtomicReference<UiccCardApplication> mUiccApplication = 591260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa new AtomicReference<UiccCardApplication>(); 601260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa private GsmInboundSmsHandler mGsmInboundSmsHandler; 61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** Status report received */ 63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_NEW_SMS_STATUS_REPORT = 100; 64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 65ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa public GsmSMSDispatcher(PhoneBase phone, SmsUsageMonitor usageMonitor, 66ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa ImsSMSDispatcher imsSMSDispatcher, 671260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa GsmInboundSmsHandler gsmInboundSmsHandler) { 68ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa super(phone, usageMonitor, imsSMSDispatcher); 6922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null); 701260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mGsmInboundSmsHandler = gsmInboundSmsHandler; 71ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa mUiccController = UiccController.getInstance(); 72ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); 731260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa Rlog.d(TAG, "GsmSMSDispatcher created"); 74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void dispose() { 780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby super.dispose(); 7922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.unSetOnSmsStatus(this); 80ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa mUiccController.unregisterForIccChanged(this); 81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected String getFormat() { 85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return SmsConstants.FORMAT_3GPP; 86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Handles 3GPP format-specific events coming from the phone stack. 90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Other events are handled by {@link SMSDispatcher#handleMessage}. 91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param msg the message to handle 93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void handleMessage(Message msg) { 96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (msg.what) { 97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_NEW_SMS_STATUS_REPORT: 98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handleStatusReport((AsyncResult) msg.obj); 99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1011260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa case EVENT_NEW_ICC_SMS: 1021260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // pass to InboundSmsHandler to process 1031260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, msg.obj); 1041260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa break; 1051260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 1061260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa case EVENT_ICC_CHANGED: 1071260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa onUpdateIccAvailability(); 1081260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa break; 1091260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville default: 111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville super.handleMessage(msg); 112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Called when a status report is received. This should correspond to 117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * a previously successful SEND. 118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param ar AsyncResult passed into the message handler. ar.result should 120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * be a String representing the status report PDU, as ASCII hex. 121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void handleStatusReport(AsyncResult ar) { 123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String pduString = (String) ar.result; 124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsMessage sms = SmsMessage.newFromCDS(pduString); 125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (sms != null) { 127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int tpStatus = sms.getStatus(); 12822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville int messageRef = sms.mMessageRef; 129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville for (int i = 0, count = deliveryPendingList.size(); i < count; i++) { 130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsTracker tracker = deliveryPendingList.get(i); 131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (tracker.mMessageRef == messageRef) { 132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Found it. Remove from list and broadcast. 133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) { 134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville deliveryPendingList.remove(i); 1350217e2d6e60f7edd95407c7b385a627da9f1c1e3David Braun // Update the message status (COMPLETE or FAILED) 1360217e2d6e60f7edd95407c7b385a627da9f1c1e3David Braun tracker.updateSentMessageStatus(mContext, tpStatus); 137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville PendingIntent intent = tracker.mDeliveryIntent; 139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville Intent fillIn = new Intent(); 140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString)); 1411260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa fillIn.putExtra("format", getFormat()); 142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville try { 143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville intent.send(mContext, Activity.RESULT_OK, fillIn); 144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } catch (CanceledException ex) {} 145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Only expect to see one tracker matching this messageref 147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mCi.acknowledgeLastIncomingGsmSms(true, Intents.RESULT_SMS_HANDLED, null); 152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void sendData(String destAddr, String scAddr, int destPort, 157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville scAddr, destAddr, destPort, data, (deliveryIntent != null)); 160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (pdu != null) { 161ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa HashMap map = getSmsTrackerMap(destAddr, scAddr, destPort, data, pdu); 162c99dab56e20222b28cbc6238645feac938f1c333Ye Wen SmsTracker tracker = getSmsTracker(map, sentIntent, deliveryIntent, getFormat(), 163c99dab56e20222b28cbc6238645feac938f1c333Ye Wen null/*messageUri*/); 1641260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa sendRawPdu(tracker); 165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 166ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(TAG, "GsmSMSDispatcher.sendData(): getSubmitPdu() returned null"); 167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void sendText(String destAddr, String scAddr, String text, 173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville PendingIntent sentIntent, PendingIntent deliveryIntent) { 174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville scAddr, destAddr, text, (deliveryIntent != null)); 176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (pdu != null) { 177c99dab56e20222b28cbc6238645feac938f1c333Ye Wen final Uri messageUri = writeOutboxMessage( 178c99dab56e20222b28cbc6238645feac938f1c333Ye Wen SubscriptionManager.getPreferredSmsSubId(), 179c99dab56e20222b28cbc6238645feac938f1c333Ye Wen destAddr, 180c99dab56e20222b28cbc6238645feac938f1c333Ye Wen text, 181c99dab56e20222b28cbc6238645feac938f1c333Ye Wen deliveryIntent != null); 182ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa HashMap map = getSmsTrackerMap(destAddr, scAddr, text, pdu); 183c99dab56e20222b28cbc6238645feac938f1c333Ye Wen SmsTracker tracker = getSmsTracker(map, sentIntent, deliveryIntent, getFormat(), 184c99dab56e20222b28cbc6238645feac938f1c333Ye Wen messageUri); 1851260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa sendRawPdu(tracker); 186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 187ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null"); 188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 19363418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni protected void injectSmsPdu(byte[] pdu, String format, PendingIntent receivedIntent) { 19463418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni throw new IllegalStateException("This method must be called only on ImsSMSDispatcher"); 19563418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni } 19663418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni 19763418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni /** {@inheritDoc} */ 19863418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni @Override 199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected GsmAlphabet.TextEncodingDetails calculateLength(CharSequence messageBody, 200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean use7bitOnly) { 201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return SmsMessage.calculateLength(messageBody, use7bitOnly); 202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void sendNewSubmitPdu(String destinationAddress, String scAddress, 207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String message, SmsHeader smsHeader, int encoding, 208c99dab56e20222b28cbc6238645feac938f1c333Ye Wen PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart, 209c99dab56e20222b28cbc6238645feac938f1c333Ye Wen AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri) { 210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress, 211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader), 212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville encoding, smsHeader.languageTable, smsHeader.languageShiftTable); 213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (pdu != null) { 214ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa HashMap map = getSmsTrackerMap(destinationAddress, scAddress, 2151260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa message, pdu); 216ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa SmsTracker tracker = getSmsTracker(map, sentIntent, 217c99dab56e20222b28cbc6238645feac938f1c333Ye Wen deliveryIntent, getFormat(), unsentPartCount, anyPartFailed, messageUri); 2181260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa sendRawPdu(tracker); 219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else { 220ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(TAG, "GsmSMSDispatcher.sendNewSubmitPdu(): getSubmitPdu() returned null"); 221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** {@inheritDoc} */ 225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void sendSms(SmsTracker tracker) { 227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville HashMap<String, Object> map = tracker.mData; 228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville byte pdu[] = (byte[]) map.get("pdu"); 230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 231454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks if (tracker.mRetryCount > 0) { 232454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks Rlog.d(TAG, "sendSms: " 233454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks + " mRetryCount=" + tracker.mRetryCount 234454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks + " mMessageRef=" + tracker.mMessageRef 235454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks + " SS=" + mPhone.getServiceState().getState()); 236454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks 237454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks // per TS 23.040 Section 9.2.3.6: If TP-MTI SMS-SUBMIT (0x01) type 238454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks // TP-RD (bit 2) is 1 for retry 239454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks // and TP-MR is set to previously failed sms TP-MR 240454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks if (((0x01 & pdu[0]) == 0x01)) { 241454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks pdu[0] |= 0x04; // TP-RD 242454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks pdu[1] = (byte) tracker.mMessageRef; // TP-MR 243454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks } 244454c5783e7695feec276325920550b2d4dcc3e16Rika Brooks } 2451260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa Rlog.d(TAG, "sendSms: " 2468d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang + " isIms()=" + isIms() 2478d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang + " mRetryCount=" + tracker.mRetryCount 2488d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang + " mImsRetry=" + tracker.mImsRetry 2498d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang + " mMessageRef=" + tracker.mMessageRef 2508d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang + " SS=" + mPhone.getServiceState().getState()); 2518d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang 2528d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang // FIX this once the carrier app and SIM restricted API is finalized. 2538d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang // We should direct the intent to only the default carrier app. 2548d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang 2558d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang // Send SMS via the carrier app. 2568d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang BroadcastReceiver resultReceiver = new SMSDispatcherReceiver(tracker); 2578d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang 2588d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang Intent intent = new Intent(Intents.SMS_SEND_ACTION); 2598d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang intent.putExtra("pdu", pdu); 2608d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang intent.putExtra("smsc", (byte[]) map.get("smsc")); 2618d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang intent.putExtra("format", getFormat()); 2628d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 2638d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang Rlog.d(TAG, "Sending SMS by carrier app."); 2648d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang 2658d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang mContext.sendOrderedBroadcast(intent, android.Manifest.permission.RECEIVE_SMS, 2668d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang AppOpsManager.OP_RECEIVE_SMS, resultReceiver, 2678d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang null, Activity.RESULT_CANCELED, null, null); 2688d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang } 2698d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang 2708d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang /** {@inheritDoc} */ 2718d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang @Override 2728d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang protected void sendSmsByPstn(SmsTracker tracker) { 2738d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang HashMap<String, Object> map = tracker.mData; 2748d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang 2758d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang byte smsc[] = (byte[]) map.get("smsc"); 2768d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang byte[] pdu = (byte[]) map.get("pdu"); 2778d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 2781260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 2791260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // sms over gsm is used: 2801260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // if sms over IMS is not supported AND 2811260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // this is not a retry case after sms over IMS failed 2821260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // indicated by mImsRetry > 0 2831260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (0 == tracker.mImsRetry && !isIms()) { 2841260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (tracker.mRetryCount > 0) { 2851260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // per TS 23.040 Section 9.2.3.6: If TP-MTI SMS-SUBMIT (0x01) type 2861260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // TP-RD (bit 2) is 1 for retry 2871260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // and TP-MR is set to previously failed sms TP-MR 2881260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (((0x01 & pdu[0]) == 0x01)) { 2891260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa pdu[0] |= 0x04; // TP-RD 2901260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa pdu[1] = (byte) tracker.mMessageRef; // TP-MR 2911260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 2921260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 2931260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mCi.sendSMS(IccUtils.bytesToHexString(smsc), 2941260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa IccUtils.bytesToHexString(pdu), reply); 2951260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } else { 2961260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mCi.sendImsGsmSms(IccUtils.bytesToHexString(smsc), 2971260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa IccUtils.bytesToHexString(pdu), tracker.mImsRetry, 2981260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa tracker.mMessageRef, reply); 2991260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // increment it here, so in case of SMS_FAIL_RETRY over IMS 3001260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // next retry will be sent using IMS request again. 3011260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa tracker.mImsRetry++; 3021260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3031260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3041260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 3058d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang /** {@inheritDoc} */ 3068d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang @Override 3078d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang protected void updateSmsSendStatus(int messageRef, boolean success) { 3088d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang // This function should be defined in ImsDispatcher. 3098d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang Rlog.e(TAG, "updateSmsSendStatus should never be called from here!"); 3108d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang } 3118d8e8f45200d17b78d196d8cba389fd9c547ac11Cheuksan Wang 3121260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa protected UiccCardApplication getUiccCardApplication() { 313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.d(TAG, "GsmSMSDispatcher: subId = " + mPhone.getSubId() 314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville + " slotId = " + mPhone.getPhoneId()); 315a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mUiccController.getUiccCardApplication(mPhone.getPhoneId(), 316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UiccController.APP_FAM_3GPP); 3171260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3181260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 3191260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa private void onUpdateIccAvailability() { 3201260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (mUiccController == null ) { 3211260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa return; 3221260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3231260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 3241260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa UiccCardApplication newUiccApplication = getUiccCardApplication(); 3251260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 3261260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa UiccCardApplication app = mUiccApplication.get(); 3271260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (app != newUiccApplication) { 3281260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (app != null) { 3291260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa Rlog.d(TAG, "Removing stale icc objects."); 3301260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (mIccRecords.get() != null) { 3311260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mIccRecords.get().unregisterForNewSms(this); 3321260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3331260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mIccRecords.set(null); 3341260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mUiccApplication.set(null); 3351260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3361260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (newUiccApplication != null) { 3371260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa Rlog.d(TAG, "New Uicc application found"); 3381260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mUiccApplication.set(newUiccApplication); 3391260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mIccRecords.set(newUiccApplication.getIccRecords()); 3401260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (mIccRecords.get() != null) { 3411260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mIccRecords.get().registerForNewSms(this, EVENT_NEW_ICC_SMS, null); 3421260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3431260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3441260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 3451260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville} 347