• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Esmertec AG.
3  * Copyright (C) 2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.mms.transaction;
19 
20 import android.content.ContentUris;
21 import android.content.ContentValues;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.SharedPreferences;
25 import android.net.Uri;
26 import android.preference.PreferenceManager;
27 import android.provider.Telephony.Mms;
28 import android.provider.Telephony.MmsSms;
29 import android.provider.Telephony.MmsSms.PendingMessages;
30 import android.util.Log;
31 
32 import com.android.mms.LogTag;
33 import com.android.mms.ui.ComposeMessageActivity;
34 import com.android.mms.ui.MessagingPreferenceActivity;
35 import com.android.mms.util.SendingProgressTokenManager;
36 import com.google.android.mms.InvalidHeaderValueException;
37 import com.google.android.mms.MmsException;
38 import com.google.android.mms.pdu.EncodedStringValue;
39 import com.google.android.mms.pdu.GenericPdu;
40 import com.google.android.mms.pdu.PduHeaders;
41 import com.google.android.mms.pdu.PduPersister;
42 import com.google.android.mms.pdu.ReadRecInd;
43 import com.google.android.mms.pdu.SendReq;
44 import com.google.android.mms.util.SqliteWrapper;
45 
46 public class MmsMessageSender implements MessageSender {
47     private static final String TAG = LogTag.TAG;
48 
49     private final Context mContext;
50     private final Uri mMessageUri;
51     private final long mMessageSize;
52 
53     // Default preference values
54     private static final boolean DEFAULT_DELIVERY_REPORT_MODE  = false;
55     private static final boolean DEFAULT_READ_REPORT_MODE      = false;
56     private static final long    DEFAULT_EXPIRY_TIME     = 7 * 24 * 60 * 60;
57     private static final int     DEFAULT_PRIORITY        = PduHeaders.PRIORITY_NORMAL;
58     private static final String  DEFAULT_MESSAGE_CLASS   = PduHeaders.MESSAGE_CLASS_PERSONAL_STR;
59 
MmsMessageSender(Context context, Uri location, long messageSize)60     public MmsMessageSender(Context context, Uri location, long messageSize) {
61         mContext = context;
62         mMessageUri = location;
63         mMessageSize = messageSize;
64 
65         if (mMessageUri == null) {
66             throw new IllegalArgumentException("Null message URI.");
67         }
68     }
69 
sendMessage(long token)70     public boolean sendMessage(long token) throws MmsException {
71         // Load the MMS from the message uri
72         if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
73             LogTag.debug("sendMessage uri: " + mMessageUri);
74         }
75         PduPersister p = PduPersister.getPduPersister(mContext);
76         GenericPdu pdu = p.load(mMessageUri);
77 
78         if (pdu.getMessageType() != PduHeaders.MESSAGE_TYPE_SEND_REQ) {
79             throw new MmsException("Invalid message: " + pdu.getMessageType());
80         }
81 
82         SendReq sendReq = (SendReq) pdu;
83 
84         // Update headers.
85         updatePreferencesHeaders(sendReq);
86 
87         // MessageClass.
88         sendReq.setMessageClass(DEFAULT_MESSAGE_CLASS.getBytes());
89 
90         // Update the 'date' field of the message before sending it.
91         sendReq.setDate(System.currentTimeMillis() / 1000L);
92 
93         sendReq.setMessageSize(mMessageSize);
94 
95         p.updateHeaders(mMessageUri, sendReq);
96 
97         long messageId = ContentUris.parseId(mMessageUri);
98 
99         // Move the message into MMS Outbox.
100         if (!mMessageUri.toString().startsWith(Mms.Draft.CONTENT_URI.toString())) {
101             // If the message is already in the outbox (most likely because we created a "primed"
102             // message in the outbox when the user hit send), then we have to manually put an
103             // entry in the pending_msgs table which is where TransacationService looks for
104             // messages to send. Normally, the entry in pending_msgs is created by the trigger:
105             // insert_mms_pending_on_update, when a message is moved from drafts to the outbox.
106             ContentValues values = new ContentValues(7);
107 
108             values.put(PendingMessages.PROTO_TYPE, MmsSms.MMS_PROTO);
109             values.put(PendingMessages.MSG_ID, messageId);
110             values.put(PendingMessages.MSG_TYPE, pdu.getMessageType());
111             values.put(PendingMessages.ERROR_TYPE, 0);
112             values.put(PendingMessages.ERROR_CODE, 0);
113             values.put(PendingMessages.RETRY_INDEX, 0);
114             values.put(PendingMessages.DUE_TIME, 0);
115 
116             SqliteWrapper.insert(mContext, mContext.getContentResolver(),
117                     PendingMessages.CONTENT_URI, values);
118         } else {
119             p.move(mMessageUri, Mms.Outbox.CONTENT_URI);
120         }
121 
122         // Start MMS transaction service
123         SendingProgressTokenManager.put(messageId, token);
124         mContext.startService(new Intent(mContext, TransactionService.class));
125 
126         return true;
127     }
128 
129     // Update the headers which are stored in SharedPreferences.
updatePreferencesHeaders(SendReq sendReq)130     private void updatePreferencesHeaders(SendReq sendReq) throws MmsException {
131         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
132 
133         // Expiry.
134         sendReq.setExpiry(prefs.getLong(
135                 MessagingPreferenceActivity.EXPIRY_TIME, DEFAULT_EXPIRY_TIME));
136 
137         // Priority.
138         sendReq.setPriority(prefs.getInt(MessagingPreferenceActivity.PRIORITY, DEFAULT_PRIORITY));
139 
140         // Delivery report.
141         boolean dr = prefs.getBoolean(MessagingPreferenceActivity.MMS_DELIVERY_REPORT_MODE,
142                 DEFAULT_DELIVERY_REPORT_MODE);
143         sendReq.setDeliveryReport(dr?PduHeaders.VALUE_YES:PduHeaders.VALUE_NO);
144 
145         // Read report.
146         boolean rr = prefs.getBoolean(MessagingPreferenceActivity.READ_REPORT_MODE,
147                 DEFAULT_READ_REPORT_MODE);
148         sendReq.setReadReport(rr?PduHeaders.VALUE_YES:PduHeaders.VALUE_NO);
149     }
150 
sendReadRec(Context context, String to, String messageId, int status)151     public static void sendReadRec(Context context, String to, String messageId, int status) {
152         EncodedStringValue[] sender = new EncodedStringValue[1];
153         sender[0] = new EncodedStringValue(to);
154 
155         try {
156             final ReadRecInd readRec = new ReadRecInd(
157                     new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()),
158                     messageId.getBytes(),
159                     PduHeaders.CURRENT_MMS_VERSION,
160                     status,
161                     sender);
162 
163             readRec.setDate(System.currentTimeMillis() / 1000);
164 
165             PduPersister.getPduPersister(context).persist(readRec, Mms.Outbox.CONTENT_URI, true,
166                     MessagingPreferenceActivity.getIsGroupMmsEnabled(context), null);
167             context.startService(new Intent(context, TransactionService.class));
168         } catch (InvalidHeaderValueException e) {
169             Log.e(TAG, "Invalide header value", e);
170         } catch (MmsException e) {
171             Log.e(TAG, "Persist message failed", e);
172         }
173     }
174 }
175