use of com.google.android.mms.pdu.SendReq in project android-aosp-mms by slvn.
the class ComposeMessageActivity method forwardMessage.
private void forwardMessage(final MessageItem msgItem) {
mTempThreadId = 0;
// The user wants to forward the message. If the message is an mms message, we need to
// persist the pdu to disk. This is done in a background task.
// If the task takes longer than a half second, a progress dialog is displayed.
// Once the PDU persisting is done, another runnable on the UI thread get executed to start
// the ForwardMessageActivity.
getAsyncDialog().runAsync(new Runnable() {
@Override
public void run() {
// This runnable gets run in a background thread.
if (msgItem.mType.equals("mms")) {
SendReq sendReq = new SendReq();
String subject = getString(R.string.forward_prefix);
if (msgItem.mSubject != null) {
subject += msgItem.mSubject;
}
sendReq.setSubject(new EncodedStringValue(subject));
sendReq.setBody(msgItem.mSlideshow.makeCopy());
mTempMmsUri = null;
try {
PduPersister persister = PduPersister.getPduPersister(ComposeMessageActivity.this);
// Copy the parts of the message here.
mTempMmsUri = persister.persist(sendReq, Mms.Draft.CONTENT_URI, true, MessagingPreferenceActivity.getIsGroupMmsEnabled(ComposeMessageActivity.this), null);
mTempThreadId = MessagingNotification.getThreadId(ComposeMessageActivity.this, mTempMmsUri);
} catch (MmsException e) {
Log.e(TAG, "Failed to copy message: " + msgItem.mMessageUri);
Toast.makeText(ComposeMessageActivity.this, R.string.cannot_save_message, Toast.LENGTH_SHORT).show();
return;
}
}
}
}, new Runnable() {
@Override
public void run() {
// Once the above background thread is complete, this runnable is run
// on the UI thread.
Intent intent = createIntent(ComposeMessageActivity.this, 0);
intent.putExtra(KEY_EXIT_ON_SENT, true);
intent.putExtra(KEY_FORWARDED_MESSAGE, true);
if (mTempThreadId > 0) {
intent.putExtra(THREAD_ID, mTempThreadId);
}
if (msgItem.mType.equals("sms")) {
intent.putExtra("sms_body", msgItem.mBody);
} else {
intent.putExtra("msg_uri", mTempMmsUri);
String subject = getString(R.string.forward_prefix);
if (msgItem.mSubject != null) {
subject += msgItem.mSubject;
}
intent.putExtra("subject", subject);
}
// ForwardMessageActivity is simply an alias in the manifest for
// ComposeMessageActivity. We have to make an alias because ComposeMessageActivity
// launch flags specify singleTop. When we forward a message, we want to start a
// separate ComposeMessageActivity. The only way to do that is to override the
// singleTop flag, which is impossible to do in code. By creating an alias to the
// activity, without the singleTop flag, we can launch a separate
// ComposeMessageActivity to edit the forward message.
intent.setClassName(ComposeMessageActivity.this, "com.android.mms.ui.ForwardMessageActivity");
startActivity(intent);
}
}, R.string.building_slideshow_title);
}
use of com.google.android.mms.pdu.SendReq in project android-aosp-mms by slvn.
the class MessageUtils method getMultimediaMessageDetails.
private static String getMultimediaMessageDetails(Context context, Cursor cursor, int size) {
int type = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_TYPE);
if (type == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) {
return getNotificationIndDetails(context, cursor);
}
StringBuilder details = new StringBuilder();
Resources res = context.getResources();
long id = cursor.getLong(MessageListAdapter.COLUMN_ID);
Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, id);
MultimediaMessagePdu msg;
try {
msg = (MultimediaMessagePdu) PduPersister.getPduPersister(context).load(uri);
} catch (MmsException e) {
Log.e(TAG, "Failed to load the message: " + uri, e);
return context.getResources().getString(R.string.cannot_get_details);
}
// Message Type: Text message.
details.append(res.getString(R.string.message_type_label));
details.append(res.getString(R.string.multimedia_message));
if (msg instanceof RetrieveConf) {
// From: ***
String from = extractEncStr(context, ((RetrieveConf) msg).getFrom());
details.append('\n');
details.append(res.getString(R.string.from_label));
details.append(!TextUtils.isEmpty(from) ? from : res.getString(R.string.hidden_sender_address));
}
// To: ***
details.append('\n');
details.append(res.getString(R.string.to_address_label));
EncodedStringValue[] to = msg.getTo();
if (to != null) {
details.append(EncodedStringValue.concat(to));
} else {
Log.w(TAG, "recipient list is empty!");
}
// Bcc: ***
if (msg instanceof SendReq) {
EncodedStringValue[] values = ((SendReq) msg).getBcc();
if ((values != null) && (values.length > 0)) {
details.append('\n');
details.append(res.getString(R.string.bcc_label));
details.append(EncodedStringValue.concat(values));
}
}
// Date: ***
details.append('\n');
int msgBox = cursor.getInt(MessageListAdapter.COLUMN_MMS_MESSAGE_BOX);
if (msgBox == Mms.MESSAGE_BOX_DRAFTS) {
details.append(res.getString(R.string.saved_label));
} else if (msgBox == Mms.MESSAGE_BOX_INBOX) {
details.append(res.getString(R.string.received_label));
} else {
details.append(res.getString(R.string.sent_label));
}
details.append(MessageUtils.formatTimeStampString(context, msg.getDate() * 1000L, true));
// Subject: ***
details.append('\n');
details.append(res.getString(R.string.subject_label));
EncodedStringValue subject = msg.getSubject();
if (subject != null) {
String subStr = subject.getString();
// Message size should include size of subject.
size += subStr.length();
details.append(subStr);
}
// Priority: High/Normal/Low
details.append('\n');
details.append(res.getString(R.string.priority_label));
details.append(getPriorityDescription(context, msg.getPriority()));
// Message size: *** KB
details.append('\n');
details.append(res.getString(R.string.message_size_label));
details.append((size - 1) / 1000 + 1);
details.append(" KB");
return details.toString();
}
use of com.google.android.mms.pdu.SendReq in project android-aosp-mms by slvn.
the class SendTransaction method run.
public void run() {
try {
RateController rateCtlr = RateController.getInstance();
if (rateCtlr.isLimitSurpassed() && !rateCtlr.isAllowedByUser()) {
Log.e(TAG, "Sending rate limit surpassed.");
return;
}
// Load M-Send.req from outbox
PduPersister persister = PduPersister.getPduPersister(mContext);
SendReq sendReq = (SendReq) persister.load(mSendReqURI);
// Update the 'date' field of the PDU right before sending it.
long date = System.currentTimeMillis() / 1000L;
sendReq.setDate(date);
// Persist the new date value into database.
ContentValues values = new ContentValues(1);
values.put(Mms.DATE, date);
SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null);
// fix bug 2100169: insert the 'from' address per spec
String lineNumber = MessageUtils.getLocalNumber();
if (!TextUtils.isEmpty(lineNumber)) {
sendReq.setFrom(new EncodedStringValue(lineNumber));
}
// Pack M-Send.req, send it, retrieve confirmation data, and parse it
long tokenKey = ContentUris.parseId(mSendReqURI);
byte[] response = sendPdu(SendingProgressTokenManager.get(tokenKey), new PduComposer(mContext, sendReq).make());
SendingProgressTokenManager.remove(tokenKey);
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
String respStr = new String(response);
Log.d(TAG, "[SendTransaction] run: send mms msg (" + mId + "), resp=" + respStr);
}
SendConf conf = (SendConf) new PduParser(response).parse();
if (conf == null) {
Log.e(TAG, "No M-Send.conf received.");
}
// Check whether the responding Transaction-ID is consistent
// with the sent one.
byte[] reqId = sendReq.getTransactionId();
byte[] confId = conf.getTransactionId();
if (!Arrays.equals(reqId, confId)) {
Log.e(TAG, "Inconsistent Transaction-ID: req=" + new String(reqId) + ", conf=" + new String(confId));
return;
}
// From now on, we won't save the whole M-Send.conf into
// our database. Instead, we just save some interesting fields
// into the related M-Send.req.
values = new ContentValues(2);
int respStatus = conf.getResponseStatus();
values.put(Mms.RESPONSE_STATUS, respStatus);
if (respStatus != PduHeaders.RESPONSE_STATUS_OK) {
SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null);
Log.e(TAG, "Server returned an error code: " + respStatus);
return;
}
String messageId = PduPersister.toIsoString(conf.getMessageId());
values.put(Mms.MESSAGE_ID, messageId);
SqliteWrapper.update(mContext, mContext.getContentResolver(), mSendReqURI, values, null, null);
// Move M-Send.req from Outbox into Sent.
Uri uri = persister.move(mSendReqURI, Sent.CONTENT_URI);
mTransactionState.setState(TransactionState.SUCCESS);
mTransactionState.setContentUri(uri);
} catch (Throwable t) {
Log.e(TAG, Log.getStackTraceString(t));
} finally {
if (mTransactionState.getState() != TransactionState.SUCCESS) {
mTransactionState.setState(TransactionState.FAILED);
mTransactionState.setContentUri(mSendReqURI);
Log.e(TAG, "Delivery failed.");
}
notifyObservers();
}
}
use of com.google.android.mms.pdu.SendReq in project android-aosp-mms by slvn.
the class MmsMessageSender method sendMessage.
public boolean sendMessage(long token) throws MmsException {
// Load the MMS from the message uri
if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
LogTag.debug("sendMessage uri: " + mMessageUri);
}
PduPersister p = PduPersister.getPduPersister(mContext);
GenericPdu pdu = p.load(mMessageUri);
if (pdu.getMessageType() != PduHeaders.MESSAGE_TYPE_SEND_REQ) {
throw new MmsException("Invalid message: " + pdu.getMessageType());
}
SendReq sendReq = (SendReq) pdu;
// Update headers.
updatePreferencesHeaders(sendReq);
// MessageClass.
sendReq.setMessageClass(DEFAULT_MESSAGE_CLASS.getBytes());
// Update the 'date' field of the message before sending it.
sendReq.setDate(System.currentTimeMillis() / 1000L);
sendReq.setMessageSize(mMessageSize);
p.updateHeaders(mMessageUri, sendReq);
long messageId = ContentUris.parseId(mMessageUri);
// Move the message into MMS Outbox.
if (!mMessageUri.toString().startsWith(Mms.Draft.CONTENT_URI.toString())) {
// If the message is already in the outbox (most likely because we created a "primed"
// message in the outbox when the user hit send), then we have to manually put an
// entry in the pending_msgs table which is where TransacationService looks for
// messages to send. Normally, the entry in pending_msgs is created by the trigger:
// insert_mms_pending_on_update, when a message is moved from drafts to the outbox.
ContentValues values = new ContentValues(7);
values.put(PendingMessages.PROTO_TYPE, MmsSms.MMS_PROTO);
values.put(PendingMessages.MSG_ID, messageId);
values.put(PendingMessages.MSG_TYPE, pdu.getMessageType());
values.put(PendingMessages.ERROR_TYPE, 0);
values.put(PendingMessages.ERROR_CODE, 0);
values.put(PendingMessages.RETRY_INDEX, 0);
values.put(PendingMessages.DUE_TIME, 0);
SqliteWrapper.insert(mContext, mContext.getContentResolver(), PendingMessages.CONTENT_URI, values);
} else {
p.move(mMessageUri, Mms.Outbox.CONTENT_URI);
}
// Start MMS transaction service
SendingProgressTokenManager.put(messageId, token);
mContext.startService(new Intent(mContext, TransactionService.class));
return true;
}
use of com.google.android.mms.pdu.SendReq in project android-aosp-mms by slvn.
the class WorkingMessage method send.
/**
* Send this message over the network. Will call back with onMessageSent() once
* it has been dispatched to the telephony stack. This WorkingMessage object is
* no longer useful after this method has been called.
*
* @throws ContentRestrictionException if sending an MMS and uaProfUrl is not defined
* in mms_config.xml.
*/
public void send(final String recipientsInUI) {
long origThreadId = mConversation.getThreadId();
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
LogTag.debug("send origThreadId: " + origThreadId);
}
removeSubjectIfEmpty(true);
// Get ready to write to disk.
prepareForSave(true);
// We need the recipient list for both SMS and MMS.
final Conversation conv = mConversation;
String msgTxt = mText.toString();
if (requiresMms() || addressContainsEmailToMms(conv, msgTxt)) {
// However, SMS service will still work in the absence of a uaProfUrl address.
if (MmsConfig.getUaProfUrl() == null) {
String err = "WorkingMessage.send MMS sending failure. mms_config.xml is " + "missing uaProfUrl setting. uaProfUrl is required for MMS service, " + "but can be absent for SMS.";
RuntimeException ex = new NullPointerException(err);
Log.e(TAG, err, ex);
// now, let's just crash.
throw ex;
}
// Make local copies of the bits we need for sending a message,
// because we will be doing it off of the main thread, which will
// immediately continue on to resetting some of this state.
final Uri mmsUri = mMessageUri;
final PduPersister persister = PduPersister.getPduPersister(mActivity);
final SlideshowModel slideshow = mSlideshow;
final CharSequence subject = mSubject;
final boolean textOnly = mAttachmentType == TEXT;
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
LogTag.debug("Send mmsUri: " + mmsUri);
}
// Do the dirty work of sending the message off of the main UI thread.
new Thread(new Runnable() {
@Override
public void run() {
final SendReq sendReq = makeSendReq(conv, subject);
// Make sure the text in slide 0 is no longer holding onto a reference to
// the text in the message text box.
slideshow.prepareForSend();
sendMmsWorker(conv, mmsUri, persister, slideshow, sendReq, textOnly);
updateSendStats(conv);
}
}, "WorkingMessage.send MMS").start();
} else {
// Same rules apply as above.
final String msgText = mText.toString();
new Thread(new Runnable() {
@Override
public void run() {
preSendSmsWorker(conv, msgText, recipientsInUI);
updateSendStats(conv);
}
}, "WorkingMessage.send SMS").start();
}
// update the Recipient cache with the new to address, if it's different
RecipientIdCache.updateNumbers(conv.getThreadId(), conv.getRecipients());
// Mark the message as discarded because it is "off the market" after being sent.
mDiscarded = true;
}
Aggregations