IccSmsInterfaceManager.java revision bd681a048599441c659f3d3a8300e47599783d54
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 Savillepackage com.android.internal.telephony;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
197fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.Manifest;
207fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.app.AppOpsManager;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.PendingIntent;
22b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.content.ContentResolver;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
24b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.database.Cursor;
25b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.database.sqlite.SQLiteException;
26b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.net.Uri;
27ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.AsyncResult;
287fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.os.Binder;
29ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.Handler;
30ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.Message;
31a2ce002a0327f0deb079cc6acad1c493e6ded442Amith Yamasaniimport android.os.UserManager;
32b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.provider.Telephony;
33ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
34b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wenimport android.telephony.SmsManager;
35f3166841bf9df142e2fbd63b7647bae7da712044Xia Yingimport android.telephony.SmsMessage;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
386f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowaimport com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
396f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowaimport com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
40d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccConstants;
41ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport com.android.internal.telephony.uicc.IccFileHandler;
42c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport com.android.internal.telephony.uicc.UiccController;
4370dad6e7c56847c91bc55755c645680ea6c6fac3Xia Yingimport com.android.internal.telephony.SmsNumberUtils;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.HexDump;
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
47ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport java.util.Arrays;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
51ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport static android.telephony.SmsManager.STATUS_ON_ICC_READ;
52ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport static android.telephony.SmsManager.STATUS_ON_ICC_UNREAD;
53a2ce002a0327f0deb079cc6acad1c493e6ded442Amith Yamasani
54c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawalimport android.telephony.TelephonyManager;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * IccSmsInterfaceManager to provide an inter-process communication to
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * access Sms in Icc.
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
60a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillepublic class IccSmsInterfaceManager {
61cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "IccSmsInterfaceManager";
62ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    static final boolean DBG = true;
63ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
64ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected final Object mLock = new Object();
65ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected boolean mSuccess;
66ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    private List<SmsRawData> mSms;
67ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
686f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    private CellBroadcastRangeManager mCellBroadcastRangeManager =
696f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            new CellBroadcastRangeManager();
706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    private CdmaBroadcastRangeManager mCdmaBroadcastRangeManager =
716f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            new CdmaBroadcastRangeManager();
726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
73ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    private static final int EVENT_LOAD_DONE = 1;
74ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    private static final int EVENT_UPDATE_DONE = 2;
75ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected static final int EVENT_SET_BROADCAST_ACTIVATION_DONE = 3;
76ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected static final int EVENT_SET_BROADCAST_CONFIG_DONE = 4;
776f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    private static final int SMS_CB_CODE_SCHEME_MIN = 0;
786f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    private static final int SMS_CB_CODE_SCHEME_MAX = 255;
79ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
806f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    protected PhoneBase mPhone;
817fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    final protected Context mContext;
827fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    final protected AppOpsManager mAppOps;
83a2ce002a0327f0deb079cc6acad1c493e6ded442Amith Yamasani    final private UserManager mUserManager;
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected SMSDispatcher mDispatcher;
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
86ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected Handler mHandler = new Handler() {
87ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        @Override
88ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        public void handleMessage(Message msg) {
89ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            AsyncResult ar;
90ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
91ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            switch (msg.what) {
92ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                case EVENT_UPDATE_DONE:
93ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    ar = (AsyncResult) msg.obj;
94ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    synchronized (mLock) {
95ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mSuccess = (ar.exception == null);
96ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mLock.notifyAll();
97ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    }
98ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    break;
99ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                case EVENT_LOAD_DONE:
100ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    ar = (AsyncResult)msg.obj;
101ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    synchronized (mLock) {
102ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        if (ar.exception == null) {
103ace9a749c5a2a5e07527f728b7331423d16c36cdSukanya Rajkhowa                            mSms = buildValidRawData((ArrayList<byte[]>) ar.result);
104ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                            //Mark SMS as read after importing it from card.
105ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                            markMessagesAsRead((ArrayList<byte[]>) ar.result);
106ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        } else {
1076f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                            if (Rlog.isLoggable("SMS", Log.DEBUG)) {
1086f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                                log("Cannot load Sms records");
1096f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                            }
110ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                            if (mSms != null)
111ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                                mSms.clear();
112ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        }
113ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mLock.notifyAll();
114ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    }
115ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    break;
116ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                case EVENT_SET_BROADCAST_ACTIVATION_DONE:
117ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                case EVENT_SET_BROADCAST_CONFIG_DONE:
118ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    ar = (AsyncResult) msg.obj;
119ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    synchronized (mLock) {
120ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mSuccess = (ar.exception == null);
121ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mLock.notifyAll();
122ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    }
123ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    break;
124ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
125ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
126ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    };
127ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
1286f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    protected IccSmsInterfaceManager(PhoneBase phone) {
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone = phone;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mContext = phone.getContext();
1316f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
132a2ce002a0327f0deb079cc6acad1c493e6ded442Amith Yamasani        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
1331260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        mDispatcher = new ImsSMSDispatcher(phone,
1341260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa                phone.mSmsStorageMonitor, phone.mSmsUsageMonitor);
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
137ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected void markMessagesAsRead(ArrayList<byte[]> messages) {
138ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (messages == null) {
139ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            return;
140ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
141ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
142ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        //IccFileHandler can be null, if icc card is absent.
143ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        IccFileHandler fh = mPhone.getIccFileHandler();
144ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (fh == null) {
145ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            //shouldn't really happen, as messages are marked as read, only
146ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            //after importing it from icc.
147ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            if (Rlog.isLoggable("SMS", Log.DEBUG)) {
148ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                log("markMessagesAsRead - aborting, no icc card present.");
149ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
150ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            return;
151ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
152ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
153ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        int count = messages.size();
154ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
155ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        for (int i = 0; i < count; i++) {
156ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks             byte[] ba = messages.get(i);
157ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks             if (ba[0] == STATUS_ON_ICC_UNREAD) {
158ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 int n = ba.length;
159ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 byte[] nba = new byte[n - 1];
160ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 System.arraycopy(ba, 1, nba, 0, n - 1);
161ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 byte[] record = makeSmsRecordData(STATUS_ON_ICC_READ, nba);
162ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 fh.updateEFLinearFixed(IccConstants.EF_SMS, i + 1, record, null, null);
163ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 if (Rlog.isLoggable("SMS", Log.DEBUG)) {
164ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                     log("SMS " + (i + 1) + " marked as read");
165ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 }
166ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks             }
167ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
168ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    }
169ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
1706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    protected void updatePhoneObject(PhoneBase phone) {
1716f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        mPhone = phone;
1721260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        mDispatcher.updatePhoneObject(phone);
1736f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
1746f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void enforceReceiveAndSend(String message) {
176c6cbdea1423262784e0a155f93be75f3f72e242cxinhe        mContext.enforceCallingOrSelfPermission(
1777fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.RECEIVE_SMS, message);
178c6cbdea1423262784e0a155f93be75f3f72e242cxinhe        mContext.enforceCallingOrSelfPermission(
1797fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.SEND_SMS, message);
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
183ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * Update the specified message on the Icc.
184ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
185ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param index record index of message to update
186ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param status new message status (STATUS_ON_ICC_READ,
187ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
188ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
189ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param pdu the raw PDU to store
190ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @return success or not
191ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
192ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     */
193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
194ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    public boolean
1957fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    updateMessageOnIccEf(String callingPackage, int index, int status, byte[] pdu) {
196ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (DBG) log("updateMessageOnIccEf: index=" + index +
197ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                " status=" + status + " ==> " +
198ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                "("+ Arrays.toString(pdu) + ")");
199ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        enforceReceiveAndSend("Updating message on Icc");
2007fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_WRITE_ICC_SMS, Binder.getCallingUid(),
2017fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
2027fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return false;
2037fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
204ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        synchronized(mLock) {
205ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            mSuccess = false;
206ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
207ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
208ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            if (status == STATUS_ON_ICC_FREE) {
209ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                // RIL_REQUEST_DELETE_SMS_ON_SIM vs RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM
210ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                // Special case FREE: call deleteSmsOnSim/Ruim instead of
211ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                // manipulating the record
212ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                // Will eventually fail if icc card is not present.
2136f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                if (PhoneConstants.PHONE_TYPE_GSM == mPhone.getPhoneType()) {
2146f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    mPhone.mCi.deleteSmsOnSim(index, response);
2156f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                } else {
2166f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    mPhone.mCi.deleteSmsOnRuim(index, response);
2176f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                }
218ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            } else {
219ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                //IccFilehandler can be null if ICC card is not present.
220ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                IccFileHandler fh = mPhone.getIccFileHandler();
221ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                if (fh == null) {
222ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    response.recycle();
223ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    return mSuccess; /* is false */
224ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                }
225ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                byte[] record = makeSmsRecordData(status, pdu);
226ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                fh.updateEFLinearFixed(
227ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        IccConstants.EF_SMS,
228ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        index, record, null, response);
229ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
230ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            try {
231ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                mLock.wait();
232ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            } catch (InterruptedException e) {
233ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                log("interrupted while trying to update by index");
234ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
235ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
236ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        return mSuccess;
237ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    }
238ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
239ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    /**
240ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * Copy a raw SMS PDU to the Icc.
241ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
242ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param pdu the raw PDU to store
243ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
244ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
245ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @return success or not
246ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
247ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     */
2487fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public boolean copyMessageToIccEf(String callingPackage, int status, byte[] pdu, byte[] smsc) {
249ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        //NOTE smsc not used in RUIM
250ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
251ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                "pdu=("+ Arrays.toString(pdu) +
252ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                "), smsc=(" + Arrays.toString(smsc) +")");
253ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        enforceReceiveAndSend("Copying message to Icc");
2547fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_WRITE_ICC_SMS, Binder.getCallingUid(),
2557fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
2567fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return false;
2577fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
258ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        synchronized(mLock) {
259ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            mSuccess = false;
260ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
261ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
262ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            //RIL_REQUEST_WRITE_SMS_TO_SIM vs RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM
2636f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            if (PhoneConstants.PHONE_TYPE_GSM == mPhone.getPhoneType()) {
2646f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                mPhone.mCi.writeSmsToSim(status, IccUtils.bytesToHexString(smsc),
2656f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                        IccUtils.bytesToHexString(pdu), response);
2666f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            } else {
2676f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                mPhone.mCi.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu),
2686f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                        response);
2696f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            }
270ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
271ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            try {
272ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                mLock.wait();
273ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            } catch (InterruptedException e) {
274ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                log("interrupted while trying to update by index");
275ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
276ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
277ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        return mSuccess;
278ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    }
279ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
280ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    /**
281ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * Retrieves all messages currently stored on Icc.
282ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
283ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @return list of SmsRawData of all sms on Icc
284ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     */
285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2867fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public List<SmsRawData> getAllMessagesFromIccEf(String callingPackage) {
287ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (DBG) log("getAllMessagesFromEF");
288ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
289e5d7a8d946bf9496ffbe7533bffdeb83963489c3Jake Hamby        mContext.enforceCallingOrSelfPermission(
2907fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.RECEIVE_SMS,
291ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                "Reading messages from Icc");
2927fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_READ_ICC_SMS, Binder.getCallingUid(),
2937fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
2947fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return new ArrayList<SmsRawData>();
2957fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
296ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        synchronized(mLock) {
297ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
298ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            IccFileHandler fh = mPhone.getIccFileHandler();
299ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            if (fh == null) {
300ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                Rlog.e(LOG_TAG, "Cannot load Sms records. No icc card?");
301ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                if (mSms != null) {
302ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    mSms.clear();
303ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    return mSms;
304ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                }
305ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
306ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
307ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
308ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            fh.loadEFLinearFixedAll(IccConstants.EF_SMS, response);
309ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
310ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            try {
311ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                mLock.wait();
312ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            } catch (InterruptedException e) {
313ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                log("interrupted while trying to load from the Icc");
314ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
315ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
316ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        return mSms;
317ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    }
318ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
319ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    /**
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Send a data based SMS to a specific application port.
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param destAddr the address to send the message to
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param scAddr is the service center address or null to use
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  the current default SMSC
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param destPort the port to deliver the message to
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param data the body of the message to send
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param sentIntent if not NULL this <code>PendingIntent</code> is
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  broadcast when the message is successfully sent, or failed.
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The result code will be <code>Activity.RESULT_OK<code> for success,
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  or one of these errors:<br>
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_NULL_PDU</code><br>
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  the extra "errorCode" containing a radio technology specific value,
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  generally only useful for troubleshooting.<br>
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The per-application based SMS control checks sentIntent. If sentIntent
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  is NULL the caller will be checked against all unknown applications,
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  which cause smaller number of SMS to be sent in checking period.
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  broadcast when the message is delivered to the recipient.  The
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  raw pdu of the status report is in the extended data ("pdu").
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3457fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().enforceCallingPermission(
3487fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.SEND_SMS,
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "Sending SMS message");
350ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                destPort + " data='"+ HexDump.toHexString(data)  + "' sentIntent=" +
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sentIntent + " deliveryIntent=" + deliveryIntent);
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3557fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
3567fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
3577fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return;
3587fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
35970dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying        destAddr = filterDestAddress(destAddr);
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Send a text based SMS.
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param destAddr the address to send the message to
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param scAddr is the service center address or null to use
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  the current default SMSC
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param text the body of the message to send
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param sentIntent if not NULL this <code>PendingIntent</code> is
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  broadcast when the message is successfully sent, or failed.
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The result code will be <code>Activity.RESULT_OK<code> for success,
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  or one of these errors:<br>
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_NULL_PDU</code><br>
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  the extra "errorCode" containing a radio technology specific value,
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  generally only useful for troubleshooting.<br>
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The per-application based SMS control checks sentIntent. If sentIntent
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  is NULL the caller will be checked against all unknown applications,
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  which cause smaller number of SMS to be sent in checking period.
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  broadcast when the message is delivered to the recipient.  The
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  raw pdu of the status report is in the extended data ("pdu").
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
387a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3887fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public void sendText(String callingPackage, String destAddr, String scAddr,
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().enforceCallingPermission(
3917fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.SEND_SMS,
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "Sending SMS message");
393ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " text='"+ text + "' sentIntent=" +
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sentIntent + " deliveryIntent=" + deliveryIntent);
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3987fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
3997fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
4007fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return;
4017fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
40270dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying        destAddr = filterDestAddress(destAddr);
403b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,
404b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                null/*messageUri*/, callingPackage);
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
40863418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     * Inject an SMS PDU into the android application framework.
40963418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     *
41063418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     * @param pdu is the byte array of pdu to be injected into android application framework
41163418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     * @param format is the format of SMS pdu (3gpp or 3gpp2)
41263418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     * @param receivedIntent if not NULL this <code>PendingIntent</code> is
41363418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     *  broadcast when the message is successfully received by the
41463418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     *  android application framework. This intent is broadcasted at
41563418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     *  the same time an SMS received from radio is acknowledged back.
41663418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni     */
41763418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni    public void injectSmsPdu(byte[] pdu, String format, PendingIntent receivedIntent) {
418c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal        enforceCarrierPrivilege();
41963418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
42063418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni            log("pdu: " + pdu +
42163418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni                "\n format=" + format +
42263418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni                "\n receivedIntent=" + receivedIntent);
42363418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni        }
42463418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni        mDispatcher.injectSmsPdu(pdu, format, receivedIntent);
42563418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni    }
42663418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni
42763418bbd2a9d7cc88ae24cc5ae776c01d688fc3aAnil Muthineni    /**
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Send a multi-part text based SMS.
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param destAddr the address to send the message to
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param scAddr is the service center address or null to use
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   the current default SMSC
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param parts an <code>ArrayList</code> of strings that, in order,
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   comprise the original message
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param sentIntents if not null, an <code>ArrayList</code> of
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>PendingIntent</code>s (one for each message part) that is
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   broadcast when the corresponding message part has been sent.
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   The result code will be <code>Activity.RESULT_OK<code> for success,
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   or one of these errors:
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>RESULT_ERROR_RADIO_OFF</code>
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>RESULT_ERROR_NULL_PDU</code>.
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The per-application based SMS control checks sentIntent. If sentIntent
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  is NULL the caller will be checked against all unknown applications,
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  which cause smaller number of SMS to be sent in checking period.
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param deliveryIntents if not null, an <code>ArrayList</code> of
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>PendingIntent</code>s (one for each message part) that is
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   broadcast when the corresponding message part has been delivered
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   to the recipient.  The raw pdu of the status report is in the
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   extended data ("pdu").
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
452a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4537fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public void sendMultipartText(String callingPackage, String destAddr, String scAddr,
4547fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            List<String> parts, List<PendingIntent> sentIntents,
4557fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            List<PendingIntent> deliveryIntents) {
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().enforceCallingPermission(
4577fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.SEND_SMS,
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "Sending SMS message");
459ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int i = 0;
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (String part : parts) {
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr +
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ", part[" + (i++) + "]=" + part);
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4667fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
4677fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
4687fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return;
4697fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
470f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
471bd681a048599441c659f3d3a8300e47599783d54Xia Ying        destAddr = filterDestAddress(destAddr);
472bd681a048599441c659f3d3a8300e47599783d54Xia Ying
473f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying        if (parts.size() > 1 && parts.size() < 10 && !SmsMessage.hasEmsSupport()) {
474f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying            for (int i = 0; i < parts.size(); i++) {
475f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                // If EMS is not supported, we have to break down EMS into single segment SMS
476f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                // and add page info " x/y".
477f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                String singlePart = parts.get(i);
478f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                if (SmsMessage.shouldAppendPageNumberAsPrefix()) {
479f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                    singlePart = String.valueOf(i + 1) + '/' + parts.size() + ' ' + singlePart;
480f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                } else {
481f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                    singlePart = singlePart.concat(' ' + String.valueOf(i + 1) + '/' + parts.size());
482f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                }
483f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
484f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                PendingIntent singleSentIntent = null;
485f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                if (sentIntents != null && sentIntents.size() > i) {
486f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                    singleSentIntent = sentIntents.get(i);
487f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                }
488f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
489f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                PendingIntent singleDeliveryIntent = null;
490f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                if (deliveryIntents != null && deliveryIntents.size() > i) {
491f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                    singleDeliveryIntent = deliveryIntents.get(i);
492f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                }
493f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
494f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                mDispatcher.sendText(destAddr, scAddr, singlePart,
495f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                        singleSentIntent, singleDeliveryIntent,
496f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                        null/*messageUri*/, callingPackage);
497f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying            }
498f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying            return;
499f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying        }
500f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,
502b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents,
503b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                null/*messageUri*/, callingPackage);
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
506a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5074658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby    public int getPremiumSmsPermission(String packageName) {
5084658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby        return mDispatcher.getPremiumSmsPermission(packageName);
5094658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby    }
5104658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby
511a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
5124658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby    public void setPremiumSmsPermission(String packageName, int permission) {
5134658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby        mDispatcher.setPremiumSmsPermission(packageName, permission);
5144658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby    }
5154658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * create SmsRawData lists from all sms record byte[]
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Use null to indicate "free" record
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param messages List of message records from EF_SMS.
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return SmsRawData list of all in-used records
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) {
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int count = messages.size();
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<SmsRawData> ret;
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret = new ArrayList<SmsRawData>(count);
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] ba = messages.get(i);
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ba[0] == STATUS_ON_ICC_FREE) {
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret.add(null);
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret.add(new SmsRawData(messages.get(i)));
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Generates an EF_SMS record from status and raw PDU.
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param status Message status.  See TS 51.011 10.5.3.
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param pdu Raw message PDU.
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return byte array for the record.
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected byte[] makeSmsRecordData(int status, byte[] pdu) {
5490e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla        byte[] data;
5500e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla        if (PhoneConstants.PHONE_TYPE_GSM == mPhone.getPhoneType()) {
5510e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla            data = new byte[IccConstants.SMS_RECORD_LENGTH];
5520e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla        } else {
5530e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla            data = new byte[IccConstants.CDMA_SMS_RECORD_LENGTH];
5540e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla        }
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Status bits for this record.  See TS 51.011 10.5.3
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        data[0] = (byte)(status & 7);
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        System.arraycopy(pdu, 0, data, 1, pdu.length);
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Pad out with 0xFF's.
5620e4839f120dfe91f93bd164257fe61851530449bRakesh Pallerla        for (int j = pdu.length+1; j < data.length; j++) {
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            data[j] = -1;
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return data;
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
569a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe    public boolean enableCellBroadcast(int messageIdentifier, int ranType) {
570a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe        return enableCellBroadcastRange(messageIdentifier, messageIdentifier, ranType);
5716f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
5726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
573a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe    public boolean disableCellBroadcast(int messageIdentifier, int ranType) {
574a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe        return disableCellBroadcastRange(messageIdentifier, messageIdentifier, ranType);
5756f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
5766f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
577a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId, int ranType) {
578a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe        if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_GSM) {
5796f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            return enableGsmBroadcastRange(startMessageId, endMessageId);
580a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe        } else if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA) {
5816f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            return enableCdmaBroadcastRange(startMessageId, endMessageId);
582a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe        } else {
583a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe            throw new IllegalArgumentException("Not a supportted RAN Type");
5846f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
5856f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
5866f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
587a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId, int ranType) {
588a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe        if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_GSM ) {
5896f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            return disableGsmBroadcastRange(startMessageId, endMessageId);
590a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe        } else if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA)  {
5916f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            return disableCdmaBroadcastRange(startMessageId, endMessageId);
592a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe        } else {
593a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe            throw new IllegalArgumentException("Not a supportted RAN Type");
5946f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
5956f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
5966f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
5976f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    synchronized public boolean enableGsmBroadcastRange(int startMessageId, int endMessageId) {
5986f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG) log("enableGsmBroadcastRange");
5996f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6006f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        Context context = mPhone.getContext();
6016f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6026f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        context.enforceCallingPermission(
6036f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                "android.permission.RECEIVE_SMS",
6046f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                "Enabling cell broadcast SMS");
6056f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6066f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        String client = context.getPackageManager().getNameForUid(
6076f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                Binder.getCallingUid());
6086f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6096f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) {
610a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe            log("Failed to add GSM cell broadcast subscription for MID range " + startMessageId
6116f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    + " to " + endMessageId + " from client " + client);
6126f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            return false;
6136f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
6146f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6156f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG)
616a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe            log("Added GSM cell broadcast subscription for MID range " + startMessageId
6176f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    + " to " + endMessageId + " from client " + client);
6186f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6196f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
6206f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6216f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        return true;
6226f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
6236f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6246f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    synchronized public boolean disableGsmBroadcastRange(int startMessageId, int endMessageId) {
6256f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG) log("disableGsmBroadcastRange");
6266f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6276f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        Context context = mPhone.getContext();
6286f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6296f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        context.enforceCallingPermission(
6306f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                "android.permission.RECEIVE_SMS",
6316f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                "Disabling cell broadcast SMS");
6326f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6336f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        String client = context.getPackageManager().getNameForUid(
6346f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                Binder.getCallingUid());
6356f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6366f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) {
637a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe            log("Failed to remove GSM cell broadcast subscription for MID range " + startMessageId
6386f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    + " to " + endMessageId + " from client " + client);
6396f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            return false;
6406f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
6416f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6426f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG)
643a8064ed9c00ab7bdd584e722efebce429bcaa51bxinhe            log("Removed GSM cell broadcast subscription for MID range " + startMessageId
6446f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    + " to " + endMessageId + " from client " + client);
6456f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6466f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
6476f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6486f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        return true;
6496f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
6506f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6516f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    synchronized public boolean enableCdmaBroadcastRange(int startMessageId, int endMessageId) {
6526f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG) log("enableCdmaBroadcastRange");
6536f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6546f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        Context context = mPhone.getContext();
6556f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6566f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        context.enforceCallingPermission(
6576f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                "android.permission.RECEIVE_SMS",
6586f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                "Enabling cdma broadcast SMS");
6596f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6606f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        String client = context.getPackageManager().getNameForUid(
6616f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                Binder.getCallingUid());
6626f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6636f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (!mCdmaBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) {
6646f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            log("Failed to add cdma broadcast subscription for MID range " + startMessageId
6656f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    + " to " + endMessageId + " from client " + client);
6666f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            return false;
6676f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
6686f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6696f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG)
6706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            log("Added cdma broadcast subscription for MID range " + startMessageId
6716f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    + " to " + endMessageId + " from client " + client);
6726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6736f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        setCdmaBroadcastActivation(!mCdmaBroadcastRangeManager.isEmpty());
6746f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6756f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        return true;
6766f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
6776f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6786f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    synchronized public boolean disableCdmaBroadcastRange(int startMessageId, int endMessageId) {
6796f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG) log("disableCdmaBroadcastRange");
6806f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6816f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        Context context = mPhone.getContext();
6826f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6836f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        context.enforceCallingPermission(
6846f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                "android.permission.RECEIVE_SMS",
6856f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                "Disabling cell broadcast SMS");
6866f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6876f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        String client = context.getPackageManager().getNameForUid(
6886f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                Binder.getCallingUid());
6896f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6906f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (!mCdmaBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) {
6916f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            log("Failed to remove cdma broadcast subscription for MID range " + startMessageId
6926f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    + " to " + endMessageId + " from client " + client);
6936f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            return false;
6946f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
6956f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
6966f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG)
6976f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            log("Removed cdma broadcast subscription for MID range " + startMessageId
6986f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    + " to " + endMessageId + " from client " + client);
6996f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7006f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        setCdmaBroadcastActivation(!mCdmaBroadcastRangeManager.isEmpty());
7016f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7026f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        return true;
7036f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
7046f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7056f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    class CellBroadcastRangeManager extends IntRangeManager {
7066f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        private ArrayList<SmsBroadcastConfigInfo> mConfigList =
7076f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                new ArrayList<SmsBroadcastConfigInfo>();
7086f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7096f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        /**
7106f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * Called when the list of enabled ranges has changed. This will be
7116f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * followed by zero or more calls to {@link #addRange} followed by
7126f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * a call to {@link #finishUpdate}.
7136f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         */
7146f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        protected void startUpdate() {
7156f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mConfigList.clear();
7166f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
7176f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7186f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        /**
7196f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * Called after {@link #startUpdate} to indicate a range of enabled
7206f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * values.
7216f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * @param startId the first id included in the range
7226f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * @param endId the last id included in the range
7236f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         */
7246f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        protected void addRange(int startId, int endId, boolean selected) {
7256f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mConfigList.add(new SmsBroadcastConfigInfo(startId, endId,
7266f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                        SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected));
7276f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
7286f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7296f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        /**
7306f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * Called to indicate the end of a range update started by the
7316f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * previous call to {@link #startUpdate}.
7326f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * @return true if successful, false otherwise
7336f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         */
7346f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        protected boolean finishUpdate() {
7356f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            if (mConfigList.isEmpty()) {
7366f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                return true;
7376f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            } else {
7386f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                SmsBroadcastConfigInfo[] configs =
7396f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                        mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]);
7406f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                return setCellBroadcastConfig(configs);
7416f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            }
7426f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
7436f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
7446f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7456f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    class CdmaBroadcastRangeManager extends IntRangeManager {
7466f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        private ArrayList<CdmaSmsBroadcastConfigInfo> mConfigList =
7476f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                new ArrayList<CdmaSmsBroadcastConfigInfo>();
7486f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7496f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        /**
7506f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * Called when the list of enabled ranges has changed. This will be
7516f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * followed by zero or more calls to {@link #addRange} followed by a
7526f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * call to {@link #finishUpdate}.
7536f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         */
7546f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        protected void startUpdate() {
7556f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mConfigList.clear();
7566f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
757ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
7586f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        /**
7596f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * Called after {@link #startUpdate} to indicate a range of enabled
7606f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * values.
7616f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * @param startId the first id included in the range
7626f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * @param endId the last id included in the range
7636f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         */
7646f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        protected void addRange(int startId, int endId, boolean selected) {
7656f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mConfigList.add(new CdmaSmsBroadcastConfigInfo(startId, endId,
7666f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                    1, selected));
7676f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
768ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
7696f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        /**
7706f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * Called to indicate the end of a range update started by the previous
7716f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * call to {@link #startUpdate}.
7726f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         * @return true if successful, false otherwise
7736f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa         */
7746f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        protected boolean finishUpdate() {
7756f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            if (mConfigList.isEmpty()) {
7766f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                return true;
7776f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            } else {
7786f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                CdmaSmsBroadcastConfigInfo[] configs =
7796f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                        mConfigList.toArray(new CdmaSmsBroadcastConfigInfo[mConfigList.size()]);
7806f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                return setCdmaBroadcastConfig(configs);
7816f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            }
7826f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
7836f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
7846f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7856f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) {
7866f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG)
7876f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            log("Calling setGsmBroadcastConfig with " + configs.length + " configurations");
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7896f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        synchronized (mLock) {
7906f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE);
7916f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7926f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mSuccess = false;
7936f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mPhone.mCi.setGsmBroadcastConfig(configs, response);
7946f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
7956f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            try {
7966f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                mLock.wait();
7976f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            } catch (InterruptedException e) {
7986f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                log("interrupted while trying to set cell broadcast config");
7996f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            }
8006f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
8016f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8026f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        return mSuccess;
8036f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
8046f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8056f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    private boolean setCellBroadcastActivation(boolean activate) {
8066f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG)
8076f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            log("Calling setCellBroadcastActivation(" + activate + ')');
8086f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8096f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        synchronized (mLock) {
8106f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE);
8116f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8126f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mSuccess = false;
8136f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mPhone.mCi.setGsmBroadcastActivation(activate, response);
8146f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8156f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            try {
8166f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                mLock.wait();
8176f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            } catch (InterruptedException e) {
8186f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                log("interrupted while trying to set cell broadcast activation");
8196f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            }
8206f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
8216f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8226f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        return mSuccess;
8236f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
8246f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8256f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    private boolean setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs) {
8266f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG)
8276f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            log("Calling setCdmaBroadcastConfig with " + configs.length + " configurations");
8286f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8296f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        synchronized (mLock) {
8306f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE);
8316f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8326f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mSuccess = false;
8336f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mPhone.mCi.setCdmaBroadcastConfig(configs, response);
8346f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8356f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            try {
8366f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                mLock.wait();
8376f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            } catch (InterruptedException e) {
8386f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                log("interrupted while trying to set cdma broadcast config");
8396f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            }
8406f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
8416f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8426f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        return mSuccess;
8436f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
8446f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8456f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    private boolean setCdmaBroadcastActivation(boolean activate) {
8466f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        if (DBG)
8476f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            log("Calling setCdmaBroadcastActivation(" + activate + ")");
8486f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8496f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        synchronized (mLock) {
8506f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE);
8516f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8526f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mSuccess = false;
8536f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            mPhone.mCi.setCdmaBroadcastActivation(activate, response);
8546f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8556f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            try {
8566f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                mLock.wait();
8576f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            } catch (InterruptedException e) {
8586f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa                log("interrupted while trying to set cdma broadcast activation");
8596f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa            }
8606f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        }
8616f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8626f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        return mSuccess;
8636f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
8646f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa
8656f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    protected void log(String msg) {
8666f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa        Log.d(LOG_TAG, "[IccSmsInterfaceManager] " + msg);
8676f2a3e1ea86ae7ae2e04eb95582e54eec7a2f864Sukanya Rajkhowa    }
8681260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
8691260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    public boolean isImsSmsSupported() {
8701260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        return mDispatcher.isIms();
8711260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    }
8721260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa
8731260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    public String getImsSmsFormat() {
8741260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa        return mDispatcher.getImsSmsFormat();
8751260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa    }
876b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen
877b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    public void sendStoredText(String callingPkg, Uri messageUri, String scAddress,
878b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            PendingIntent sentIntent, PendingIntent deliveryIntent) {
879b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        mPhone.getContext().enforceCallingPermission(Manifest.permission.SEND_SMS,
880b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                "Sending SMS message");
881b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
882b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            log("sendStoredText: scAddr=" + scAddress + " messageUri=" + messageUri
883b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    + " sentIntent=" + sentIntent + " deliveryIntent=" + deliveryIntent);
884b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
885b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), callingPkg)
886b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                != AppOpsManager.MODE_ALLOWED) {
887b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            return;
888b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
889b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        final ContentResolver resolver = mPhone.getContext().getContentResolver();
890b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (!isFailedOrDraft(resolver, messageUri)) {
891b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredText: not FAILED or DRAFT message");
892b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            returnUnspecifiedFailure(sentIntent);
893b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            return;
894b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
895b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        final String[] textAndAddress = loadTextAndAddress(resolver, messageUri);
896b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (textAndAddress == null) {
897b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredText: can not load text");
898b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            returnUnspecifiedFailure(sentIntent);
899b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            return;
900b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
90170dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying        textAndAddress[1] = filterDestAddress(textAndAddress[1]);
902b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        mDispatcher.sendText(textAndAddress[1], scAddress, textAndAddress[0],
903b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                sentIntent, deliveryIntent, messageUri, callingPkg);
904b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    }
905b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen
906b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    public void sendStoredMultipartText(String callingPkg, Uri messageUri, String scAddress,
907b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
908b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        mPhone.getContext().enforceCallingPermission(Manifest.permission.SEND_SMS,
909b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                "Sending SMS message");
910b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(), callingPkg)
911b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                != AppOpsManager.MODE_ALLOWED) {
912b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            return;
913b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
914b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        final ContentResolver resolver = mPhone.getContext().getContentResolver();
915b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (!isFailedOrDraft(resolver, messageUri)) {
916b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: "
917b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    + "not FAILED or DRAFT message");
918b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            returnUnspecifiedFailure(sentIntents);
919b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            return;
920b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
921b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        final String[] textAndAddress = loadTextAndAddress(resolver, messageUri);
922b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (textAndAddress == null) {
923b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: can not load text");
924b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            returnUnspecifiedFailure(sentIntents);
925b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            return;
926b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
927b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        final ArrayList<String> parts = SmsManager.getDefault().divideMessage(textAndAddress[0]);
928b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (parts == null || parts.size() < 1) {
929b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: can not divide text");
930b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            returnUnspecifiedFailure(sentIntents);
931b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            return;
932b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
933f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
934bd681a048599441c659f3d3a8300e47599783d54Xia Ying        textAndAddress[1] = filterDestAddress(textAndAddress[1]);
935bd681a048599441c659f3d3a8300e47599783d54Xia Ying
936f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying        if (parts.size() > 1 && parts.size() < 10 && !SmsMessage.hasEmsSupport()) {
937f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying            for (int i = 0; i < parts.size(); i++) {
938f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                // If EMS is not supported, we have to break down EMS into single segment SMS
939f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                // and add page info " x/y".
940f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                String singlePart = parts.get(i);
941f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                if (SmsMessage.shouldAppendPageNumberAsPrefix()) {
942f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                    singlePart = String.valueOf(i + 1) + '/' + parts.size() + ' ' + singlePart;
943f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                } else {
944f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                    singlePart = singlePart.concat(' ' + String.valueOf(i + 1) + '/' + parts.size());
945f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                }
946f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
947f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                PendingIntent singleSentIntent = null;
948f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                if (sentIntents != null && sentIntents.size() > i) {
949f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                    singleSentIntent = sentIntents.get(i);
950f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                }
951f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
952f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                PendingIntent singleDeliveryIntent = null;
953f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                if (deliveryIntents != null && deliveryIntents.size() > i) {
954f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                    singleDeliveryIntent = deliveryIntents.get(i);
955f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                }
956f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
957f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                mDispatcher.sendText(textAndAddress[1], scAddress, singlePart,
958f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying                        singleSentIntent, singleDeliveryIntent, messageUri, callingPkg);
959f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying            }
960f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying            return;
961f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying        }
962f3166841bf9df142e2fbd63b7647bae7da712044Xia Ying
963b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        mDispatcher.sendMultipartText(
964b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                textAndAddress[1], // destAddress
965b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                scAddress,
966b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                parts,
967b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                (ArrayList<PendingIntent>) sentIntents,
968b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                (ArrayList<PendingIntent>) deliveryIntents,
969b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                messageUri,
970b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                callingPkg);
971b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    }
972b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen
973b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    private boolean isFailedOrDraft(ContentResolver resolver, Uri messageUri) {
97449754105adf232419410cfca7507aa63a9d05e3bYe Wen        // Clear the calling identity and query the database using the phone user id
97549754105adf232419410cfca7507aa63a9d05e3bYe Wen        // Otherwise the AppOps check in TelephonyProvider would complain about mismatch
97649754105adf232419410cfca7507aa63a9d05e3bYe Wen        // between the calling uid and the package uid
97749754105adf232419410cfca7507aa63a9d05e3bYe Wen        final long identity = Binder.clearCallingIdentity();
978b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        Cursor cursor = null;
979b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        try {
980b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            cursor = resolver.query(
981b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    messageUri,
982b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    new String[]{ Telephony.Sms.TYPE },
983b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    null/*selection*/,
984b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    null/*selectionArgs*/,
985b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    null/*sortOrder*/);
986b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            if (cursor != null && cursor.moveToFirst()) {
987b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                final int type = cursor.getInt(0);
988b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                return type == Telephony.Sms.MESSAGE_TYPE_DRAFT
989b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                        || type == Telephony.Sms.MESSAGE_TYPE_FAILED;
990b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            }
991b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        } catch (SQLiteException e) {
992b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            Log.e(LOG_TAG, "[IccSmsInterfaceManager]isFailedOrDraft: query message type failed", e);
993b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        } finally {
994b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            if (cursor != null) {
995b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                cursor.close();
996b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            }
99749754105adf232419410cfca7507aa63a9d05e3bYe Wen            Binder.restoreCallingIdentity(identity);
998b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
999b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        return false;
1000b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    }
1001b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen
1002b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    // Return an array including both the SMS text (0) and address (1)
1003b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    private String[] loadTextAndAddress(ContentResolver resolver, Uri messageUri) {
100449754105adf232419410cfca7507aa63a9d05e3bYe Wen        // Clear the calling identity and query the database using the phone user id
100549754105adf232419410cfca7507aa63a9d05e3bYe Wen        // Otherwise the AppOps check in TelephonyProvider would complain about mismatch
100649754105adf232419410cfca7507aa63a9d05e3bYe Wen        // between the calling uid and the package uid
100749754105adf232419410cfca7507aa63a9d05e3bYe Wen        final long identity = Binder.clearCallingIdentity();
1008b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        Cursor cursor = null;
1009b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        try {
1010b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            cursor = resolver.query(
1011b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    messageUri,
1012b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    new String[]{
1013b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                            Telephony.Sms.BODY,
1014b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                            Telephony.Sms.ADDRESS
1015b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    },
1016b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    null/*selection*/,
1017b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    null/*selectionArgs*/,
1018b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                    null/*sortOrder*/);
1019b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            if (cursor != null && cursor.moveToFirst()) {
1020b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                return new String[]{ cursor.getString(0), cursor.getString(1) };
1021b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            }
1022b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        } catch (SQLiteException e) {
1023b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            Log.e(LOG_TAG, "[IccSmsInterfaceManager]loadText: query message text failed", e);
1024b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        } finally {
1025b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            if (cursor != null) {
1026b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                cursor.close();
1027b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            }
102849754105adf232419410cfca7507aa63a9d05e3bYe Wen            Binder.restoreCallingIdentity(identity);
1029b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
1030b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        return null;
1031b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    }
1032b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen
1033b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    private void returnUnspecifiedFailure(PendingIntent pi) {
1034b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (pi != null) {
1035b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            try {
1036b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                pi.send(SmsManager.RESULT_ERROR_GENERIC_FAILURE);
1037b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            } catch (PendingIntent.CanceledException e) {
1038b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen                // ignore
1039b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            }
1040b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
1041b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    }
1042b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen
1043b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    private void returnUnspecifiedFailure(List<PendingIntent> pis) {
1044b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        if (pis == null) {
1045b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            return;
1046b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
1047b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        for (PendingIntent pi : pis) {
1048b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen            returnUnspecifiedFailure(pi);
1049b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen        }
1050b29851580bba4a13ddbf7a534d8b09295eb2c60fYe Wen    }
1051c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal
1052c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal    private void enforceCarrierPrivilege() {
105368515b655255005f653aec29e9f152412514982aShishir Agrawal        UiccController controller = UiccController.getInstance();
105468515b655255005f653aec29e9f152412514982aShishir Agrawal        if (controller == null || controller.getUiccCard() == null) {
105568515b655255005f653aec29e9f152412514982aShishir Agrawal            throw new SecurityException("No Carrier Privilege: No UICC");
105668515b655255005f653aec29e9f152412514982aShishir Agrawal        }
105768515b655255005f653aec29e9f152412514982aShishir Agrawal        if (controller.getUiccCard().getCarrierPrivilegeStatusForCurrentTransaction(
1058c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal                mContext.getPackageManager()) !=
1059c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal                    TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
1060c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal            throw new SecurityException("No Carrier Privilege.");
1061c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal        }
1062c9394399180abbc32d04f6a3652ce22d5931e0b8Shishir Agrawal    }
106370dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying
106470dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying    private String filterDestAddress(String destAddr) {
106570dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying        String result  = null;
10663c36d8029ea2c92e0339cd0cbe26511e5478da09Xia Ying        result = SmsNumberUtils.filterDestAddr(mPhone, destAddr);
106770dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying        return result != null ? result : destAddr;
106870dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying    }
106970dad6e7c56847c91bc55755c645680ea6c6fac3Xia Ying
10700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1071