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