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;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
23ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.AsyncResult;
247fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.os.Binder;
25ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.Handler;
26ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport android.os.Message;
27ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
30d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccConstants;
31ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport com.android.internal.telephony.uicc.IccFileHandler;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.HexDump;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
35ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport java.util.Arrays;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
39ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport static android.telephony.SmsManager.STATUS_ON_ICC_READ;
40ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooksimport static android.telephony.SmsManager.STATUS_ON_ICC_UNREAD;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * IccSmsInterfaceManager to provide an inter-process communication to
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * access Sms in Icc.
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic abstract class IccSmsInterfaceManager extends ISms.Stub {
47cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "IccSmsInterfaceManager";
48ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    static final boolean DBG = true;
49ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
50ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected final Object mLock = new Object();
51ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected boolean mSuccess;
52ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    private List<SmsRawData> mSms;
53ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
54ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    private static final int EVENT_LOAD_DONE = 1;
55ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    private static final int EVENT_UPDATE_DONE = 2;
56ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected static final int EVENT_SET_BROADCAST_ACTIVATION_DONE = 3;
57ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected static final int EVENT_SET_BROADCAST_CONFIG_DONE = 4;
58ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
597fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    final protected PhoneBase mPhone;
607fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    final protected Context mContext;
617fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    final protected AppOpsManager mAppOps;
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected SMSDispatcher mDispatcher;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
64ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected Handler mHandler = new Handler() {
65ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        @Override
66ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        public void handleMessage(Message msg) {
67ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            AsyncResult ar;
68ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
69ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            switch (msg.what) {
70ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                case EVENT_UPDATE_DONE:
71ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    ar = (AsyncResult) msg.obj;
72ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    synchronized (mLock) {
73ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mSuccess = (ar.exception == null);
74ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mLock.notifyAll();
75ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    }
76ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    break;
77ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                case EVENT_LOAD_DONE:
78ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    ar = (AsyncResult)msg.obj;
79ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    synchronized (mLock) {
80ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        if (ar.exception == null) {
81ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                            mSms = buildValidRawData((ArrayList<byte[]>) ar.result);
82ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                            //Mark SMS as read after importing it from card.
83ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                            markMessagesAsRead((ArrayList<byte[]>) ar.result);
84ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        } else {
85ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                            if(DBG) log("Cannot load Sms records");
86ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                            if (mSms != null)
87ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                                mSms.clear();
88ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        }
89ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mLock.notifyAll();
90ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    }
91ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    break;
92ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                case EVENT_SET_BROADCAST_ACTIVATION_DONE:
93ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                case EVENT_SET_BROADCAST_CONFIG_DONE:
94ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    ar = (AsyncResult) msg.obj;
95ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    synchronized (mLock) {
96ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mSuccess = (ar.exception == null);
97ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        mLock.notifyAll();
98ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    }
99ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    break;
100ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
101ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
102ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    };
103ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected IccSmsInterfaceManager(PhoneBase phone){
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone = phone;
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mContext = phone.getContext();
1077fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
110ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected void markMessagesAsRead(ArrayList<byte[]> messages) {
111ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (messages == null) {
112ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            return;
113ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
114ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
115ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        //IccFileHandler can be null, if icc card is absent.
116ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        IccFileHandler fh = mPhone.getIccFileHandler();
117ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (fh == null) {
118ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            //shouldn't really happen, as messages are marked as read, only
119ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            //after importing it from icc.
120ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            if (Rlog.isLoggable("SMS", Log.DEBUG)) {
121ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                log("markMessagesAsRead - aborting, no icc card present.");
122ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
123ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            return;
124ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
125ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
126ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        int count = messages.size();
127ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
128ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        for (int i = 0; i < count; i++) {
129ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks             byte[] ba = messages.get(i);
130ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks             if (ba[0] == STATUS_ON_ICC_UNREAD) {
131ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 int n = ba.length;
132ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 byte[] nba = new byte[n - 1];
133ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 System.arraycopy(ba, 1, nba, 0, n - 1);
134ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 byte[] record = makeSmsRecordData(STATUS_ON_ICC_READ, nba);
135ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 fh.updateEFLinearFixed(IccConstants.EF_SMS, i + 1, record, null, null);
136ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 if (Rlog.isLoggable("SMS", Log.DEBUG)) {
137ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                     log("SMS " + (i + 1) + " marked as read");
138ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                 }
139ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks             }
140ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
141ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    }
142ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected void enforceReceiveAndSend(String message) {
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mContext.enforceCallingPermission(
1457fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.RECEIVE_SMS, message);
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mContext.enforceCallingPermission(
1477fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.SEND_SMS, message);
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
151ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * Update the specified message on the Icc.
152ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
153ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param index record index of message to update
154ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param status new message status (STATUS_ON_ICC_READ,
155ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
156ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
157ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param pdu the raw PDU to store
158ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @return success or not
159ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
160ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     */
161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
162ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    public boolean
1637fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    updateMessageOnIccEf(String callingPackage, int index, int status, byte[] pdu) {
164ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (DBG) log("updateMessageOnIccEf: index=" + index +
165ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                " status=" + status + " ==> " +
166ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                "("+ Arrays.toString(pdu) + ")");
167ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        enforceReceiveAndSend("Updating message on Icc");
1687fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_WRITE_ICC_SMS, Binder.getCallingUid(),
1697fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
1707fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return false;
1717fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
172ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        synchronized(mLock) {
173ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            mSuccess = false;
174ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
175ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
176ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            if (status == STATUS_ON_ICC_FREE) {
177ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                // RIL_REQUEST_DELETE_SMS_ON_SIM vs RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM
178ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                // Special case FREE: call deleteSmsOnSim/Ruim instead of
179ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                // manipulating the record
180ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                // Will eventually fail if icc card is not present.
181ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                deleteSms(index, response);
182ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            } else {
183ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                //IccFilehandler can be null if ICC card is not present.
184ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                IccFileHandler fh = mPhone.getIccFileHandler();
185ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                if (fh == null) {
186ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    response.recycle();
187ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    return mSuccess; /* is false */
188ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                }
189ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                byte[] record = makeSmsRecordData(status, pdu);
190ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                fh.updateEFLinearFixed(
191ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        IccConstants.EF_SMS,
192ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                        index, record, null, response);
193ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
194ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            try {
195ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                mLock.wait();
196ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            } catch (InterruptedException e) {
197ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                log("interrupted while trying to update by index");
198ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
199ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
200ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        return mSuccess;
201ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    }
202ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
203ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    /**
204ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * Copy a raw SMS PDU to the Icc.
205ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
206ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param pdu the raw PDU to store
207ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
208ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
209ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @return success or not
210ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
211ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     */
212cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2137fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public boolean copyMessageToIccEf(String callingPackage, int status, byte[] pdu, byte[] smsc) {
214ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        //NOTE smsc not used in RUIM
215ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
216ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                "pdu=("+ Arrays.toString(pdu) +
217ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                "), smsc=(" + Arrays.toString(smsc) +")");
218ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        enforceReceiveAndSend("Copying message to Icc");
2197fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_WRITE_ICC_SMS, Binder.getCallingUid(),
2207fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
2217fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return false;
2227fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
223ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        synchronized(mLock) {
224ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            mSuccess = false;
225ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
226ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
227ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            //RIL_REQUEST_WRITE_SMS_TO_SIM vs RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM
228ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            writeSms(status, smsc, pdu, 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     * Retrieves all messages currently stored on Icc.
241ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     *
242ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     * @return list of SmsRawData of all sms on Icc
243ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks     */
244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2457fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public List<SmsRawData> getAllMessagesFromIccEf(String callingPackage) {
246ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        if (DBG) log("getAllMessagesFromEF");
247ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
248ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        mContext.enforceCallingPermission(
2497fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.RECEIVE_SMS,
250ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                "Reading messages from Icc");
2517fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_READ_ICC_SMS, Binder.getCallingUid(),
2527fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
2537fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return new ArrayList<SmsRawData>();
2547fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
255ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        synchronized(mLock) {
256ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
257ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            IccFileHandler fh = mPhone.getIccFileHandler();
258ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            if (fh == null) {
259ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                Rlog.e(LOG_TAG, "Cannot load Sms records. No icc card?");
260ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                if (mSms != null) {
261ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    mSms.clear();
262ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                    return mSms;
263ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                }
264ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
265ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
266ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
267ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            fh.loadEFLinearFixedAll(IccConstants.EF_SMS, response);
268ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
269ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            try {
270ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                mLock.wait();
271ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            } catch (InterruptedException e) {
272ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks                log("interrupted while trying to load from the Icc");
273ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks            }
274ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        }
275ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks        return mSms;
276ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    }
277ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
278ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    /**
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Send a data based SMS to a specific application port.
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param destAddr the address to send the message to
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param scAddr is the service center address or null to use
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  the current default SMSC
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param destPort the port to deliver the message to
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param data the body of the message to send
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param sentIntent if not NULL this <code>PendingIntent</code> is
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  broadcast when the message is successfully sent, or failed.
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The result code will be <code>Activity.RESULT_OK<code> for success,
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  or one of these errors:<br>
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_NULL_PDU</code><br>
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  the extra "errorCode" containing a radio technology specific value,
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  generally only useful for troubleshooting.<br>
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The per-application based SMS control checks sentIntent. If sentIntent
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  is NULL the caller will be checked against all unknown applications,
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  which cause smaller number of SMS to be sent in checking period.
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  broadcast when the message is delivered to the recipient.  The
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  raw pdu of the status report is in the extended data ("pdu").
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
303cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3047fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().enforceCallingPermission(
3077fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.SEND_SMS,
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "Sending SMS message");
309ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                destPort + " data='"+ HexDump.toHexString(data)  + "' sentIntent=" +
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sentIntent + " deliveryIntent=" + deliveryIntent);
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3147fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
3157fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
3167fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return;
3177fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Send a text based SMS.
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param destAddr the address to send the message to
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param scAddr is the service center address or null to use
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  the current default SMSC
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param text the body of the message to send
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param sentIntent if not NULL this <code>PendingIntent</code> is
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  broadcast when the message is successfully sent, or failed.
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The result code will be <code>Activity.RESULT_OK<code> for success,
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  or one of these errors:<br>
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  <code>RESULT_ERROR_NULL_PDU</code><br>
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  the extra "errorCode" containing a radio technology specific value,
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  generally only useful for troubleshooting.<br>
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The per-application based SMS control checks sentIntent. If sentIntent
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  is NULL the caller will be checked against all unknown applications,
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  which cause smaller number of SMS to be sent in checking period.
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  broadcast when the message is delivered to the recipient.  The
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  raw pdu of the status report is in the extended data ("pdu").
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
345cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3467fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public void sendText(String callingPackage, String destAddr, String scAddr,
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().enforceCallingPermission(
3497fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.SEND_SMS,
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "Sending SMS message");
351ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                " text='"+ text + "' sentIntent=" +
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sentIntent + " deliveryIntent=" + deliveryIntent);
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3567fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
3577fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
3587fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return;
3597fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Send a multi-part 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 parts an <code>ArrayList</code> of strings that, in order,
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   comprise the original message
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param sentIntents if not null, an <code>ArrayList</code> of
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>PendingIntent</code>s (one for each message part) that is
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   broadcast when the corresponding message part has been sent.
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   The result code will be <code>Activity.RESULT_OK<code> for success,
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   or one of these errors:
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>RESULT_ERROR_RADIO_OFF</code>
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>RESULT_ERROR_NULL_PDU</code>.
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  The per-application based SMS control checks sentIntent. If sentIntent
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  is NULL the caller will be checked against all unknown applications,
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  which cause smaller number of SMS to be sent in checking period.
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param deliveryIntents if not null, an <code>ArrayList</code> of
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   <code>PendingIntent</code>s (one for each message part) that is
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   broadcast when the corresponding message part has been delivered
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   to the recipient.  The raw pdu of the status report is in the
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *   extended data ("pdu").
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
3897fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn    public void sendMultipartText(String callingPackage, String destAddr, String scAddr,
3907fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            List<String> parts, List<PendingIntent> sentIntents,
3917fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            List<PendingIntent> deliveryIntents) {
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mPhone.getContext().enforceCallingPermission(
3937fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                Manifest.permission.SEND_SMS,
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "Sending SMS message");
395ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int i = 0;
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (String part : parts) {
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr +
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ", part[" + (i++) + "]=" + part);
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4027fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        if (mAppOps.noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
4037fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn                callingPackage) != AppOpsManager.MODE_ALLOWED) {
4047fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn            return;
4057fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn        }
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
410cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4114658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby    public int getPremiumSmsPermission(String packageName) {
4124658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby        return mDispatcher.getPremiumSmsPermission(packageName);
4134658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby    }
4144658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby
415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
4164658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby    public void setPremiumSmsPermission(String packageName, int permission) {
4174658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby        mDispatcher.setPremiumSmsPermission(packageName, permission);
4184658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby    }
4194658a1a8c23111d5cc89feb040ce547a7b65dfb0Jake Hamby
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * create SmsRawData lists from all sms record byte[]
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Use null to indicate "free" record
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param messages List of message records from EF_SMS.
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return SmsRawData list of all in-used records
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) {
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int count = messages.size();
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<SmsRawData> ret;
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret = new ArrayList<SmsRawData>(count);
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < count; i++) {
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] ba = messages.get(i);
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ba[0] == STATUS_ON_ICC_FREE) {
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret.add(null);
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret.add(new SmsRawData(messages.get(i)));
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Generates an EF_SMS record from status and raw PDU.
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param status Message status.  See TS 51.011 10.5.3.
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param pdu Raw message PDU.
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return byte array for the record.
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected byte[] makeSmsRecordData(int status, byte[] pdu) {
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH];
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Status bits for this record.  See TS 51.011 10.5.3
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        data[0] = (byte)(status & 7);
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        System.arraycopy(pdu, 0, data, 1, pdu.length);
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Pad out with 0xFF's.
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) {
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            data[j] = -1;
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return data;
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
468ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected abstract void deleteSms(int index, Message response);
469ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
470ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks    protected abstract void writeSms(int status, byte[] pdu, byte[] smsc, Message response);
471ebc3f0565ad0f9b8b7d3531afd8744843d96aadbRika Brooks
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    protected abstract void log(String msg);
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
475