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