10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2008 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 19271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yenimport static android.telephony.SmsManager.STATUS_ON_ICC_FREE; 20271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yenimport static android.telephony.SmsManager.STATUS_ON_ICC_READ; 21271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yenimport static android.telephony.SmsManager.STATUS_ON_ICC_UNREAD; 22271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yen 237fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.Manifest; 247fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.app.AppOpsManager; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.PendingIntent; 26b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.content.ContentResolver; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context; 284256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupalaimport android.content.Intent; 294256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupalaimport android.content.pm.PackageManager; 30b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.database.Cursor; 31b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.database.sqlite.SQLiteException; 32b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.net.Uri; 33ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.AsyncResult; 347fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.os.Binder; 35ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.Handler; 36ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.Message; 37a2ce002a0327f0deb079cc6acad1c493e6ded442Amith Yamasaniimport android.os.UserManager; 38b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.provider.Telephony; 394256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupalaimport android.service.carrier.CarrierMessagingService; 40ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 41b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.telephony.SmsManager; 42f3166841bf9df142e2fbd63b7647bae7da712044Xia Yingimport android.telephony.SmsMessage; 43271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yenimport android.telephony.TelephonyManager; 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log; 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 466f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowaimport com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo; 47271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yenimport com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; 48d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccConstants; 49ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport com.android.internal.telephony.uicc.IccFileHandler; 5017a3c8b39f73dac470b53934191679899450d97aAmit Mahajanimport com.android.internal.telephony.uicc.IccUtils; 51c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport com.android.internal.telephony.uicc.UiccController; 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.HexDump; 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList; 55ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport java.util.Arrays; 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List; 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * IccSmsInterfaceManager to provide an inter-process communication to 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * access Sms in Icc. 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 62a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillepublic class IccSmsInterfaceManager { 63cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville static final String LOG_TAG = "IccSmsInterfaceManager"; 64ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks static final boolean DBG = true; 65ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 66ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks protected final Object mLock = new Object(); 67ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks protected boolean mSuccess; 68ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks private List<SmsRawData> mSms; 69ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private CellBroadcastRangeManager mCellBroadcastRangeManager = 716f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa new CellBroadcastRangeManager(); 726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private CdmaBroadcastRangeManager mCdmaBroadcastRangeManager = 736f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa new CdmaBroadcastRangeManager(); 746f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 75ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks private static final int EVENT_LOAD_DONE = 1; 76ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks private static final int EVENT_UPDATE_DONE = 2; 77ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks protected static final int EVENT_SET_BROADCAST_ACTIVATION_DONE = 3; 78ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks protected static final int EVENT_SET_BROADCAST_CONFIG_DONE = 4; 796f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private static final int SMS_CB_CODE_SCHEME_MIN = 0; 806f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private static final int SMS_CB_CODE_SCHEME_MAX = 255; 81ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 821a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu protected Phone mPhone; 837fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn final protected Context mContext; 847fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn final protected AppOpsManager mAppOps; 85a2ce002a0327f0deb079cc6acad1c493e6ded442Amith Yamasani final private UserManager mUserManager; 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected SMSDispatcher mDispatcher; 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 88ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks protected Handler mHandler = new Handler() { 89ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks @Override 90ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks public void handleMessage(Message msg) { 91ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks AsyncResult ar; 92ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 93ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks switch (msg.what) { 94ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks case EVENT_UPDATE_DONE: 95ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks ar = (AsyncResult) msg.obj; 96ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks synchronized (mLock) { 97ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mSuccess = (ar.exception == null); 98ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mLock.notifyAll(); 99ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 100ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks break; 101ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks case EVENT_LOAD_DONE: 102ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks ar = (AsyncResult)msg.obj; 103ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks synchronized (mLock) { 104ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (ar.exception == null) { 105ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa mSms = buildValidRawData((ArrayList<byte[]>) ar.result); 106ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks //Mark SMS as read after importing it from card. 107ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks markMessagesAsRead((ArrayList<byte[]>) ar.result); 108ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } else { 1096f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (Rlog.isLoggable("SMS", Log.DEBUG)) { 1106f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Cannot load Sms records"); 1116f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 1123be9fb032307d7586b32dc57ddd486e8e9d43bd2fionaxu mSms = null; 113ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 114ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mLock.notifyAll(); 115ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 116ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks break; 117ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks case EVENT_SET_BROADCAST_ACTIVATION_DONE: 118ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks case EVENT_SET_BROADCAST_CONFIG_DONE: 119ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks ar = (AsyncResult) msg.obj; 120ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks synchronized (mLock) { 121ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mSuccess = (ar.exception == null); 122ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mLock.notifyAll(); 123ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 124ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks break; 125ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 126ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 127ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks }; 128ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 1291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu protected IccSmsInterfaceManager(Phone phone) { 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone = phone; 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mContext = phone.getContext(); 1326f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); 133a2ce002a0327f0deb079cc6acad1c493e6ded442Amith Yamasani mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 1341260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mDispatcher = new ImsSMSDispatcher(phone, 1351260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa phone.mSmsStorageMonitor, phone.mSmsUsageMonitor); 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 138ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks protected void markMessagesAsRead(ArrayList<byte[]> messages) { 139ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (messages == null) { 140ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks return; 141ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 142ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 143ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks //IccFileHandler can be null, if icc card is absent. 144ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks IccFileHandler fh = mPhone.getIccFileHandler(); 145ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (fh == null) { 146ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks //shouldn't really happen, as messages are marked as read, only 147ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks //after importing it from icc. 148ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (Rlog.isLoggable("SMS", Log.DEBUG)) { 149ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks log("markMessagesAsRead - aborting, no icc card present."); 150ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 151ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks return; 152ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 153ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 154ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks int count = messages.size(); 155ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 156ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks for (int i = 0; i < count; i++) { 157ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks byte[] ba = messages.get(i); 158ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (ba[0] == STATUS_ON_ICC_UNREAD) { 159ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks int n = ba.length; 160ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks byte[] nba = new byte[n - 1]; 161ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks System.arraycopy(ba, 1, nba, 0, n - 1); 162ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks byte[] record = makeSmsRecordData(STATUS_ON_ICC_READ, nba); 163ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks fh.updateEFLinearFixed(IccConstants.EF_SMS, i + 1, record, null, null); 164ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (Rlog.isLoggable("SMS", Log.DEBUG)) { 165ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks log("SMS " + (i + 1) + " marked as read"); 166ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 167ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 168ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 169ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 170ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 1711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu protected void updatePhoneObject(Phone phone) { 1726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone = phone; 1731260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa mDispatcher.updatePhoneObject(phone); 1746f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 1756f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void enforceReceiveAndSend(String message) { 177c6cbdea1423262784e0a155f93be75f3f72e242cxinhe mContext.enforceCallingOrSelfPermission( 1787fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn Manifest.permission.RECEIVE_SMS, message); 179c6cbdea1423262784e0a155f93be75f3f72e242cxinhe mContext.enforceCallingOrSelfPermission( 1807fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn Manifest.permission.SEND_SMS, message); 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 184ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * Update the specified message on the Icc. 185ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * 186ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * @param index record index of message to update 187ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * @param status new message status (STATUS_ON_ICC_READ, 188ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT, 189ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE) 190ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * @param pdu the raw PDU to store 191ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * @return success or not 192ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * 193ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks */ 194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 195ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks public boolean 1967fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn updateMessageOnIccEf(String callingPackage, int index, int status, byte[] pdu) { 197ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (DBG) log("updateMessageOnIccEf: index=" + index + 198ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks " status=" + status + " ==> " + 199ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks "("+ Arrays.toString(pdu) + ")"); 200ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks enforceReceiveAndSend("Updating message on Icc"); 2017fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn if (mAppOps.noteOp(AppOpsManager.OP_WRITE_ICC_SMS, Binder.getCallingUid(), 2027fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn callingPackage) != AppOpsManager.MODE_ALLOWED) { 2037fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn return false; 2047fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn } 205ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks synchronized(mLock) { 206ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mSuccess = false; 207ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 208ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 209ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (status == STATUS_ON_ICC_FREE) { 210ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks // RIL_REQUEST_DELETE_SMS_ON_SIM vs RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 211ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks // Special case FREE: call deleteSmsOnSim/Ruim instead of 212ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks // manipulating the record 213ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks // Will eventually fail if icc card is not present. 2146f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (PhoneConstants.PHONE_TYPE_GSM == mPhone.getPhoneType()) { 2156f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone.mCi.deleteSmsOnSim(index, response); 2166f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } else { 2176f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone.mCi.deleteSmsOnRuim(index, response); 2186f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 219ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } else { 220ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks //IccFilehandler can be null if ICC card is not present. 221ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks IccFileHandler fh = mPhone.getIccFileHandler(); 222ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (fh == null) { 223ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks response.recycle(); 224ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks return mSuccess; /* is false */ 225ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 226ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks byte[] record = makeSmsRecordData(status, pdu); 227ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks fh.updateEFLinearFixed( 228ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks IccConstants.EF_SMS, 229ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks index, record, null, response); 230ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 231ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks try { 232ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mLock.wait(); 233ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } catch (InterruptedException e) { 234ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks log("interrupted while trying to update by index"); 235ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 236ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 237ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks return mSuccess; 238ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 239ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 240ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks /** 241ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * Copy a raw SMS PDU to the Icc. 242ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * 243ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * @param pdu the raw PDU to store 244ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD, 245ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT) 246ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * @return success or not 247ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * 248ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks */ 2497fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn public boolean copyMessageToIccEf(String callingPackage, int status, byte[] pdu, byte[] smsc) { 250ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks //NOTE smsc not used in RUIM 251ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " + 252ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks "pdu=("+ Arrays.toString(pdu) + 253ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks "), smsc=(" + Arrays.toString(smsc) +")"); 254ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks enforceReceiveAndSend("Copying message to Icc"); 2557fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn if (mAppOps.noteOp(AppOpsManager.OP_WRITE_ICC_SMS, Binder.getCallingUid(), 2567fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn callingPackage) != AppOpsManager.MODE_ALLOWED) { 2577fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn return false; 2587fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn } 259ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks synchronized(mLock) { 260ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mSuccess = false; 261ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 262ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 263ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks //RIL_REQUEST_WRITE_SMS_TO_SIM vs RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 2646f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (PhoneConstants.PHONE_TYPE_GSM == mPhone.getPhoneType()) { 2656f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone.mCi.writeSmsToSim(status, IccUtils.bytesToHexString(smsc), 2666f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa IccUtils.bytesToHexString(pdu), response); 2676f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } else { 2686f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone.mCi.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu), 2696f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa response); 2706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 271ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 272ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks try { 273ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mLock.wait(); 274ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } catch (InterruptedException e) { 275ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks log("interrupted while trying to update by index"); 276ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 277ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 278ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks return mSuccess; 279ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 280ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 281ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks /** 282ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * Retrieves all messages currently stored on Icc. 283ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * 284ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks * @return list of SmsRawData of all sms on Icc 285ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks */ 286a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 2877fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn public List<SmsRawData> getAllMessagesFromIccEf(String callingPackage) { 288ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (DBG) log("getAllMessagesFromEF"); 289ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 290e5d7a8d946bf9496ffbe7533bffdeb83963489c3Jake Hamby mContext.enforceCallingOrSelfPermission( 2917fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn Manifest.permission.RECEIVE_SMS, 292ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks "Reading messages from Icc"); 2937fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn if (mAppOps.noteOp(AppOpsManager.OP_READ_ICC_SMS, Binder.getCallingUid(), 2947fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn callingPackage) != AppOpsManager.MODE_ALLOWED) { 2957fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn return new ArrayList<SmsRawData>(); 2967fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn } 297ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks synchronized(mLock) { 298ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 299ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks IccFileHandler fh = mPhone.getIccFileHandler(); 300ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks if (fh == null) { 301ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks Rlog.e(LOG_TAG, "Cannot load Sms records. No icc card?"); 3023be9fb032307d7586b32dc57ddd486e8e9d43bd2fionaxu mSms = null; 3033be9fb032307d7586b32dc57ddd486e8e9d43bd2fionaxu return mSms; 304ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 305ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 306ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks Message response = mHandler.obtainMessage(EVENT_LOAD_DONE); 307ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks fh.loadEFLinearFixedAll(IccConstants.EF_SMS, response); 308ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 309ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks try { 310ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks mLock.wait(); 311ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } catch (InterruptedException e) { 312ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks log("interrupted while trying to load from the Icc"); 313ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 314ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 315ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks return mSms; 316ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks } 317ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 318ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks /** 319c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen * A permissions check before passing to {@link IccSmsInterfaceManager#sendDataInternal}. 320c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen * This method checks if the calling package or itself has the permission to send the data sms. 321c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen */ 322c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen public void sendDataWithSelfPermissions(String callingPackage, String destAddr, String scAddr, 323c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 324c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen mPhone.getContext().enforceCallingOrSelfPermission( 325c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen Manifest.permission.SEND_SMS, 326c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen "Sending SMS message"); 327c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen sendDataInternal(callingPackage, destAddr, scAddr, destPort, data, sentIntent, 328c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen deliveryIntent); 329c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen } 330c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen 331c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen /** 332c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen * A permissions check before passing to {@link IccSmsInterfaceManager#sendDataInternal}. 333c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen * This method checks only if the calling package has the permission to send the data sms. 334c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen */ 335c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen public void sendData(String callingPackage, String destAddr, String scAddr, int destPort, 336c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 337c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen mPhone.getContext().enforceCallingPermission( 338c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen Manifest.permission.SEND_SMS, 339c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen "Sending SMS message"); 340c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen sendDataInternal(callingPackage, destAddr, scAddr, destPort, data, sentIntent, 341c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen deliveryIntent); 342c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen } 343c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen 344c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen /** 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Send a data based SMS to a specific application port. 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr the address to send the message to 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param scAddr is the service center address or null to use 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the current default SMSC 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destPort the port to deliver the message to 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data the body of the message to send 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param sentIntent if not NULL this <code>PendingIntent</code> is 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * broadcast when the message is successfully sent, or failed. 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The result code will be <code>Activity.RESULT_OK<code> for success, 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * or one of these errors:<br> 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_RADIO_OFF</code><br> 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_NULL_PDU</code><br> 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the extra "errorCode" containing a radio technology specific value, 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * generally only useful for troubleshooting.<br> 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The per-application based SMS control checks sentIntent. If sentIntent 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * is NULL the caller will be checked against all unknown applications, 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * which cause smaller number of SMS to be sent in checking period. 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * broadcast when the message is delivered to the recipient. The 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * raw pdu of the status report is in the extended data ("pdu"). 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 369a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 370c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen private void sendDataInternal(String callingPackage, String destAddr, String scAddr, 371c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 372ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable("SMS", Log.VERBOSE)) { 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" + 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" + 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sentIntent + " deliveryIntent=" + deliveryIntent); 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3777fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), 3787fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn callingPackage) != AppOpsManager.MODE_ALLOWED) { 3797fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn return; 3807fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn } 38170dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying destAddr = filterDestAddress(destAddr); 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent); 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 386c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen * A permissions check before passing to {@link IccSmsInterfaceManager#sendTextInternal}. 387c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen * This method checks only if the calling package has the permission to send the sms. 388c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen */ 389c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen public void sendText(String callingPackage, String destAddr, String scAddr, 390a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang String text, PendingIntent sentIntent, PendingIntent deliveryIntent, 391a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang boolean persistMessageForNonDefaultSmsApp) { 392c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen mPhone.getContext().enforceCallingPermission( 393c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen Manifest.permission.SEND_SMS, 394c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen "Sending SMS message"); 395a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang sendTextInternal(callingPackage, destAddr, scAddr, text, sentIntent, deliveryIntent, 396a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang persistMessageForNonDefaultSmsApp); 397c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen } 398c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen 399c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen /** 400c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen * A permissions check before passing to {@link IccSmsInterfaceManager#sendTextInternal}. 401c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen * This method checks if the calling package or itself has the permission to send the sms. 402c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen */ 403c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen public void sendTextWithSelfPermissions(String callingPackage, String destAddr, String scAddr, 404271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yen String text, PendingIntent sentIntent, PendingIntent deliveryIntent, 405271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yen boolean persistMessage) { 406c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen mPhone.getContext().enforceCallingOrSelfPermission( 407c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen Manifest.permission.SEND_SMS, 408c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen "Sending SMS message"); 409a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang sendTextInternal(callingPackage, destAddr, scAddr, text, sentIntent, deliveryIntent, 410271770174f97e010dab9b7916034aecb270b1d81Ta-wei Yen persistMessage); 411c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen } 412c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen 413c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen /** 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Send a text based SMS. 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr the address to send the message to 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param scAddr is the service center address or null to use 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the current default SMSC 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param text the body of the message to send 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param sentIntent if not NULL this <code>PendingIntent</code> is 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * broadcast when the message is successfully sent, or failed. 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The result code will be <code>Activity.RESULT_OK<code> for success, 4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * or one of these errors:<br> 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_RADIO_OFF</code><br> 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_NULL_PDU</code><br> 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the extra "errorCode" containing a radio technology specific value, 4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * generally only useful for troubleshooting.<br> 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The per-application based SMS control checks sentIntent. If sentIntent 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * is NULL the caller will be checked against all unknown applications, 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * which cause smaller number of SMS to be sent in checking period. 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * broadcast when the message is delivered to the recipient. The 4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * raw pdu of the status report is in the extended data ("pdu"). 4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 437a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 438c55f67e3fa488c5f8aa90fda1ae43ef9d32cef52Nancy Chen private void sendTextInternal(String callingPackage, String destAddr, String scAddr, 439a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang String text, PendingIntent sentIntent, PendingIntent deliveryIntent, 440a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang boolean persistMessageForNonDefaultSmsApp) { 441ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable("SMS", Log.VERBOSE)) { 4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr + 4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville " text='"+ text + "' sentIntent=" + 4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sentIntent + " deliveryIntent=" + deliveryIntent); 4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4467fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), 4477fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn callingPackage) != AppOpsManager.MODE_ALLOWED) { 4487fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn return; 4497fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn } 450a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang if (!persistMessageForNonDefaultSmsApp) { 451532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry enforcePrivilegedAppPermissions(); 452a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang } 45370dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying destAddr = filterDestAddress(destAddr); 454b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent, 455a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang null/*messageUri*/, callingPackage, persistMessageForNonDefaultSmsApp); 4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 45963418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni * Inject an SMS PDU into the android application framework. 46063418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni * 46163418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni * @param pdu is the byte array of pdu to be injected into android application framework 46263418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni * @param format is the format of SMS pdu (3gpp or 3gpp2) 46363418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni * @param receivedIntent if not NULL this <code>PendingIntent</code> is 46463418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni * broadcast when the message is successfully received by the 46563418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni * android application framework. This intent is broadcasted at 46663418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni * the same time an SMS received from radio is acknowledged back. 46763418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni */ 46863418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni public void injectSmsPdu(byte[] pdu, String format, PendingIntent receivedIntent) { 469532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry enforcePrivilegedAppPermissions(); 47063418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni if (Rlog.isLoggable("SMS", Log.VERBOSE)) { 47163418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni log("pdu: " + pdu + 47263418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni "\n format=" + format + 47363418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni "\n receivedIntent=" + receivedIntent); 47463418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni } 47563418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni mDispatcher.injectSmsPdu(pdu, format, receivedIntent); 47663418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni } 47763418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni 47863418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni /** 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Send a multi-part text based SMS. 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr the address to send the message to 4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param scAddr is the service center address or null to use 4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the current default SMSC 4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param parts an <code>ArrayList</code> of strings that, in order, 4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * comprise the original message 4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param sentIntents if not null, an <code>ArrayList</code> of 4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>PendingIntent</code>s (one for each message part) that is 4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * broadcast when the corresponding message part has been sent. 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The result code will be <code>Activity.RESULT_OK<code> for success, 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * or one of these errors: 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_GENERIC_FAILURE</code> 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_RADIO_OFF</code> 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>RESULT_ERROR_NULL_PDU</code>. 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The per-application based SMS control checks sentIntent. If sentIntent 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * is NULL the caller will be checked against all unknown applications, 4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * which cause smaller number of SMS to be sent in checking period. 4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param deliveryIntents if not null, an <code>ArrayList</code> of 4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <code>PendingIntent</code>s (one for each message part) that is 4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * broadcast when the corresponding message part has been delivered 5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * to the recipient. The raw pdu of the status report is in the 5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * extended data ("pdu"). 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 503a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 5047fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn public void sendMultipartText(String callingPackage, String destAddr, String scAddr, 5057fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn List<String> parts, List<PendingIntent> sentIntents, 506a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) { 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.getContext().enforceCallingPermission( 5087fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn Manifest.permission.SEND_SMS, 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "Sending SMS message"); 510a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang if (!persistMessageForNonDefaultSmsApp) { 5114256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala // Only allow carrier app or carrier ims to skip auto message persistence. 512532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry enforcePrivilegedAppPermissions(); 513a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang } 514ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable("SMS", Log.VERBOSE)) { 5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int i = 0; 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (String part : parts) { 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr + 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ", part[" + (i++) + "]=" + part); 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5217fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), 5227fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn callingPackage) != AppOpsManager.MODE_ALLOWED) { 5237fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn return; 5247fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn } 525f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 526bd681a048599441c659f3d3a8300e47599783d54Xia Ying destAddr = filterDestAddress(destAddr); 527bd681a048599441c659f3d3a8300e47599783d54Xia Ying 528f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying if (parts.size() > 1 && parts.size() < 10 && !SmsMessage.hasEmsSupport()) { 529f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying for (int i = 0; i < parts.size(); i++) { 530f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying // If EMS is not supported, we have to break down EMS into single segment SMS 531f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying // and add page info " x/y". 532f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying String singlePart = parts.get(i); 533f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying if (SmsMessage.shouldAppendPageNumberAsPrefix()) { 534f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singlePart = String.valueOf(i + 1) + '/' + parts.size() + ' ' + singlePart; 535f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } else { 536f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singlePart = singlePart.concat(' ' + String.valueOf(i + 1) + '/' + parts.size()); 537f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 538f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 539f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying PendingIntent singleSentIntent = null; 540f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying if (sentIntents != null && sentIntents.size() > i) { 541f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singleSentIntent = sentIntents.get(i); 542f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 543f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 544f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying PendingIntent singleDeliveryIntent = null; 545f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying if (deliveryIntents != null && deliveryIntents.size() > i) { 546f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singleDeliveryIntent = deliveryIntents.get(i); 547f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 548f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 549f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying mDispatcher.sendText(destAddr, scAddr, singlePart, 550f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singleSentIntent, singleDeliveryIntent, 551a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang null/*messageUri*/, callingPackage, 552a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang persistMessageForNonDefaultSmsApp); 553f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 554f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying return; 555f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 556f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts, 558b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents, 559a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang null/*messageUri*/, callingPackage, persistMessageForNonDefaultSmsApp); 5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 562a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 5634658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby public int getPremiumSmsPermission(String packageName) { 5644658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby return mDispatcher.getPremiumSmsPermission(packageName); 5654658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby } 5664658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby 567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 5684658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby public void setPremiumSmsPermission(String packageName, int permission) { 5694658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby mDispatcher.setPremiumSmsPermission(packageName, permission); 5704658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby } 5714658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby 5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * create SmsRawData lists from all sms record byte[] 5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Use null to indicate "free" record 5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param messages List of message records from EF_SMS. 5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return SmsRawData list of all in-used records 5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) { 5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int count = messages.size(); 5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ArrayList<SmsRawData> ret; 5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = new ArrayList<SmsRawData>(count); 5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < count; i++) { 5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] ba = messages.get(i); 5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ba[0] == STATUS_ON_ICC_FREE) { 5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.add(null); 5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret.add(new SmsRawData(messages.get(i))); 5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret; 5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Generates an EF_SMS record from status and raw PDU. 5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param status Message status. See TS 51.011 10.5.3. 6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param pdu Raw message PDU. 6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return byte array for the record. 6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected byte[] makeSmsRecordData(int status, byte[] pdu) { 6050e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla byte[] data; 6060e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla if (PhoneConstants.PHONE_TYPE_GSM == mPhone.getPhoneType()) { 607444c570f0beab900e6c45f4270ab52c46a4c2d7fNathan Harold data = new byte[SmsManager.SMS_RECORD_LENGTH]; 6080e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla } else { 609444c570f0beab900e6c45f4270ab52c46a4c2d7fNathan Harold data = new byte[SmsManager.CDMA_SMS_RECORD_LENGTH]; 6100e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla } 6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Status bits for this record. See TS 51.011 10.5.3 6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[0] = (byte)(status & 7); 6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(pdu, 0, data, 1, pdu.length); 6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Pad out with 0xFF's. 6180e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla for (int j = pdu.length+1; j < data.length; j++) { 6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[j] = -1; 6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return data; 6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 625a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe public boolean enableCellBroadcast(int messageIdentifier, int ranType) { 626a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe return enableCellBroadcastRange(messageIdentifier, messageIdentifier, ranType); 6276f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6286f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 629a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe public boolean disableCellBroadcast(int messageIdentifier, int ranType) { 630a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe return disableCellBroadcastRange(messageIdentifier, messageIdentifier, ranType); 6316f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6326f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 633a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe public boolean enableCellBroadcastRange(int startMessageId, int endMessageId, int ranType) { 634a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_GSM) { 6356f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return enableGsmBroadcastRange(startMessageId, endMessageId); 636a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe } else if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA) { 6376f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return enableCdmaBroadcastRange(startMessageId, endMessageId); 638a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe } else { 639a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe throw new IllegalArgumentException("Not a supportted RAN Type"); 6406f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6416f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6426f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 643a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe public boolean disableCellBroadcastRange(int startMessageId, int endMessageId, int ranType) { 644a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_GSM ) { 6456f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return disableGsmBroadcastRange(startMessageId, endMessageId); 646a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe } else if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA) { 6476f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return disableCdmaBroadcastRange(startMessageId, endMessageId); 648a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe } else { 649a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe throw new IllegalArgumentException("Not a supportted RAN Type"); 6506f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6516f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6526f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6536f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa synchronized public boolean enableGsmBroadcastRange(int startMessageId, int endMessageId) { 6546f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6556f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Context context = mPhone.getContext(); 6566f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6576f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa context.enforceCallingPermission( 6586f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa "android.permission.RECEIVE_SMS", 6596f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa "Enabling cell broadcast SMS"); 6606f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6616f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa String client = context.getPackageManager().getNameForUid( 6626f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Binder.getCallingUid()); 6636f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6646f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) { 665a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe log("Failed to add GSM cell broadcast subscription for MID range " + startMessageId 6666f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa + " to " + endMessageId + " from client " + client); 6676f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return false; 6686f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6696f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (DBG) 671a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe log("Added GSM cell broadcast subscription for MID range " + startMessageId 6726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa + " to " + endMessageId + " from client " + client); 6736f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6746f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty()); 6756f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6766f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return true; 6776f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6786f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6796f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa synchronized public boolean disableGsmBroadcastRange(int startMessageId, int endMessageId) { 6806f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6816f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Context context = mPhone.getContext(); 6826f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6836f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa context.enforceCallingPermission( 6846f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa "android.permission.RECEIVE_SMS", 6856f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa "Disabling cell broadcast SMS"); 6866f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6876f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa String client = context.getPackageManager().getNameForUid( 6886f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Binder.getCallingUid()); 6896f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6906f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) { 691a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe log("Failed to remove GSM cell broadcast subscription for MID range " + startMessageId 6926f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa + " to " + endMessageId + " from client " + client); 6936f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return false; 6946f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 6956f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 6966f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (DBG) 697a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe log("Removed GSM cell broadcast subscription for MID range " + startMessageId 6986f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa + " to " + endMessageId + " from client " + client); 6996f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7006f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty()); 7016f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7026f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return true; 7036f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7046f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7056f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa synchronized public boolean enableCdmaBroadcastRange(int startMessageId, int endMessageId) { 7066f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7076f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Context context = mPhone.getContext(); 7086f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7096f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa context.enforceCallingPermission( 7106f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa "android.permission.RECEIVE_SMS", 7116f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa "Enabling cdma broadcast SMS"); 7126f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7136f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa String client = context.getPackageManager().getNameForUid( 7146f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Binder.getCallingUid()); 7156f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7166f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (!mCdmaBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) { 7176f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Failed to add cdma broadcast subscription for MID range " + startMessageId 7186f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa + " to " + endMessageId + " from client " + client); 7196f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return false; 7206f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7216f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7226f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (DBG) 7236f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Added cdma broadcast subscription for MID range " + startMessageId 7246f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa + " to " + endMessageId + " from client " + client); 7256f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7266f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa setCdmaBroadcastActivation(!mCdmaBroadcastRangeManager.isEmpty()); 7276f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7286f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return true; 7296f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7306f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7316f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa synchronized public boolean disableCdmaBroadcastRange(int startMessageId, int endMessageId) { 7326f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7336f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Context context = mPhone.getContext(); 7346f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7356f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa context.enforceCallingPermission( 7366f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa "android.permission.RECEIVE_SMS", 7376f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa "Disabling cell broadcast SMS"); 7386f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7396f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa String client = context.getPackageManager().getNameForUid( 7406f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Binder.getCallingUid()); 7416f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7426f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (!mCdmaBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) { 7436f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Failed to remove cdma broadcast subscription for MID range " + startMessageId 7446f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa + " to " + endMessageId + " from client " + client); 7456f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return false; 7466f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7476f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7486f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (DBG) 7496f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Removed cdma broadcast subscription for MID range " + startMessageId 7506f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa + " to " + endMessageId + " from client " + client); 7516f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7526f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa setCdmaBroadcastActivation(!mCdmaBroadcastRangeManager.isEmpty()); 7536f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7546f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return true; 7556f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7566f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7576f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa class CellBroadcastRangeManager extends IntRangeManager { 7586f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private ArrayList<SmsBroadcastConfigInfo> mConfigList = 7596f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa new ArrayList<SmsBroadcastConfigInfo>(); 7606f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7616f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa /** 7626f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * Called when the list of enabled ranges has changed. This will be 7636f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * followed by zero or more calls to {@link #addRange} followed by 7646f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * a call to {@link #finishUpdate}. 7656f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa */ 7666f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa protected void startUpdate() { 7676f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mConfigList.clear(); 7686f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7696f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa /** 7716f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * Called after {@link #startUpdate} to indicate a range of enabled 7726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * values. 7736f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * @param startId the first id included in the range 7746f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * @param endId the last id included in the range 7756f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa */ 7766f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa protected void addRange(int startId, int endId, boolean selected) { 7776f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mConfigList.add(new SmsBroadcastConfigInfo(startId, endId, 7786f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected)); 7796f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7806f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7816f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa /** 7826f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * Called to indicate the end of a range update started by the 7836f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * previous call to {@link #startUpdate}. 7846f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * @return true if successful, false otherwise 7856f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa */ 7866f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa protected boolean finishUpdate() { 7876f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (mConfigList.isEmpty()) { 7886f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return true; 7896f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } else { 7906f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa SmsBroadcastConfigInfo[] configs = 7916f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]); 7926f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return setCellBroadcastConfig(configs); 7936f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7946f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7956f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 7966f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 7976f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa class CdmaBroadcastRangeManager extends IntRangeManager { 7986f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private ArrayList<CdmaSmsBroadcastConfigInfo> mConfigList = 7996f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa new ArrayList<CdmaSmsBroadcastConfigInfo>(); 8006f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8016f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa /** 8026f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * Called when the list of enabled ranges has changed. This will be 8036f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * followed by zero or more calls to {@link #addRange} followed by a 8046f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * call to {@link #finishUpdate}. 8056f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa */ 8066f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa protected void startUpdate() { 8076f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mConfigList.clear(); 8086f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 809ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 8106f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa /** 8116f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * Called after {@link #startUpdate} to indicate a range of enabled 8126f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * values. 8136f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * @param startId the first id included in the range 8146f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * @param endId the last id included in the range 8156f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa */ 8166f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa protected void addRange(int startId, int endId, boolean selected) { 8176f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mConfigList.add(new CdmaSmsBroadcastConfigInfo(startId, endId, 8186f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 1, selected)); 8196f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 820ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks 8216f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa /** 8226f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * Called to indicate the end of a range update started by the previous 8236f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * call to {@link #startUpdate}. 8246f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa * @return true if successful, false otherwise 8256f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa */ 8266f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa protected boolean finishUpdate() { 8276f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (mConfigList.isEmpty()) { 8286f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return true; 8296f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } else { 8306f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa CdmaSmsBroadcastConfigInfo[] configs = 8316f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mConfigList.toArray(new CdmaSmsBroadcastConfigInfo[mConfigList.size()]); 8326f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return setCdmaBroadcastConfig(configs); 8336f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8346f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8356f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8366f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8376f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) { 8386f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (DBG) 8396f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Calling setGsmBroadcastConfig with " + configs.length + " configurations"); 8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8416f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa synchronized (mLock) { 8426f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE); 8436f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8446f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mSuccess = false; 8456f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone.mCi.setGsmBroadcastConfig(configs, response); 8466f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8476f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa try { 8486f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mLock.wait(); 8496f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } catch (InterruptedException e) { 8506f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("interrupted while trying to set cell broadcast config"); 8516f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8526f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8536f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8546f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return mSuccess; 8556f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8566f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8576f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private boolean setCellBroadcastActivation(boolean activate) { 8586f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (DBG) 8596f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Calling setCellBroadcastActivation(" + activate + ')'); 8606f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8616f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa synchronized (mLock) { 8626f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE); 8636f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8646f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mSuccess = false; 8656f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone.mCi.setGsmBroadcastActivation(activate, response); 8666f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8676f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa try { 8686f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mLock.wait(); 8696f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } catch (InterruptedException e) { 8706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("interrupted while trying to set cell broadcast activation"); 8716f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8736f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8746f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return mSuccess; 8756f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8766f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8776f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private boolean setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs) { 8786f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (DBG) 8796f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Calling setCdmaBroadcastConfig with " + configs.length + " configurations"); 8806f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8816f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa synchronized (mLock) { 8826f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE); 8836f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8846f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mSuccess = false; 8856f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone.mCi.setCdmaBroadcastConfig(configs, response); 8866f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8876f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa try { 8886f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mLock.wait(); 8896f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } catch (InterruptedException e) { 8906f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("interrupted while trying to set cdma broadcast config"); 8916f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8926f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8936f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8946f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return mSuccess; 8956f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 8966f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 8976f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa private boolean setCdmaBroadcastActivation(boolean activate) { 8986f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa if (DBG) 8996f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("Calling setCdmaBroadcastActivation(" + activate + ")"); 9006f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 9016f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa synchronized (mLock) { 9026f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE); 9036f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 9046f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mSuccess = false; 9056f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mPhone.mCi.setCdmaBroadcastActivation(activate, response); 9066f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 9076f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa try { 9086f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa mLock.wait(); 9096f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } catch (InterruptedException e) { 9106f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa log("interrupted while trying to set cdma broadcast activation"); 9116f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 9126f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 9136f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 9146f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa return mSuccess; 9156f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 9166f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa 9176f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa protected void log(String msg) { 9186f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa Log.d(LOG_TAG, "[IccSmsInterfaceManager] " + msg); 9196f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa } 9201260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 9211260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa public boolean isImsSmsSupported() { 9221260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa return mDispatcher.isIms(); 9231260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 9241260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 9251260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa public String getImsSmsFormat() { 9261260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa return mDispatcher.getImsSmsFormat(); 9271260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 928b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen 929b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen public void sendStoredText(String callingPkg, Uri messageUri, String scAddress, 930b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen PendingIntent sentIntent, PendingIntent deliveryIntent) { 931b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen mPhone.getContext().enforceCallingPermission(Manifest.permission.SEND_SMS, 932b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen "Sending SMS message"); 933b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (Rlog.isLoggable("SMS", Log.VERBOSE)) { 934b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen log("sendStoredText: scAddr=" + scAddress + " messageUri=" + messageUri 935b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen + " sentIntent=" + sentIntent + " deliveryIntent=" + deliveryIntent); 936b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 937b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), callingPkg) 938b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen != AppOpsManager.MODE_ALLOWED) { 939b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return; 940b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 941b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen final ContentResolver resolver = mPhone.getContext().getContentResolver(); 942b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (!isFailedOrDraft(resolver, messageUri)) { 943b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredText: not FAILED or DRAFT message"); 944b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen returnUnspecifiedFailure(sentIntent); 945b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return; 946b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 947b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen final String[] textAndAddress = loadTextAndAddress(resolver, messageUri); 948b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (textAndAddress == null) { 949b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredText: can not load text"); 950b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen returnUnspecifiedFailure(sentIntent); 951b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return; 952b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 95370dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying textAndAddress[1] = filterDestAddress(textAndAddress[1]); 954b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen mDispatcher.sendText(textAndAddress[1], scAddress, textAndAddress[0], 955a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang sentIntent, deliveryIntent, messageUri, callingPkg, 956a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang true /* persistMessageForNonDefaultSmsApp */); 957b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 958b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen 959b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen public void sendStoredMultipartText(String callingPkg, Uri messageUri, String scAddress, 960b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { 961b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen mPhone.getContext().enforceCallingPermission(Manifest.permission.SEND_SMS, 962b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen "Sending SMS message"); 963b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), callingPkg) 964b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen != AppOpsManager.MODE_ALLOWED) { 965b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return; 966b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 967b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen final ContentResolver resolver = mPhone.getContext().getContentResolver(); 968b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (!isFailedOrDraft(resolver, messageUri)) { 969b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: " 970b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen + "not FAILED or DRAFT message"); 971b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen returnUnspecifiedFailure(sentIntents); 972b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return; 973b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 974b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen final String[] textAndAddress = loadTextAndAddress(resolver, messageUri); 975b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (textAndAddress == null) { 976b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: can not load text"); 977b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen returnUnspecifiedFailure(sentIntents); 978b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return; 979b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 980b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen final ArrayList<String> parts = SmsManager.getDefault().divideMessage(textAndAddress[0]); 981b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (parts == null || parts.size() < 1) { 982b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: can not divide text"); 983b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen returnUnspecifiedFailure(sentIntents); 984b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return; 985b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 986f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 987bd681a048599441c659f3d3a8300e47599783d54Xia Ying textAndAddress[1] = filterDestAddress(textAndAddress[1]); 988bd681a048599441c659f3d3a8300e47599783d54Xia Ying 989f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying if (parts.size() > 1 && parts.size() < 10 && !SmsMessage.hasEmsSupport()) { 990f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying for (int i = 0; i < parts.size(); i++) { 991f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying // If EMS is not supported, we have to break down EMS into single segment SMS 992f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying // and add page info " x/y". 993f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying String singlePart = parts.get(i); 994f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying if (SmsMessage.shouldAppendPageNumberAsPrefix()) { 995f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singlePart = String.valueOf(i + 1) + '/' + parts.size() + ' ' + singlePart; 996f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } else { 997f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singlePart = singlePart.concat(' ' + String.valueOf(i + 1) + '/' + parts.size()); 998f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 999f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 1000f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying PendingIntent singleSentIntent = null; 1001f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying if (sentIntents != null && sentIntents.size() > i) { 1002f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singleSentIntent = sentIntents.get(i); 1003f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 1004f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 1005f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying PendingIntent singleDeliveryIntent = null; 1006f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying if (deliveryIntents != null && deliveryIntents.size() > i) { 1007f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying singleDeliveryIntent = deliveryIntents.get(i); 1008f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 1009f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 1010f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying mDispatcher.sendText(textAndAddress[1], scAddress, singlePart, 1011a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang singleSentIntent, singleDeliveryIntent, messageUri, callingPkg, 1012a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang true /* persistMessageForNonDefaultSmsApp */); 1013f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 1014f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying return; 1015f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying } 1016f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying 1017b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen mDispatcher.sendMultipartText( 1018b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen textAndAddress[1], // destAddress 1019b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen scAddress, 1020b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen parts, 1021b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen (ArrayList<PendingIntent>) sentIntents, 1022b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen (ArrayList<PendingIntent>) deliveryIntents, 1023b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen messageUri, 1024a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang callingPkg, 1025a8f8c5a113a66de4854f4fb13a5825eb0705bd59Ji Yang true /* persistMessageForNonDefaultSmsApp */); 1026b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1027b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen 1028b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen private boolean isFailedOrDraft(ContentResolver resolver, Uri messageUri) { 102949754105adf232419410cfca7507aa63a9d05e3bYe Wen // Clear the calling identity and query the database using the phone user id 103049754105adf232419410cfca7507aa63a9d05e3bYe Wen // Otherwise the AppOps check in TelephonyProvider would complain about mismatch 103149754105adf232419410cfca7507aa63a9d05e3bYe Wen // between the calling uid and the package uid 103249754105adf232419410cfca7507aa63a9d05e3bYe Wen final long identity = Binder.clearCallingIdentity(); 1033b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Cursor cursor = null; 1034b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen try { 1035b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen cursor = resolver.query( 1036b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen messageUri, 1037b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen new String[]{ Telephony.Sms.TYPE }, 1038b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen null/*selection*/, 1039b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen null/*selectionArgs*/, 1040b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen null/*sortOrder*/); 1041b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (cursor != null && cursor.moveToFirst()) { 1042b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen final int type = cursor.getInt(0); 1043b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return type == Telephony.Sms.MESSAGE_TYPE_DRAFT 1044b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen || type == Telephony.Sms.MESSAGE_TYPE_FAILED; 1045b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1046b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } catch (SQLiteException e) { 1047b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Log.e(LOG_TAG, "[IccSmsInterfaceManager]isFailedOrDraft: query message type failed", e); 1048b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } finally { 1049b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (cursor != null) { 1050b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen cursor.close(); 1051b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 105249754105adf232419410cfca7507aa63a9d05e3bYe Wen Binder.restoreCallingIdentity(identity); 1053b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1054b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return false; 1055b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1056b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen 1057b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen // Return an array including both the SMS text (0) and address (1) 1058b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen private String[] loadTextAndAddress(ContentResolver resolver, Uri messageUri) { 105949754105adf232419410cfca7507aa63a9d05e3bYe Wen // Clear the calling identity and query the database using the phone user id 106049754105adf232419410cfca7507aa63a9d05e3bYe Wen // Otherwise the AppOps check in TelephonyProvider would complain about mismatch 106149754105adf232419410cfca7507aa63a9d05e3bYe Wen // between the calling uid and the package uid 106249754105adf232419410cfca7507aa63a9d05e3bYe Wen final long identity = Binder.clearCallingIdentity(); 1063b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Cursor cursor = null; 1064b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen try { 1065b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen cursor = resolver.query( 1066b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen messageUri, 1067b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen new String[]{ 1068b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Telephony.Sms.BODY, 1069b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Telephony.Sms.ADDRESS 1070b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen }, 1071b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen null/*selection*/, 1072b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen null/*selectionArgs*/, 1073b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen null/*sortOrder*/); 1074b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (cursor != null && cursor.moveToFirst()) { 1075b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return new String[]{ cursor.getString(0), cursor.getString(1) }; 1076b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1077b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } catch (SQLiteException e) { 1078b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen Log.e(LOG_TAG, "[IccSmsInterfaceManager]loadText: query message text failed", e); 1079b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } finally { 1080b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (cursor != null) { 1081b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen cursor.close(); 1082b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 108349754105adf232419410cfca7507aa63a9d05e3bYe Wen Binder.restoreCallingIdentity(identity); 1084b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1085b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return null; 1086b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1087b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen 1088b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen private void returnUnspecifiedFailure(PendingIntent pi) { 1089b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (pi != null) { 1090b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen try { 1091b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen pi.send(SmsManager.RESULT_ERROR_GENERIC_FAILURE); 1092b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } catch (PendingIntent.CanceledException e) { 1093b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen // ignore 1094b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1095b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1096b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1097b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen 1098b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen private void returnUnspecifiedFailure(List<PendingIntent> pis) { 1099b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen if (pis == null) { 1100b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen return; 1101b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1102b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen for (PendingIntent pi : pis) { 1103b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen returnUnspecifiedFailure(pi); 1104b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1105b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen } 1106c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal 1107c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal private void enforceCarrierPrivilege() { 110868515b655255005f653aec29e9f152412514982aShishir Agrawal UiccController controller = UiccController.getInstance(); 1109062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal if (controller == null || controller.getUiccCard(mPhone.getPhoneId()) == null) { 111068515b655255005f653aec29e9f152412514982aShishir Agrawal throw new SecurityException("No Carrier Privilege: No UICC"); 111168515b655255005f653aec29e9f152412514982aShishir Agrawal } 1112062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal if (controller.getUiccCard(mPhone.getPhoneId()).getCarrierPrivilegeStatusForCurrentTransaction( 1113c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal mContext.getPackageManager()) != 1114c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1115c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal throw new SecurityException("No Carrier Privilege."); 1116c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 1117c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal } 111870dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying 1119532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry /** 1120a700124bf726680fe96675ab7f558e524fc024c9Abhijith Shastry * Enforces that the caller has {@link android.Manifest.permission#MODIFY_PHONE_STATE} 1121a700124bf726680fe96675ab7f558e524fc024c9Abhijith Shastry * permission or is one of the following apps: 1122532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry * <ul> 1123532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry * <li> IMS App 1124532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry * <li> Carrier App 1125532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry * </ul> 1126532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry */ 1127532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry private void enforcePrivilegedAppPermissions() { 1128a700124bf726680fe96675ab7f558e524fc024c9Abhijith Shastry if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 1129a700124bf726680fe96675ab7f558e524fc024c9Abhijith Shastry == PackageManager.PERMISSION_GRANTED) { 1130532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry return; 1131532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry } 1132532c5ffb1d1ba6a3d642a21c107fd578ae64ef1cAbhijith Shastry 1133a700124bf726680fe96675ab7f558e524fc024c9Abhijith Shastry int callingUid = Binder.getCallingUid(); 11344256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala String carrierImsPackage = CarrierSmsUtils.getCarrierImsPackageForIntent(mContext, mPhone, 11354256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala new Intent(CarrierMessagingService.SERVICE_INTERFACE)); 11364256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala try { 11374256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala if (carrierImsPackage != null 11384256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala && callingUid == mContext.getPackageManager().getPackageUid( 11394256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala carrierImsPackage, 0)) { 11404256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala return; 11414256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala } 11424256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala } catch (PackageManager.NameNotFoundException e) { 11434256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala if (Rlog.isLoggable("SMS", Log.DEBUG)) { 11444256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala log("Cannot find configured carrier ims package"); 11454256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala } 11464256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala } 1147a700124bf726680fe96675ab7f558e524fc024c9Abhijith Shastry 11484256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala enforceCarrierPrivilege(); 11494256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala } 11504256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala 115170dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying private String filterDestAddress(String destAddr) { 115270dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying String result = null; 11533c36d8029ea2c92e0339cd0cbe26511e5478da09Xia Ying result = SmsNumberUtils.filterDestAddr(mPhone, destAddr); 115470dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying return result != null ? result : destAddr; 115570dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying } 115670dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying 11570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 1158