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 Saville 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cdma; 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccConstants; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccSmsInterfaceManager; 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccUtils; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.PhoneProxy; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SMSDispatcher; 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsRawData; 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList; 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays; 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List; 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport static android.telephony.SmsManager.STATUS_ON_ICC_FREE; 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * RuimSmsInterfaceManager to provide an inter-process communication to 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * access Sms in Ruim. 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class RuimSmsInterfaceManager extends IccSmsInterfaceManager { 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final String LOG_TAG = "CDMA"; 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final boolean DBG = true; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final Object mLock = new Object(); 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean mSuccess; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private List<SmsRawData> mSms; 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_LOAD_DONE = 1; 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int EVENT_UPDATE_DONE = 2; 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Handler mHandler = new Handler() { 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void handleMessage(Message msg) { 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville AsyncResult ar; 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (msg.what) { 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_UPDATE_DONE: 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult) msg.obj; 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized (mLock) { 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = (ar.exception == null); 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.notifyAll(); 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case EVENT_LOAD_DONE: 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ar = (AsyncResult)msg.obj; 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized (mLock) { 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ar.exception == null) { 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSms = buildValidRawData((ArrayList<byte[]>) ar.result); 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if(DBG) log("Cannot load Sms records"); 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mSms != null) 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSms.clear(); 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.notifyAll(); 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville }; 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public RuimSmsInterfaceManager(CDMAPhone phone, SMSDispatcher dispatcher) { 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville super(phone); 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mDispatcher = dispatcher; 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void dispose() { 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void finalize() { 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville super.finalize(); 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (Throwable throwable) { 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "Error while finalizing:", throwable); 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if(DBG) Log.d(LOG_TAG, "RuimSmsInterfaceManager finalized"); 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Update the specified message on the RUIM. 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param index record index of message to update 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param status new message status (STATUS_ON_ICC_READ, 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT, 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE) 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param pdu the raw PDU to store 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return success or not 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville updateMessageOnIccEf(int index, int status, byte[] pdu) { 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("updateMessageOnIccEf: index=" + index + 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville " status=" + status + " ==> " + 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "("+ pdu + ")"); 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville enforceReceiveAndSend("Updating message on RUIM"); 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized(mLock) { 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = false; 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (status == STATUS_ON_ICC_FREE) { 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Special case FREE: call deleteSmsOnRuim instead of 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // manipulating the RUIM record 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.mCM.deleteSmsOnRuim(index, response); 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] record = makeSmsRecordData(status, pdu); 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.getIccFileHandler().updateEFLinearFixed( 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IccConstants.EF_SMS, index, record, null, response); 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.wait(); 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (InterruptedException e) { 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("interrupted while trying to update by index"); 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSuccess; 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copy a raw SMS PDU to the RUIM. 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param pdu the raw PDU to store 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD, 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT) 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return success or not 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) { 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //NOTE smsc not used in RUIM 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " + 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "pdu=("+ Arrays.toString(pdu) + ")"); 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville enforceReceiveAndSend("Copying message to RUIM"); 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized(mLock) { 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSuccess = false; 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.mCM.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu), 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville response); 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.wait(); 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (InterruptedException e) { 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("interrupted while trying to update by index"); 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSuccess; 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Retrieves all messages currently stored on RUIM. 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public List<SmsRawData> getAllMessagesFromIccEf() { 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("getAllMessagesFromEF"); 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Context context = mPhone.getContext(); 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville context.enforceCallingPermission( 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "android.permission.RECEIVE_SMS", 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "Reading messages from RUIM"); 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized(mLock) { 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message response = mHandler.obtainMessage(EVENT_LOAD_DONE); 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response); 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLock.wait(); 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (InterruptedException e) { 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville log("interrupted while trying to load from the RUIM"); 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSms; 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean enableCellBroadcast(int messageIdentifier) { 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Not implemented 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "Error! Not implemented for CDMA."); 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean disableCellBroadcast(int messageIdentifier) { 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Not implemented 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "Error! Not implemented for CDMA."); 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) { 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Not implemented 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "Error! Not implemented for CDMA."); 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) { 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Not implemented 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "Error! Not implemented for CDMA."); 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void log(String msg) { 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.d(LOG_TAG, "[RuimSmsInterfaceManager] " + msg); 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 223