IccSmsInterfaceManager.java revision ded9c0af7fa49504c047275ed34c2d3b22bf0c3a
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony; 18 19import android.app.PendingIntent; 20import android.content.Context; 21import android.telephony.Rlog; 22import android.util.Log; 23 24import com.android.internal.util.HexDump; 25 26import java.util.ArrayList; 27import java.util.List; 28 29import static android.telephony.SmsManager.STATUS_ON_ICC_FREE; 30 31/** 32 * IccSmsInterfaceManager to provide an inter-process communication to 33 * access Sms in Icc. 34 */ 35public abstract class IccSmsInterfaceManager extends ISms.Stub { 36 protected PhoneBase mPhone; 37 protected Context mContext; 38 protected SMSDispatcher mDispatcher; 39 40 protected IccSmsInterfaceManager(PhoneBase phone){ 41 mPhone = phone; 42 mContext = phone.getContext(); 43 } 44 45 protected void enforceReceiveAndSend(String message) { 46 mContext.enforceCallingPermission( 47 "android.permission.RECEIVE_SMS", message); 48 mContext.enforceCallingPermission( 49 "android.permission.SEND_SMS", message); 50 } 51 52 /** 53 * Send a data based SMS to a specific application port. 54 * 55 * @param destAddr the address to send the message to 56 * @param scAddr is the service center address or null to use 57 * the current default SMSC 58 * @param destPort the port to deliver the message to 59 * @param data the body of the message to send 60 * @param sentIntent if not NULL this <code>PendingIntent</code> is 61 * broadcast when the message is successfully sent, or failed. 62 * The result code will be <code>Activity.RESULT_OK<code> for success, 63 * or one of these errors:<br> 64 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 65 * <code>RESULT_ERROR_RADIO_OFF</code><br> 66 * <code>RESULT_ERROR_NULL_PDU</code><br> 67 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include 68 * the extra "errorCode" containing a radio technology specific value, 69 * generally only useful for troubleshooting.<br> 70 * The per-application based SMS control checks sentIntent. If sentIntent 71 * is NULL the caller will be checked against all unknown applications, 72 * which cause smaller number of SMS to be sent in checking period. 73 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 74 * broadcast when the message is delivered to the recipient. The 75 * raw pdu of the status report is in the extended data ("pdu"). 76 */ 77 public void sendData(String destAddr, String scAddr, int destPort, 78 byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 79 mPhone.getContext().enforceCallingPermission( 80 "android.permission.SEND_SMS", 81 "Sending SMS message"); 82 if (Rlog.isLoggable("SMS", Log.VERBOSE)) { 83 log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" + 84 destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" + 85 sentIntent + " deliveryIntent=" + deliveryIntent); 86 } 87 mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent); 88 } 89 90 /** 91 * Send a text based SMS. 92 * 93 * @param destAddr the address to send the message to 94 * @param scAddr is the service center address or null to use 95 * the current default SMSC 96 * @param text the body of the message to send 97 * @param sentIntent if not NULL this <code>PendingIntent</code> is 98 * broadcast when the message is successfully sent, or failed. 99 * The result code will be <code>Activity.RESULT_OK<code> for success, 100 * or one of these errors:<br> 101 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> 102 * <code>RESULT_ERROR_RADIO_OFF</code><br> 103 * <code>RESULT_ERROR_NULL_PDU</code><br> 104 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include 105 * the extra "errorCode" containing a radio technology specific value, 106 * generally only useful for troubleshooting.<br> 107 * The per-application based SMS control checks sentIntent. If sentIntent 108 * is NULL the caller will be checked against all unknown applications, 109 * which cause smaller number of SMS to be sent in checking period. 110 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 111 * broadcast when the message is delivered to the recipient. The 112 * raw pdu of the status report is in the extended data ("pdu"). 113 */ 114 public void sendText(String destAddr, String scAddr, 115 String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { 116 mPhone.getContext().enforceCallingPermission( 117 "android.permission.SEND_SMS", 118 "Sending SMS message"); 119 if (Rlog.isLoggable("SMS", Log.VERBOSE)) { 120 log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr + 121 " text='"+ text + "' sentIntent=" + 122 sentIntent + " deliveryIntent=" + deliveryIntent); 123 } 124 mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent); 125 } 126 127 /** 128 * Send a multi-part text based SMS. 129 * 130 * @param destAddr the address to send the message to 131 * @param scAddr is the service center address or null to use 132 * the current default SMSC 133 * @param parts an <code>ArrayList</code> of strings that, in order, 134 * comprise the original message 135 * @param sentIntents if not null, an <code>ArrayList</code> of 136 * <code>PendingIntent</code>s (one for each message part) that is 137 * broadcast when the corresponding message part has been sent. 138 * The result code will be <code>Activity.RESULT_OK<code> for success, 139 * or one of these errors: 140 * <code>RESULT_ERROR_GENERIC_FAILURE</code> 141 * <code>RESULT_ERROR_RADIO_OFF</code> 142 * <code>RESULT_ERROR_NULL_PDU</code>. 143 * The per-application based SMS control checks sentIntent. If sentIntent 144 * is NULL the caller will be checked against all unknown applications, 145 * which cause smaller number of SMS to be sent in checking period. 146 * @param deliveryIntents if not null, an <code>ArrayList</code> of 147 * <code>PendingIntent</code>s (one for each message part) that is 148 * broadcast when the corresponding message part has been delivered 149 * to the recipient. The raw pdu of the status report is in the 150 * extended data ("pdu"). 151 */ 152 public void sendMultipartText(String destAddr, String scAddr, List<String> parts, 153 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { 154 mPhone.getContext().enforceCallingPermission( 155 "android.permission.SEND_SMS", 156 "Sending SMS message"); 157 if (Rlog.isLoggable("SMS", Log.VERBOSE)) { 158 int i = 0; 159 for (String part : parts) { 160 log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr + 161 ", part[" + (i++) + "]=" + part); 162 } 163 } 164 mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts, 165 (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents); 166 } 167 168 public int getPremiumSmsPermission(String packageName) { 169 return mDispatcher.getPremiumSmsPermission(packageName); 170 } 171 172 public void setPremiumSmsPermission(String packageName, int permission) { 173 mDispatcher.setPremiumSmsPermission(packageName, permission); 174 } 175 176 /** 177 * create SmsRawData lists from all sms record byte[] 178 * Use null to indicate "free" record 179 * 180 * @param messages List of message records from EF_SMS. 181 * @return SmsRawData list of all in-used records 182 */ 183 protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) { 184 int count = messages.size(); 185 ArrayList<SmsRawData> ret; 186 187 ret = new ArrayList<SmsRawData>(count); 188 189 for (int i = 0; i < count; i++) { 190 byte[] ba = messages.get(i); 191 if (ba[0] == STATUS_ON_ICC_FREE) { 192 ret.add(null); 193 } else { 194 ret.add(new SmsRawData(messages.get(i))); 195 } 196 } 197 198 return ret; 199 } 200 201 /** 202 * Generates an EF_SMS record from status and raw PDU. 203 * 204 * @param status Message status. See TS 51.011 10.5.3. 205 * @param pdu Raw message PDU. 206 * @return byte array for the record. 207 */ 208 protected byte[] makeSmsRecordData(int status, byte[] pdu) { 209 byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH]; 210 211 // Status bits for this record. See TS 51.011 10.5.3 212 data[0] = (byte)(status & 7); 213 214 System.arraycopy(pdu, 0, data, 1, pdu.length); 215 216 // Pad out with 0xFF's. 217 for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) { 218 data[j] = -1; 219 } 220 221 return data; 222 } 223 224 protected abstract void log(String msg); 225 226} 227