NotificationTransactionpublic class NotificationTransaction extends Transaction implements RunnableThe NotificationTransaction is responsible for handling multimedia
message notifications (M-Notification.ind). It:
- Composes the notification response (M-NotifyResp.ind).
- Sends the notification response to the MMSC server.
- Stores the notification indication.
- Notifies the TransactionService about succesful completion.
NOTE: This MMS client handles all notifications with a deferred
retrieval response. The transaction service, upon succesful
completion of this transaction, will trigger a retrieve transaction
in case the client is in immediate retrieve mode. |
Fields Summary |
---|
private static final String | TAG | private static final boolean | DEBUG | private static final boolean | LOCAL_LOGV | private android.net.Uri | mUri | private com.google.android.mms.pdu.NotificationInd | mNotificationInd |
Constructors Summary |
---|
public NotificationTransaction(android.content.Context context, int serviceId, TransactionSettings connectionSettings, String uriString)
super(context, serviceId, connectionSettings);
mUri = Uri.parse(uriString);
try {
mNotificationInd = (NotificationInd)
PduPersister.getPduPersister(context).load(mUri);
} catch (MmsException e) {
Log.e(TAG, "Failed to load NotificationInd from: " + uriString, e);
throw new IllegalArgumentException();
}
mId = new String(mNotificationInd.getTransactionId());
// Attach the transaction to the instance of RetryScheduler.
attach(RetryScheduler.getInstance(context));
| public NotificationTransaction(android.content.Context context, int serviceId, TransactionSettings connectionSettings, com.google.android.mms.pdu.NotificationInd ind)This constructor is only used for test purposes.
super(context, serviceId, connectionSettings);
try {
mUri = PduPersister.getPduPersister(context).persist(
ind, Inbox.CONTENT_URI);
} catch (MmsException e) {
Log.e(TAG, "Failed to save NotificationInd in constructor.", e);
throw new IllegalArgumentException();
}
mNotificationInd = ind;
mId = new String(ind.getTransactionId());
|
Methods Summary |
---|
public int | getType()
return NOTIFICATION_TRANSACTION;
| public void | process()
new Thread(this).start();
| public void | run()
DownloadManager downloadManager = DownloadManager.getInstance();
boolean autoDownload = downloadManager.isAuto();
try {
if (LOCAL_LOGV) {
Log.v(TAG, "Notification transaction launched: " + this);
}
// By default, we set status to STATUS_DEFERRED because we
// should response MMSC with STATUS_DEFERRED when we cannot
// download a MM immediately.
int status = STATUS_DEFERRED;
if (!autoDownload) {
downloadManager.markState(mUri, DownloadManager.STATE_UNSTARTED);
sendNotifyRespInd(status);
return;
}
downloadManager.markState(mUri, DownloadManager.STATE_DOWNLOADING);
byte[] clBytes = mNotificationInd.getContentLocation();
if (clBytes == null) {
throw new MmsException("Content-Location may not be null.");
}
String contentLocation = new String(clBytes);
if (LOCAL_LOGV) {
Log.v(TAG, "Content-Location: " + contentLocation);
}
byte[] retrieveConfData = null;
// We should catch exceptions here to response MMSC
// with STATUS_DEFERRED.
try {
retrieveConfData = getPdu(contentLocation);
} catch (IOException e) {
mTransactionState.setState(FAILED);
}
if (retrieveConfData != null) {
GenericPdu pdu = new PduParser(retrieveConfData).parse();
if ((pdu == null) || (pdu.getMessageType() != MESSAGE_TYPE_RETRIEVE_CONF)) {
Log.e(TAG, "Invalid M-RETRIEVE.CONF PDU.");
mTransactionState.setState(FAILED);
status = STATUS_UNRECOGNIZED;
} else {
// Save the received PDU (must be a M-RETRIEVE.CONF).
PduPersister p = PduPersister.getPduPersister(mContext);
Uri uri = p.persist(pdu, Inbox.CONTENT_URI);
// We have successfully downloaded the new MM. Delete the
// M-NotifyResp.ind from Inbox.
SqliteWrapper.delete(mContext, mContext.getContentResolver(),
mUri, null, null);
// Notify observers with newly received MM.
mUri = uri;
status = STATUS_RETRIEVED;
}
}
if (LOCAL_LOGV) {
Log.v(TAG, "status=0x" + Integer.toHexString(status));
}
// Check the status and update the result state of this Transaction.
switch (status) {
case STATUS_RETRIEVED:
mTransactionState.setState(SUCCESS);
break;
case STATUS_DEFERRED:
// STATUS_DEFERRED, may be a failed immediate retrieval.
if (mTransactionState.getState() == INITIALIZED) {
mTransactionState.setState(SUCCESS);
}
break;
}
sendNotifyRespInd(status);
} catch (Throwable t) {
Log.e(TAG, Log.getStackTraceString(t));
} finally {
mTransactionState.setContentUri(mUri);
if (!autoDownload) {
// Always mark the transaction successful for deferred
// download since any error here doesn't make sense.
mTransactionState.setState(SUCCESS);
}
if (mTransactionState.getState() != SUCCESS) {
mTransactionState.setState(FAILED);
Log.e(TAG, "NotificationTransaction failed.");
}
notifyObservers();
}
| private void | sendNotifyRespInd(int status)
// Create the M-NotifyResp.ind
NotifyRespInd notifyRespInd = new NotifyRespInd(
PduHeaders.CURRENT_MMS_VERSION,
mNotificationInd.getTransactionId(),
status);
// Pack M-NotifyResp.ind and send it
sendPdu(new PduComposer(mContext, notifyRespInd).make());
|
|