19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2007, The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.telephony.gsm; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 2095bc625e294e14a651321b5172f31406cdebbefbHenrik Hallimport android.content.pm.PackageManager; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.AsyncResult; 2295bc625e294e14a651321b5172f31406cdebbefbHenrik Hallimport android.os.Binder; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport com.android.internal.telephony.IccConstants; 2804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport com.android.internal.telephony.IccSmsInterfaceManager; 2904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport com.android.internal.telephony.IccUtils; 30ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hambyimport com.android.internal.telephony.IntRangeManager; 31bb3716332321e22537a5015be13e2229fb9b90bcJake Hambyimport com.android.internal.telephony.SMSDispatcher; 3204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport com.android.internal.telephony.SmsRawData; 3304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 35a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guyimport java.util.Arrays; 3695bc625e294e14a651321b5172f31406cdebbefbHenrik Hallimport java.util.HashMap; 3795bc625e294e14a651321b5172f31406cdebbefbHenrik Hallimport java.util.HashSet; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 3995bc625e294e14a651321b5172f31406cdebbefbHenrik Hallimport java.util.Set; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savilleimport static android.telephony.SmsManager.STATUS_ON_ICC_FREE; 4204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SimSmsInterfaceManager to provide an inter-process communication to 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * access Sms in Sim. 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Savillepublic class SimSmsInterfaceManager extends IccSmsInterfaceManager { 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String LOG_TAG = "GSM"; 4904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville static final boolean DBG = true; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Object mLock = new Object(); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mSuccess; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<SmsRawData> mSms; 5495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall private HashMap<Integer, HashSet<String>> mCellBroadcastSubscriptions = 5595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall new HashMap<Integer, HashSet<String>>(); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 57ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby private CellBroadcastRangeManager mCellBroadcastRangeManager = 58ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby new CellBroadcastRangeManager(); 59ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EVENT_LOAD_DONE = 1; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EVENT_UPDATE_DONE = 2; 6295bc625e294e14a651321b5172f31406cdebbefbHenrik Hall private static final int EVENT_SET_BROADCAST_ACTIVATION_DONE = 3; 6395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall private static final int EVENT_SET_BROADCAST_CONFIG_DONE = 4; 6495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall private static final int SMS_CB_CODE_SCHEME_MIN = 0; 6595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall private static final int SMS_CB_CODE_SCHEME_MAX = 255; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler mHandler = new Handler() { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AsyncResult ar; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case EVENT_UPDATE_DONE: 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar = (AsyncResult) msg.obj; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSuccess = (ar.exception == null); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.notifyAll(); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case EVENT_LOAD_DONE: 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ar = (AsyncResult)msg.obj; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ar.exception == null) { 84a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy mSms = buildValidRawData((ArrayList<byte[]>) ar.result); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(DBG) log("Cannot load Sms records"); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSms != null) 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSms.clear(); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.notifyAll(); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall case EVENT_SET_BROADCAST_ACTIVATION_DONE: 9495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall case EVENT_SET_BROADCAST_CONFIG_DONE: 9595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall ar = (AsyncResult) msg.obj; 9695bc625e294e14a651321b5172f31406cdebbefbHenrik Hall synchronized (mLock) { 9795bc625e294e14a651321b5172f31406cdebbefbHenrik Hall mSuccess = (ar.exception == null); 9895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall mLock.notifyAll(); 9995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 10095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall break; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 105bb3716332321e22537a5015be13e2229fb9b90bcJake Hamby public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) { 10604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville super(phone); 107bb3716332321e22537a5015be13e2229fb9b90bcJake Hamby mDispatcher = dispatcher; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville public void dispose() { 11104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 113145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 11404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville protected void finalize() { 115a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy try { 116a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy super.finalize(); 117a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy } catch (Throwable throwable) { 118a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy Log.e(LOG_TAG, "Error while finalizing:", throwable); 119a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy } 12004e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville if(DBG) Log.d(LOG_TAG, "SimSmsInterfaceManager finalized"); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update the specified message on the SIM. 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param index record index of message to update 12704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * @param status new message status (STATUS_ON_ICC_READ, 12804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT, 12904e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE) 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pdu the raw PDU to store 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return success or not 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean 13504e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville updateMessageOnIccEf(int index, int status, byte[] pdu) { 13604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville if (DBG) log("updateMessageOnIccEf: index=" + index + 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " status=" + status + " ==> " + 138a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy "("+ Arrays.toString(pdu) + ")"); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceReceiveAndSend("Updating message on SIM"); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mLock) { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSuccess = false; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville if (status == STATUS_ON_ICC_FREE) { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Special case FREE: call deleteSmsOnSim instead of 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // manipulating the SIM record 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPhone.mCM.deleteSmsOnSim(index, response); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] record = makeSmsRecordData(status, pdu); 150a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy mPhone.getIccFileHandler().updateEFLinearFixed( 15104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville IccConstants.EF_SMS, 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index, record, null, response); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.wait(); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log("interrupted while trying to update by index"); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSuccess; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copy a raw SMS PDU to the SIM. 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pdu the raw PDU to store 16704e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD, 16804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT) 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return success or not 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) { 17304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " + 174a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy "pdu=("+ Arrays.toString(pdu) + 175a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy "), smsm=(" + Arrays.toString(smsc) +")"); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceReceiveAndSend("Copying message to SIM"); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mLock) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSuccess = false; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18104e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville mPhone.mCM.writeSmsToSim(status, IccUtils.bytesToHexString(smsc), 18204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville IccUtils.bytesToHexString(pdu), response); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.wait(); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log("interrupted while trying to update by index"); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSuccess; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19404e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * Retrieves all messages currently stored on ICC. 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19604e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville * @return list of SmsRawData of all sms on ICC 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19804e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville public List<SmsRawData> getAllMessagesFromIccEf() { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) log("getAllMessagesFromEF"); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Context context = mPhone.getContext(); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.enforceCallingPermission( 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.permission.RECEIVE_SMS", 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Reading messages from SIM"); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mLock) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message response = mHandler.obtainMessage(EVENT_LOAD_DONE); 208a1303e0193aeb32131572fb0dfe8e595a908b4e0Romain Guy mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLock.wait(); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project log("interrupted while trying to load from the SIM"); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSms; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall public boolean enableCellBroadcast(int messageIdentifier) { 220ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby return enableCellBroadcastRange(messageIdentifier, messageIdentifier); 221ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby } 222ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby 223ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby public boolean disableCellBroadcast(int messageIdentifier) { 224ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby return disableCellBroadcastRange(messageIdentifier, messageIdentifier); 225ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby } 226ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby 227ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) { 228ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby if (DBG) log("enableCellBroadcastRange"); 22995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 23095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall Context context = mPhone.getContext(); 23195bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 23295bc625e294e14a651321b5172f31406cdebbefbHenrik Hall context.enforceCallingPermission( 23395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall "android.permission.RECEIVE_SMS", 23495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall "Enabling cell broadcast SMS"); 23595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 23695bc625e294e14a651321b5172f31406cdebbefbHenrik Hall String client = context.getPackageManager().getNameForUid( 23795bc625e294e14a651321b5172f31406cdebbefbHenrik Hall Binder.getCallingUid()); 23895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 239ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) { 240ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby log("Failed to add cell broadcast subscription for MID range " + startMessageId 241ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby + " to " + endMessageId + " from client " + client); 242ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby return false; 24395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 24495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 24595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall if (DBG) 246ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby log("Added cell broadcast subscription for MID range " + startMessageId 247ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby + " to " + endMessageId + " from client " + client); 24895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 249f044a370d41687e0546a63b747b7c383f7f41e3eJake Hamby setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty()); 250f044a370d41687e0546a63b747b7c383f7f41e3eJake Hamby 25195bc625e294e14a651321b5172f31406cdebbefbHenrik Hall return true; 25295bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 25395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 254ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) { 255ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby if (DBG) log("disableCellBroadcastRange"); 25695bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 25795bc625e294e14a651321b5172f31406cdebbefbHenrik Hall Context context = mPhone.getContext(); 25895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 25995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall context.enforceCallingPermission( 26095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall "android.permission.RECEIVE_SMS", 26195bc625e294e14a651321b5172f31406cdebbefbHenrik Hall "Disabling cell broadcast SMS"); 26295bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 26395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall String client = context.getPackageManager().getNameForUid( 26495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall Binder.getCallingUid()); 26595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 266ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) { 267ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby log("Failed to remove cell broadcast subscription for MID range " + startMessageId 268ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby + " to " + endMessageId + " from client " + client); 269ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby return false; 27095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 27195bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 272ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby if (DBG) 273ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby log("Removed cell broadcast subscription for MID range " + startMessageId 274ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby + " to " + endMessageId + " from client " + client); 275ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby 276f044a370d41687e0546a63b747b7c383f7f41e3eJake Hamby setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty()); 277f044a370d41687e0546a63b747b7c383f7f41e3eJake Hamby 278ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby return true; 27995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 28095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 281ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby class CellBroadcastRangeManager extends IntRangeManager { 282ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby private ArrayList<SmsBroadcastConfigInfo> mConfigList = 283ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby new ArrayList<SmsBroadcastConfigInfo>(); 284ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby 285ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby /** 286ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * Called when the list of enabled ranges has changed. This will be 287ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * followed by zero or more calls to {@link #addRange} followed by 288ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * a call to {@link #finishUpdate}. 289ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby */ 290ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby protected void startUpdate() { 291ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby mConfigList.clear(); 292ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby } 29395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 294ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby /** 295ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * Called after {@link #startUpdate} to indicate a range of enabled 296ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * values. 297ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * @param startId the first id included in the range 298ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * @param endId the last id included in the range 299ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby */ 300ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby protected void addRange(int startId, int endId, boolean selected) { 301ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby mConfigList.add(new SmsBroadcastConfigInfo(startId, endId, 302ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected)); 303ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby } 30495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 305ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby /** 306ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * Called to indicate the end of a range update started by the 307ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby * previous call to {@link #startUpdate}. 308f044a370d41687e0546a63b747b7c383f7f41e3eJake Hamby * @return true if successful, false otherwise 309ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby */ 310ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby protected boolean finishUpdate() { 311ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby if (mConfigList.isEmpty()) { 312f044a370d41687e0546a63b747b7c383f7f41e3eJake Hamby return true; 313ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby } else { 314ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby SmsBroadcastConfigInfo[] configs = 315ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]); 316f044a370d41687e0546a63b747b7c383f7f41e3eJake Hamby return setCellBroadcastConfig(configs); 31795bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 31895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 31995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 32095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 32195bc625e294e14a651321b5172f31406cdebbefbHenrik Hall private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) { 32295bc625e294e14a651321b5172f31406cdebbefbHenrik Hall if (DBG) 32395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall log("Calling setGsmBroadcastConfig with " + configs.length + " configurations"); 32495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 32595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall synchronized (mLock) { 32695bc625e294e14a651321b5172f31406cdebbefbHenrik Hall Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE); 32795bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 32895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall mSuccess = false; 32995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall mPhone.mCM.setGsmBroadcastConfig(configs, response); 33095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 33195bc625e294e14a651321b5172f31406cdebbefbHenrik Hall try { 33295bc625e294e14a651321b5172f31406cdebbefbHenrik Hall mLock.wait(); 33395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } catch (InterruptedException e) { 33495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall log("interrupted while trying to set cell broadcast config"); 33595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 33695bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 33795bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 33895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall return mSuccess; 33995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 34095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 34195bc625e294e14a651321b5172f31406cdebbefbHenrik Hall private boolean setCellBroadcastActivation(boolean activate) { 34295bc625e294e14a651321b5172f31406cdebbefbHenrik Hall if (DBG) 343ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby log("Calling setCellBroadcastActivation(" + activate + ')'); 34495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 34595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall synchronized (mLock) { 34695bc625e294e14a651321b5172f31406cdebbefbHenrik Hall Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE); 34795bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 34895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall mSuccess = false; 34995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall mPhone.mCM.setGsmBroadcastActivation(activate, response); 35095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 35195bc625e294e14a651321b5172f31406cdebbefbHenrik Hall try { 35295bc625e294e14a651321b5172f31406cdebbefbHenrik Hall mLock.wait(); 35395bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } catch (InterruptedException e) { 35495bc625e294e14a651321b5172f31406cdebbefbHenrik Hall log("interrupted while trying to set cell broadcast activation"); 35595bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 35695bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 35795bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 35895bc625e294e14a651321b5172f31406cdebbefbHenrik Hall return mSuccess; 35995bc625e294e14a651321b5172f31406cdebbefbHenrik Hall } 36095bc625e294e14a651321b5172f31406cdebbefbHenrik Hall 361145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 36204e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville protected void log(String msg) { 36304e71b3db84fd5f7fc4eefb49a33154ea91ec9fcWink Saville Log.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 366