| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.internal.telephony; |
| |
| import android.app.PendingIntent; |
| import android.content.Context; |
| import android.util.Log; |
| |
| import com.android.internal.util.HexDump; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import static android.telephony.SmsManager.STATUS_ON_ICC_FREE; |
| |
| /** |
| * IccSmsInterfaceManager to provide an inter-process communication to |
| * access Sms in Icc. |
| */ |
| public abstract class IccSmsInterfaceManager extends ISms.Stub { |
| protected PhoneBase mPhone; |
| protected Context mContext; |
| protected SMSDispatcher mDispatcher; |
| |
| protected IccSmsInterfaceManager(PhoneBase phone){ |
| mPhone = phone; |
| mContext = phone.getContext(); |
| } |
| |
| protected void enforceReceiveAndSend(String message) { |
| mContext.enforceCallingPermission( |
| "android.permission.RECEIVE_SMS", message); |
| mContext.enforceCallingPermission( |
| "android.permission.SEND_SMS", message); |
| } |
| |
| /** |
| * Send a data based SMS to a specific application port. |
| * |
| * @param destAddr the address to send the message to |
| * @param scAddr is the service center address or null to use |
| * the current default SMSC |
| * @param destPort the port to deliver the message to |
| * @param data the body of the message to send |
| * @param sentIntent if not NULL this <code>PendingIntent</code> is |
| * broadcast when the message is sucessfully sent, or failed. |
| * The result code will be <code>Activity.RESULT_OK<code> for success, |
| * or one of these errors:<br> |
| * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> |
| * <code>RESULT_ERROR_RADIO_OFF</code><br> |
| * <code>RESULT_ERROR_NULL_PDU</code><br> |
| * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include |
| * the extra "errorCode" containing a radio technology specific value, |
| * generally only useful for troubleshooting.<br> |
| * The per-application based SMS control checks sentIntent. If sentIntent |
| * is NULL the caller will be checked against all unknown applicaitons, |
| * which cause smaller number of SMS to be sent in checking period. |
| * @param deliveryIntent if not NULL this <code>PendingIntent</code> is |
| * broadcast when the message is delivered to the recipient. The |
| * raw pdu of the status report is in the extended data ("pdu"). |
| */ |
| public void sendData(String destAddr, String scAddr, int destPort, |
| byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { |
| mPhone.getContext().enforceCallingPermission( |
| "android.permission.SEND_SMS", |
| "Sending SMS message"); |
| if (Log.isLoggable("SMS", Log.VERBOSE)) { |
| log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" + |
| destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" + |
| sentIntent + " deliveryIntent=" + deliveryIntent); |
| } |
| mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent); |
| } |
| |
| /** |
| * Send a text based SMS. |
| * |
| * @param destAddr the address to send the message to |
| * @param scAddr is the service center address or null to use |
| * the current default SMSC |
| * @param text the body of the message to send |
| * @param sentIntent if not NULL this <code>PendingIntent</code> is |
| * broadcast when the message is sucessfully sent, or failed. |
| * The result code will be <code>Activity.RESULT_OK<code> for success, |
| * or one of these errors:<br> |
| * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> |
| * <code>RESULT_ERROR_RADIO_OFF</code><br> |
| * <code>RESULT_ERROR_NULL_PDU</code><br> |
| * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include |
| * the extra "errorCode" containing a radio technology specific value, |
| * generally only useful for troubleshooting.<br> |
| * The per-application based SMS control checks sentIntent. If sentIntent |
| * is NULL the caller will be checked against all unknown applications, |
| * which cause smaller number of SMS to be sent in checking period. |
| * @param deliveryIntent if not NULL this <code>PendingIntent</code> is |
| * broadcast when the message is delivered to the recipient. The |
| * raw pdu of the status report is in the extended data ("pdu"). |
| */ |
| public void sendText(String destAddr, String scAddr, |
| String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { |
| mPhone.getContext().enforceCallingPermission( |
| "android.permission.SEND_SMS", |
| "Sending SMS message"); |
| if (Log.isLoggable("SMS", Log.VERBOSE)) { |
| log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr + |
| " text='"+ text + "' sentIntent=" + |
| sentIntent + " deliveryIntent=" + deliveryIntent); |
| } |
| mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent); |
| } |
| |
| /** |
| * Send a multi-part text based SMS. |
| * |
| * @param destAddr the address to send the message to |
| * @param scAddr is the service center address or null to use |
| * the current default SMSC |
| * @param parts an <code>ArrayList</code> of strings that, in order, |
| * comprise the original message |
| * @param sentIntents if not null, an <code>ArrayList</code> of |
| * <code>PendingIntent</code>s (one for each message part) that is |
| * broadcast when the corresponding message part has been sent. |
| * The result code will be <code>Activity.RESULT_OK<code> for success, |
| * or one of these errors: |
| * <code>RESULT_ERROR_GENERIC_FAILURE</code> |
| * <code>RESULT_ERROR_RADIO_OFF</code> |
| * <code>RESULT_ERROR_NULL_PDU</code>. |
| * The per-application based SMS control checks sentIntent. If sentIntent |
| * is NULL the caller will be checked against all unknown applicaitons, |
| * which cause smaller number of SMS to be sent in checking period. |
| * @param deliveryIntents if not null, an <code>ArrayList</code> of |
| * <code>PendingIntent</code>s (one for each message part) that is |
| * broadcast when the corresponding message part has been delivered |
| * to the recipient. The raw pdu of the status report is in the |
| * extended data ("pdu"). |
| */ |
| public void sendMultipartText(String destAddr, String scAddr, List<String> parts, |
| List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { |
| mPhone.getContext().enforceCallingPermission( |
| "android.permission.SEND_SMS", |
| "Sending SMS message"); |
| if (Log.isLoggable("SMS", Log.VERBOSE)) { |
| int i = 0; |
| for (String part : parts) { |
| log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr + |
| ", part[" + (i++) + "]=" + part); |
| } |
| } |
| mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts, |
| (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents); |
| } |
| |
| /** |
| * create SmsRawData lists from all sms record byte[] |
| * Use null to indicate "free" record |
| * |
| * @param messages List of message records from EF_SMS. |
| * @return SmsRawData list of all in-used records |
| */ |
| protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) { |
| int count = messages.size(); |
| ArrayList<SmsRawData> ret; |
| |
| ret = new ArrayList<SmsRawData>(count); |
| |
| for (int i = 0; i < count; i++) { |
| byte[] ba = messages.get(i); |
| if (ba[0] == STATUS_ON_ICC_FREE) { |
| ret.add(null); |
| } else { |
| ret.add(new SmsRawData(messages.get(i))); |
| } |
| } |
| |
| return ret; |
| } |
| |
| /** |
| * Generates an EF_SMS record from status and raw PDU. |
| * |
| * @param status Message status. See TS 51.011 10.5.3. |
| * @param pdu Raw message PDU. |
| * @return byte array for the record. |
| */ |
| protected byte[] makeSmsRecordData(int status, byte[] pdu) { |
| byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH]; |
| |
| // Status bits for this record. See TS 51.011 10.5.3 |
| data[0] = (byte)(status & 7); |
| |
| System.arraycopy(pdu, 0, data, 1, pdu.length); |
| |
| // Pad out with 0xFF's. |
| for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) { |
| data[j] = -1; |
| } |
| |
| return data; |
| } |
| |
| protected abstract void log(String msg); |
| |
| } |