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