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
197fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.Manifest;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Binder;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
23ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccSmsInterfaceManager;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IntRangeManager;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SMSDispatcher;
28d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * SimSmsInterfaceManager to provide an inter-process communication to
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * access Sms in Sim.
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class SimSmsInterfaceManager extends IccSmsInterfaceManager {
37cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "SimSmsIM";
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final boolean DBG = true;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CellBroadcastRangeManager mCellBroadcastRangeManager =
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            new CellBroadcastRangeManager();
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int SMS_CB_CODE_SCHEME_MIN = 0;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int SMS_CB_CODE_SCHEME_MAX = 255;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) {
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super(phone);
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDispatcher = dispatcher;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void dispose() {
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void finalize() {
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            super.finalize();
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (Throwable throwable) {
59ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.e(LOG_TAG, "Error while finalizing:", throwable);
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
61ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        if(DBG) Rlog.d(LOG_TAG, "SimSmsInterfaceManager finalized");
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
64cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
65ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected void deleteSms(int index, Message response) {
6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.deleteSmsOnSim(index, response);
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
69cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
70ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected void writeSms(int status, byte[] pdu, byte[] smsc, Message response) {
7122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.mCi.writeSmsToSim(status, IccUtils.bytesToHexString(smsc),
72ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                IccUtils.bytesToHexString(pdu), response);
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
75cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean enableCellBroadcast(int messageIdentifier) {
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return enableCellBroadcastRange(messageIdentifier, messageIdentifier);
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
80cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean disableCellBroadcast(int messageIdentifier) {
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return disableCellBroadcastRange(messageIdentifier, messageIdentifier);
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
85cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("enableCellBroadcastRange");
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Context context = mPhone.getContext();
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        context.enforceCallingPermission(
927fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.RECEIVE_SMS,
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "Enabling cell broadcast SMS");
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String client = context.getPackageManager().getNameForUid(
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Binder.getCallingUid());
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) {
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Failed to add cell broadcast subscription for MID range " + startMessageId
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + " to " + endMessageId + " from client " + client);
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG)
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Added cell broadcast subscription for MID range " + startMessageId
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + " to " + endMessageId + " from client " + client);
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
113cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG) log("disableCellBroadcastRange");
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Context context = mPhone.getContext();
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        context.enforceCallingPermission(
1207fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.RECEIVE_SMS,
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "Disabling cell broadcast SMS");
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String client = context.getPackageManager().getNameForUid(
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Binder.getCallingUid());
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) {
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Failed to remove cell broadcast subscription for MID range " + startMessageId
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + " to " + endMessageId + " from client " + client);
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG)
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Removed cell broadcast subscription for MID range " + startMessageId
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    + " to " + endMessageId + " from client " + client);
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    class CellBroadcastRangeManager extends IntRangeManager {
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        private ArrayList<SmsBroadcastConfigInfo> mConfigList =
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                new ArrayList<SmsBroadcastConfigInfo>();
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        /**
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * Called when the list of enabled ranges has changed. This will be
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * followed by zero or more calls to {@link #addRange} followed by
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * a call to {@link #finishUpdate}.
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         */
150cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        protected void startUpdate() {
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mConfigList.clear();
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        /**
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * Called after {@link #startUpdate} to indicate a range of enabled
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * values.
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * @param startId the first id included in the range
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * @param endId the last id included in the range
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         */
161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        protected void addRange(int startId, int endId, boolean selected) {
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mConfigList.add(new SmsBroadcastConfigInfo(startId, endId,
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected));
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        /**
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * Called to indicate the end of a range update started by the
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * previous call to {@link #startUpdate}.
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * @return true if successful, false otherwise
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         */
172cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        protected boolean finishUpdate() {
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mConfigList.isEmpty()) {
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsBroadcastConfigInfo[] configs =
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]);
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return setCellBroadcastConfig(configs);
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) {
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG)
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Calling setGsmBroadcastConfig with " + configs.length + " configurations");
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (mLock) {
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE);
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mSuccess = false;
19222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCi.setGsmBroadcastConfig(configs, response);
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mLock.wait();
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (InterruptedException e) {
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("interrupted while trying to set cell broadcast config");
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mSuccess;
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean setCellBroadcastActivation(boolean activate) {
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (DBG)
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("Calling setCellBroadcastActivation(" + activate + ')');
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (mLock) {
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE);
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mSuccess = false;
21222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.mCi.setGsmBroadcastActivation(activate, response);
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mLock.wait();
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (InterruptedException e) {
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("interrupted while trying to set cell broadcast activation");
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return mSuccess;
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @Override
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void log(String msg) {
226ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        Rlog.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg);
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
229