10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** Copyright 2007, 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.gsm; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.pm.PackageManager; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Binder; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log; 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccConstants; 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccSmsInterfaceManager; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccUtils; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IntRangeManager; 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SMSDispatcher; 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsRawData; 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList; 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays; 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.HashMap; 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.HashSet; 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List; 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Set; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport static android.telephony.SmsManager.STATUS_ON_ICC_FREE; 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * SimSmsInterfaceManager to provide an inter-process communication to 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * access Sms in Sim. 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class SimSmsInterfaceManager extends IccSmsInterfaceManager { 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final String LOG_TAG = "GSM"; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final boolean DBG = true; 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final Object mLock = new Object(); 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean mSuccess; 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private List<SmsRawData> mSms; 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private HashMap<Integer, HashSet<String>> mCellBroadcastSubscriptions = 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville new HashMap<Integer, HashSet<String>>(); 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private CellBroadcastRangeManager mCellBroadcastRangeManager = 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville new CellBroadcastRangeManager(); 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_LOAD_DONE = 1; 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_UPDATE_DONE = 2; 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_SET_BROADCAST_ACTIVATION_DONE = 3; 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_SET_BROADCAST_CONFIG_DONE = 4; 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int SMS_CB_CODE_SCHEME_MIN = 0; 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int SMS_CB_CODE_SCHEME_MAX = 255; 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Handler mHandler = new Handler() { 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void handleMessage(Message msg) { 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville AsyncResult ar; 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (msg.what) { 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_UPDATE_DONE: 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult) msg.obj; 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized (mLock) { 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = (ar.exception == null); 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.notifyAll(); 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_LOAD_DONE: 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult)msg.obj; 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized (mLock) { 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ar.exception == null) { 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSms = buildValidRawData((ArrayList<byte[]>) ar.result); 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if(DBG) log("Cannot load Sms records"); 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mSms != null) 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSms.clear(); 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.notifyAll(); 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_SET_BROADCAST_ACTIVATION_DONE: 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_SET_BROADCAST_CONFIG_DONE: 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult) msg.obj; 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized (mLock) { 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = (ar.exception == null); 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.notifyAll(); 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville }; 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) { 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville super(phone); 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mDispatcher = dispatcher; 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void dispose() { 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void finalize() { 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville super.finalize(); 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (Throwable throwable) { 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "Error while finalizing:", throwable); 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if(DBG) Log.d(LOG_TAG, "SimSmsInterfaceManager finalized"); 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Update the specified message on the SIM. 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param index record index of message to update 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param status new message status (STATUS_ON_ICC_READ, 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT, 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE) 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param pdu the raw PDU to store 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return success or not 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville updateMessageOnIccEf(int index, int status, byte[] pdu) { 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("updateMessageOnIccEf: index=" + index + 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville " status=" + status + " ==> " + 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "("+ Arrays.toString(pdu) + ")"); 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville enforceReceiveAndSend("Updating message on SIM"); 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized(mLock) { 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = false; 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (status == STATUS_ON_ICC_FREE) { 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Special case FREE: call deleteSmsOnSim instead of 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // manipulating the SIM record 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.mCM.deleteSmsOnSim(index, response); 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] record = makeSmsRecordData(status, pdu); 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.getIccFileHandler().updateEFLinearFixed( 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IccConstants.EF_SMS, 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville index, record, null, response); 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.wait(); 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (InterruptedException e) { 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("interrupted while trying to update by index"); 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSuccess; 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copy a raw SMS PDU to the SIM. 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param pdu the raw PDU to store 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD, 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT) 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return success or not 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) { 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " + 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "pdu=("+ Arrays.toString(pdu) + 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "), smsm=(" + Arrays.toString(smsc) +")"); 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville enforceReceiveAndSend("Copying message to SIM"); 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized(mLock) { 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = false; 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.mCM.writeSmsToSim(status, IccUtils.bytesToHexString(smsc), 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IccUtils.bytesToHexString(pdu), response); 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.wait(); 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (InterruptedException e) { 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("interrupted while trying to update by index"); 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSuccess; 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Retrieves all messages currently stored on ICC. 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return list of SmsRawData of all sms on ICC 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public List<SmsRawData> getAllMessagesFromIccEf() { 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("getAllMessagesFromEF"); 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Context context = mPhone.getContext(); 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville context.enforceCallingPermission( 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "android.permission.RECEIVE_SMS", 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "Reading messages from SIM"); 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized(mLock) { 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message response = mHandler.obtainMessage(EVENT_LOAD_DONE); 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response); 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.wait(); 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (InterruptedException e) { 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("interrupted while trying to load from the SIM"); 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSms; 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean enableCellBroadcast(int messageIdentifier) { 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return enableCellBroadcastRange(messageIdentifier, messageIdentifier); 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean disableCellBroadcast(int messageIdentifier) { 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return disableCellBroadcastRange(messageIdentifier, messageIdentifier); 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) { 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("enableCellBroadcastRange"); 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Context context = mPhone.getContext(); 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville context.enforceCallingPermission( 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "android.permission.RECEIVE_SMS", 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "Enabling cell broadcast SMS"); 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String client = context.getPackageManager().getNameForUid( 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Binder.getCallingUid()); 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) { 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("Failed to add cell broadcast subscription for MID range " + startMessageId 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + " to " + endMessageId + " from client " + client); 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("Added cell broadcast subscription for MID range " + startMessageId 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + " to " + endMessageId + " from client " + client); 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty()); 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) { 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("disableCellBroadcastRange"); 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Context context = mPhone.getContext(); 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville context.enforceCallingPermission( 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "android.permission.RECEIVE_SMS", 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "Disabling cell broadcast SMS"); 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String client = context.getPackageManager().getNameForUid( 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Binder.getCallingUid()); 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) { 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("Failed to remove cell broadcast subscription for MID range " + startMessageId 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + " to " + endMessageId + " from client " + client); 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("Removed cell broadcast subscription for MID range " + startMessageId 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + " to " + endMessageId + " from client " + client); 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty()); 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville class CellBroadcastRangeManager extends IntRangeManager { 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private ArrayList<SmsBroadcastConfigInfo> mConfigList = 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville new ArrayList<SmsBroadcastConfigInfo>(); 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Called when the list of enabled ranges has changed. This will be 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * followed by zero or more calls to {@link #addRange} followed by 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * a call to {@link #finishUpdate}. 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void startUpdate() { 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mConfigList.clear(); 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Called after {@link #startUpdate} to indicate a range of enabled 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * values. 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param startId the first id included in the range 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param endId the last id included in the range 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void addRange(int startId, int endId, boolean selected) { 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mConfigList.add(new SmsBroadcastConfigInfo(startId, endId, 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected)); 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Called to indicate the end of a range update started by the 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * previous call to {@link #startUpdate}. 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if successful, false otherwise 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected boolean finishUpdate() { 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mConfigList.isEmpty()) { 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsBroadcastConfigInfo[] configs = 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]); 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return setCellBroadcastConfig(configs); 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) { 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("Calling setGsmBroadcastConfig with " + configs.length + " configurations"); 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized (mLock) { 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE); 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = false; 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.mCM.setGsmBroadcastConfig(configs, response); 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.wait(); 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (InterruptedException e) { 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("interrupted while trying to set cell broadcast config"); 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSuccess; 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean setCellBroadcastActivation(boolean activate) { 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("Calling setCellBroadcastActivation(" + activate + ')'); 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized (mLock) { 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE); 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = false; 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.mCM.setGsmBroadcastActivation(activate, response); 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.wait(); 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (InterruptedException e) { 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("interrupted while trying to set cell broadcast activation"); 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSuccess; 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void log(String msg) { 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg); 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 366