1package com.android.mms.transaction;
2
3import java.util.ArrayList;
4
5import android.app.PendingIntent;
6import android.content.Context;
7import android.content.Intent;
8import android.net.Uri;
9import android.provider.Telephony.Mms;
10import android.provider.Telephony.Sms;
11import android.telephony.PhoneNumberUtils;
12import android.telephony.SmsManager;
13import android.util.Log;
14
15import com.android.mms.LogTag;
16import com.android.mms.MmsConfig;
17import com.android.mms.data.Conversation;
18import com.android.mms.ui.MessageUtils;
19import com.google.android.mms.MmsException;
20
21public class SmsSingleRecipientSender extends SmsMessageSender {
22
23    private final boolean mRequestDeliveryReport;
24    private String mDest;
25    private Uri mUri;
26    private static final String TAG = LogTag.TAG;
27
28    public SmsSingleRecipientSender(Context context, String dest, String msgText, long threadId,
29            boolean requestDeliveryReport, Uri uri) {
30        super(context, null, msgText, threadId);
31        mRequestDeliveryReport = requestDeliveryReport;
32        mDest = dest;
33        mUri = uri;
34    }
35
36    public boolean sendMessage(long token) throws MmsException {
37        if (LogTag.DEBUG_SEND) {
38            Log.v(TAG, "sendMessage token: " + token);
39        }
40        if (mMessageText == null) {
41            // Don't try to send an empty message, and destination should be just
42            // one.
43            throw new MmsException("Null message body or have multiple destinations.");
44        }
45        SmsManager smsManager = SmsManager.getDefault();
46        ArrayList<String> messages = null;
47        if ((MmsConfig.getEmailGateway() != null) &&
48                (Mms.isEmailAddress(mDest) || MessageUtils.isAlias(mDest))) {
49            String msgText;
50            msgText = mDest + " " + mMessageText;
51            mDest = MmsConfig.getEmailGateway();
52            messages = smsManager.divideMessage(msgText);
53        } else {
54            messages = smsManager.divideMessage(mMessageText);
55            // remove spaces and dashes from destination number
56            // (e.g. "801 555 1212" -> "8015551212")
57            // (e.g. "+8211-123-4567" -> "+82111234567")
58            mDest = PhoneNumberUtils.stripSeparators(mDest);
59            mDest = Conversation.verifySingleRecipient(mContext, mThreadId, mDest);
60        }
61        int messageCount = messages.size();
62
63        if (messageCount == 0) {
64            // Don't try to send an empty message.
65            throw new MmsException("SmsMessageSender.sendMessage: divideMessage returned " +
66                    "empty messages. Original message is \"" + mMessageText + "\"");
67        }
68
69        boolean moved = Sms.moveMessageToFolder(mContext, mUri, Sms.MESSAGE_TYPE_OUTBOX, 0);
70        if (!moved) {
71            throw new MmsException("SmsMessageSender.sendMessage: couldn't move message " +
72                    "to outbox: " + mUri);
73        }
74        if (LogTag.DEBUG_SEND) {
75            Log.v(TAG, "sendMessage mDest: " + mDest + " mRequestDeliveryReport: " +
76                    mRequestDeliveryReport);
77        }
78
79        ArrayList<PendingIntent> deliveryIntents =  new ArrayList<PendingIntent>(messageCount);
80        ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(messageCount);
81        for (int i = 0; i < messageCount; i++) {
82            if (mRequestDeliveryReport && (i == (messageCount - 1))) {
83                // TODO: Fix: It should not be necessary to
84                // specify the class in this intent.  Doing that
85                // unnecessarily limits customizability.
86                deliveryIntents.add(PendingIntent.getBroadcast(
87                        mContext, 0,
88                        new Intent(
89                                MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION,
90                                mUri,
91                                mContext,
92                                MessageStatusReceiver.class),
93                                0));
94            } else {
95                deliveryIntents.add(null);
96            }
97            Intent intent  = new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,
98                    mUri,
99                    mContext,
100                    SmsReceiver.class);
101
102            int requestCode = 0;
103            if (i == messageCount -1) {
104                // Changing the requestCode so that a different pending intent
105                // is created for the last fragment with
106                // EXTRA_MESSAGE_SENT_SEND_NEXT set to true.
107                requestCode = 1;
108                intent.putExtra(SmsReceiverService.EXTRA_MESSAGE_SENT_SEND_NEXT, true);
109            }
110            if (LogTag.DEBUG_SEND) {
111                Log.v(TAG, "sendMessage sendIntent: " + intent);
112            }
113            sentIntents.add(PendingIntent.getBroadcast(mContext, requestCode, intent, 0));
114        }
115        try {
116            smsManager.sendMultipartTextMessage(mDest, mServiceCenter, messages, sentIntents, deliveryIntents);
117        } catch (Exception ex) {
118            Log.e(TAG, "SmsMessageSender.sendMessage: caught", ex);
119            throw new MmsException("SmsMessageSender.sendMessage: caught " + ex +
120                    " from SmsManager.sendTextMessage()");
121        }
122        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) {
123            log("sendMessage: address=" + mDest + ", threadId=" + mThreadId +
124                    ", uri=" + mUri + ", msgs.count=" + messageCount);
125        }
126        return false;
127    }
128
129    private void log(String msg) {
130        Log.d(LogTag.TAG, "[SmsSingleRecipientSender] " + msg);
131    }
132}
133