/** * Find all messages to be sent or downloaded before certain time. */ public Cursor getPendingMessages(long dueTime) { Uri.Builder uriBuilder = MessageDAO.MMS_PENDING_URI.buildUpon(); uriBuilder.appendQueryParameter("protocol", "mms"); String selection = PendingMessages.ERROR_TYPE + " < ?" + " AND " + PendingMessages.DUE_TIME + " <= ?"; String[] selectionArgs = new String[] { String.valueOf(MmsSms.ERR_TYPE_GENERIC_PERMANENT), String.valueOf(dueTime) }; return SqliteWrapper.query(mContext, mContentResolver, uriBuilder.build(), null, selection, selectionArgs, PendingMessages.DUE_TIME); }
private void markMmsFailedToSend(Context context, Uri msgUri) { // https://github.com/qklabs/aosp-messenger/blob/master/src/com/android/mms/data/WorkingMessage.java#L1476-1476 try { PduPersister p = PduPersister.getPduPersister(context); // Move the message into MMS Outbox. A trigger will create an entry in // the "pending_msgs" table. p.move(msgUri, Telephony.Mms.Outbox.CONTENT_URI); // Now update the pending_msgs table with an error for that new item. ContentValues values = new ContentValues(1); values.put(Telephony.MmsSms.PendingMessages.ERROR_TYPE, Telephony.MmsSms.ERR_TYPE_GENERIC_PERMANENT); long msgId = ContentUris.parseId(msgUri); SqliteWrapper.update(context, mContentResolver, Telephony.MmsSms.PendingMessages.CONTENT_URI, values, Telephony.MmsSms.PendingMessages.MSG_ID + "=" + msgId, null); } catch (MmsException e) { // Not much we can do here. If the p.move throws an exception, we'll just // leave the message in the draft box. Log.e(TAG, "Failed to move message to outbox and mark as error: " + msgUri, e); } }
/** * Check for locked messages in all threads or a specified thread. * * @param handler An AsyncQueryHandler that will receive onQueryComplete * upon completion of looking for locked messages * @param threadIds A list of threads to search. null means all threads * @param token The token that will be passed to onQueryComplete */ public static void startQueryHaveLockedMessages(AsyncQueryHandler handler, Collection<Long> threadIds, int token) { handler.cancelOperation(token); Uri uri = MmsSms.CONTENT_LOCKED_URI; String selection = null; if (threadIds != null) { StringBuilder buf = new StringBuilder(); int i = 0; for (long threadId : threadIds) { if (i++ > 0) { buf.append(" OR "); } // We have to build the selection arg into the selection because deep down in // provider, the function buildUnionSubQuery takes selectionArgs, but ignores it. buf.append(Mms.THREAD_ID).append("=").append(Long.toString(threadId)); } selection = buf.toString(); } handler.startQuery(token, threadIds, uri, ALL_THREADS_PROJECTION, selection, null, Conversations.DEFAULT_SORT_ORDER); }
private void markMmsMessageWithError(Uri mmsUri) { try { PduPersister p = PduPersister.getPduPersister(mActivity); // Move the message into MMS Outbox. A trigger will create an entry // in // the "pending_msgs" table. p.move(mmsUri, Mms.Outbox.CONTENT_URI); // Now update the pending_msgs table with an error for that new // item. ContentValues values = new ContentValues(1); values.put(PendingMessages.ERROR_TYPE, MmsSms.ERR_TYPE_GENERIC_PERMANENT); long msgId = ContentUris.parseId(mmsUri); SqliteWrapper.update(mActivity, mContentResolver, PendingMessages.CONTENT_URI, values, PendingMessages.MSG_ID + "=" + msgId, null); } catch (MmsException e) { // Not much we can do here. If the p.move throws an exception, we'll // just // leave the message in the draft box. Log.e(TAG, "Failed to move message to outbox and mark as error: " + mmsUri, e); } }
/** * Check for locked messages in all threads or a specified thread. * @param handler An AsyncQueryHandler that will receive onQueryComplete * upon completion of looking for locked messages * @param threadIds A list of threads to search. null means all threads * @param token The token that will be passed to onQueryComplete */ public static void startQueryHaveLockedMessages(AsyncQueryHandler handler, Collection<Long> threadIds, int token) { handler.cancelOperation(token); Uri uri = MmsSms.CONTENT_LOCKED_URI; String selection = null; if (threadIds != null) { StringBuilder buf = new StringBuilder(); int i = 0; for (long threadId : threadIds) { if (i++ > 0) { buf.append(" OR "); } // We have to build the selection arg into the selection because deep down in // provider, the function buildUnionSubQuery takes selectionArgs, but ignores it. buf.append(Mms.THREAD_ID).append("=").append(Long.toString(threadId)); } selection = buf.toString(); } handler.startQuery(token, threadIds, uri, ALL_THREADS_PROJECTION, selection, null, Conversations.DEFAULT_SORT_ORDER); }
private void markMmsMessageWithError(Uri mmsUri) { try { PduPersister p = PduPersister.getPduPersister(mActivity); // Move the message into MMS Outbox. A trigger will create an entry in // the "pending_msgs" table. p.move(mmsUri, Mms.Outbox.CONTENT_URI); // Now update the pending_msgs table with an error for that new item. ContentValues values = new ContentValues(1); values.put(PendingMessages.ERROR_TYPE, MmsSms.ERR_TYPE_GENERIC_PERMANENT); long msgId = ContentUris.parseId(mmsUri); SqliteWrapper.update(mActivity, mContentResolver, PendingMessages.CONTENT_URI, values, PendingMessages.MSG_ID + "=" + msgId, null); } catch (MmsException e) { // Not much we can do here. If the p.move throws an exception, we'll just // leave the message in the draft box. Log.e(TAG, "Failed to move message to outbox and mark as error: " + mmsUri, e); } }
@TargetApi(19) public void start(Context context) { this.context = context; this.listeners = new ArrayList(); this.pendingMessages = new ArrayList(); this.mmsDownloadedReceiver = null; this.mmsContentObserver = null; this.mmsContentObserver = new MmsContentObserver(new Handler(Looper.getMainLooper())); context.getContentResolver().registerContentObserver(MmsSms.CONTENT_URI, true, this.mmsContentObserver); this.lastMessageId = -1; loadLastMessageId(); }
public boolean isFailedMessage() { boolean isFailedMms = isMms() && (mErrorType >= MmsSms.ERR_TYPE_GENERIC_PERMANENT); boolean isFailedSms = isSms() && (mBoxId == Sms.MESSAGE_TYPE_FAILED); return isFailedMms || isFailedSms; }
/** * Find all messages to be sent or downloaded before certain time. */ public Cursor getPendingMessages(long dueTime) { Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon(); uriBuilder.appendQueryParameter("protocol", "mms"); String selection = PendingMessages.ERROR_TYPE + " < ?" + " AND " + PendingMessages.DUE_TIME + " <= ?"; String[] selectionArgs = new String[] { String.valueOf(MmsSms.ERR_TYPE_GENERIC_PERMANENT), String.valueOf(dueTime) }; return mContentResolver.query( uriBuilder.build(), null, selection, selectionArgs, PendingMessages.DUE_TIME); }
/** * Check for locked messages in all threads or a specified thread. * * @param handler * An AsyncQueryHandler that will receive onQueryComplete upon * completion of looking for locked messages * @param threadIds * A list of threads to search. null means all threads * @param token * The token that will be passed to onQueryComplete */ public static void startQueryHaveLockedMessages(AsyncQueryHandler handler, Collection<Long> threadIds, int token) { handler.cancelOperation(token); Uri uri = MmsSms.CONTENT_LOCKED_URI; String selection = null; if (threadIds != null) { StringBuilder buf = new StringBuilder(); int i = 0; for (long threadId : threadIds) { if (i++ > 0) { buf.append(" OR "); } // We have to build the selection arg into the selection because // deep down in // provider, the function buildUnionSubQuery takes // selectionArgs, but ignores it. buf.append(Mms.THREAD_ID).append("=") .append(Long.toString(threadId)); } selection = buf.toString(); } handler.startQuery(token, threadIds, uri, ALL_THREADS_PROJECTION, selection, null, Conversations.DEFAULT_SORT_ORDER); }
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); if (MultiSimConfig.isMultiSimEnabled()) { Intent intent = new Intent(mContext, TransactionService.class); intent.putExtra(Mms.SUB_ID, ComposeMessageActivity.subSelected); Intent silentIntent = new Intent(mContext, edu.bupt.mms.ui.SelectMmsSubscription.class); silentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); silentIntent.putExtras(intent); //copy all extras mContext.startService(silentIntent); } else { mContext.startService(new Intent(mContext, TransactionService.class)); } return true; }
private static boolean isTransientFailure(int type) { return (type < MmsSms.ERR_TYPE_GENERIC_PERMANENT) && (type > MmsSms.NO_ERROR); }
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; }
private static boolean isTransientFailure(int type) { return type > MmsSms.NO_ERROR && type < MmsSms.ERR_TYPE_GENERIC_PERMANENT; }