Search in sources :

Example 6 with RetrieveConf

use of com.google.android.mms.pdu_alt.RetrieveConf in project qksms by moezbhatti.

the class MessageUtils method getMultimediaMessageDetails.

private static String getMultimediaMessageDetails(Context context, Cursor cursor, int size) {
    int type = cursor.getInt(MessageColumns.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(MessageColumns.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\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\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\n");
            details.append(res.getString(R.string.bcc_label));
            details.append(EncodedStringValue.concat(values));
        }
    }
    // Date: ***
    details.append("\n\n");
    int msgBox = cursor.getInt(MessageColumns.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\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\n");
    details.append(res.getString(R.string.priority_label));
    details.append(getPriorityDescription(context, msg.getPriority()));
    // Message size: *** KB
    details.append("\n\n");
    details.append(res.getString(R.string.message_size_label));
    details.append((size - 1) / 1000 + 1);
    details.append(" KB");
    return details.toString();
}
Also used : MmsException(com.google.android.mms.MmsException) EncodedStringValue(com.google.android.mms.pdu_alt.EncodedStringValue) MultimediaMessagePdu(com.google.android.mms.pdu_alt.MultimediaMessagePdu) Resources(android.content.res.Resources) Uri(android.net.Uri) SendReq(com.google.android.mms.pdu_alt.SendReq) RetrieveConf(com.google.android.mms.pdu_alt.RetrieveConf)

Example 7 with RetrieveConf

use of com.google.android.mms.pdu_alt.RetrieveConf in project qksms by moezbhatti.

the class MmsReceivedReceiver method getNotificationTask.

private List<CommonAsyncTask> getNotificationTask(Context context, Intent intent, byte[] response) {
    if (response.length == 0) {
        Timber.v("MmsReceivedReceiver.sendNotification blank response");
        return null;
    }
    if (getMmscInfoForReceptionAck() == null) {
        Timber.v("No MMSC information set, so no notification tasks will be able to complete");
        return null;
    }
    final GenericPdu pdu = (new PduParser(response, new MmsConfig.Overridden(new MmsConfig(context), null).getSupportMmsContentDisposition())).parse();
    if (pdu == null || !(pdu instanceof RetrieveConf)) {
        Timber.e("MmsReceivedReceiver.sendNotification failed to parse pdu");
        return null;
    }
    try {
        final NotificationInd ind = getNotificationInd(context, intent);
        final MmscInformation mmsc = getMmscInfoForReceptionAck();
        final TransactionSettings transactionSettings = new TransactionSettings(mmsc.mmscUrl, mmsc.mmsProxy, mmsc.proxyPort);
        final List<CommonAsyncTask> responseTasks = new ArrayList<>();
        responseTasks.add(new AcknowledgeIndTask(context, ind, transactionSettings, (RetrieveConf) pdu));
        responseTasks.add(new NotifyRespTask(context, ind, transactionSettings));
        return responseTasks;
    } catch (MmsException e) {
        Timber.e(e, "error");
        return null;
    }
}
Also used : PduParser(com.google.android.mms.pdu_alt.PduParser) NotificationInd(com.google.android.mms.pdu_alt.NotificationInd) ArrayList(java.util.ArrayList) MmsException(com.google.android.mms.MmsException) MmsConfig(com.android.mms.service_alt.MmsConfig) TransactionSettings(com.android.mms.transaction.TransactionSettings) GenericPdu(com.google.android.mms.pdu_alt.GenericPdu) RetrieveConf(com.google.android.mms.pdu_alt.RetrieveConf)

Example 8 with RetrieveConf

use of com.google.android.mms.pdu_alt.RetrieveConf in project qksms by moezbhatti.

the class NotificationTransaction method run.

public void run() {
    try {
        Looper.prepare();
    } catch (Exception e) {
    }
    DownloadManager.init(mContext);
    DownloadManager downloadManager = DownloadManager.getInstance();
    boolean autoDownload = allowAutoDownload(mContext);
    try {
        if (LOCAL_LOGV) {
            Timber.v("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;
        // Don't try to download when data is suspended, as it will fail, so defer download
        if (!autoDownload) {
            downloadManager.markState(mUri, DownloadManager.STATE_UNSTARTED);
            sendNotifyRespInd(status);
            return;
        }
        downloadManager.markState(mUri, DownloadManager.STATE_DOWNLOADING);
        if (LOCAL_LOGV) {
            Timber.v("Content-Location: " + mContentLocation);
        }
        byte[] retrieveConfData = null;
        // with STATUS_DEFERRED.
        try {
            retrieveConfData = getPdu(mContentLocation);
        } catch (IOException e) {
            mTransactionState.setState(FAILED);
        }
        if (retrieveConfData != null) {
            GenericPdu pdu = new PduParser(retrieveConfData).parse();
            if ((pdu == null) || (pdu.getMessageType() != MESSAGE_TYPE_RETRIEVE_CONF)) {
                Timber.e("Invalid M-RETRIEVE.CONF PDU. " + (pdu != null ? "message type: " + pdu.getMessageType() : "null 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, PduPersister.DUMMY_THREAD_ID, true, true, null);
                RetrieveConf retrieveConf = (RetrieveConf) pdu;
                // Use local time instead of PDU time
                ContentValues values = new ContentValues(2);
                values.put(Mms.DATE, System.currentTimeMillis() / 1000L);
                try {
                    values.put(Mms.DATE_SENT, retrieveConf.getDate());
                } catch (Exception ignored) {
                }
                SqliteWrapper.update(mContext, mContext.getContentResolver(), uri, values, null, null);
                // We have successfully downloaded the new MM. Delete the
                // M-NotifyResp.ind from Inbox.
                SqliteWrapper.delete(mContext, mContext.getContentResolver(), mUri, null, null);
                Timber.v("NotificationTransaction received new mms message: " + uri);
                // Delete obsolete threads
                SqliteWrapper.delete(mContext, mContext.getContentResolver(), Threads.OBSOLETE_THREADS_URI, null, null);
                // Notify observers with newly received MM.
                mUri = uri;
                status = STATUS_RETRIEVED;
                BroadcastUtils.sendExplicitBroadcast(mContext, new Intent(), com.klinker.android.send_message.Transaction.NOTIFY_OF_MMS);
            }
        }
        if (LOCAL_LOGV) {
            Timber.v("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) {
        Timber.e(t, "error");
    } 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);
            Timber.e("NotificationTransaction failed.");
        }
        notifyObservers();
    }
}
Also used : ContentValues(android.content.ContentValues) PduParser(com.google.android.mms.pdu_alt.PduParser) PduPersister(com.google.android.mms.pdu_alt.PduPersister) Intent(android.content.Intent) IOException(java.io.IOException) DownloadManager(com.android.mms.util.DownloadManager) Uri(android.net.Uri) MmsException(com.google.android.mms.MmsException) IOException(java.io.IOException) GenericPdu(com.google.android.mms.pdu_alt.GenericPdu) RetrieveConf(com.google.android.mms.pdu_alt.RetrieveConf)

Example 9 with RetrieveConf

use of com.google.android.mms.pdu_alt.RetrieveConf in project qksms by moezbhatti.

the class DownloadRequest method persist.

public static Uri persist(Context context, byte[] response, MmsConfig.Overridden mmsConfig, String locationUrl, int subId, String creator) {
    // Let any mms apps running as secondary user know that a new mms has been downloaded.
    notifyOfDownload(context);
    Timber.d("DownloadRequest.persistIfRequired");
    if (response == null || response.length < 1) {
        Timber.e("DownloadRequest.persistIfRequired: empty response");
        // Update the retrieve status of the NotificationInd
        final ContentValues values = new ContentValues(1);
        values.put(Telephony.Mms.RETRIEVE_STATUS, PduHeaders.RETRIEVE_STATUS_ERROR_END);
        SqliteWrapper.update(context, context.getContentResolver(), Telephony.Mms.CONTENT_URI, values, LOCATION_SELECTION, new String[] { Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND), locationUrl });
        return null;
    }
    final long identity = Binder.clearCallingIdentity();
    try {
        final GenericPdu pdu = (new PduParser(response, mmsConfig.getSupportMmsContentDisposition())).parse();
        if (pdu == null || !(pdu instanceof RetrieveConf)) {
            Timber.e("DownloadRequest.persistIfRequired: invalid parsed PDU");
            // Update the error type of the NotificationInd
            setErrorType(context, locationUrl, Telephony.MmsSms.ERR_TYPE_MMS_PROTO_PERMANENT);
            return null;
        }
        final RetrieveConf retrieveConf = (RetrieveConf) pdu;
        final int status = retrieveConf.getRetrieveStatus();
        // if (status != PduHeaders.RETRIEVE_STATUS_OK) {
        // Timber.e("DownloadRequest.persistIfRequired: retrieve failed "
        // + status);
        // // Update the retrieve status of the NotificationInd
        // final ContentValues values = new ContentValues(1);
        // values.put(Telephony.Mms.RETRIEVE_STATUS, status);
        // SqliteWrapper.update(
        // context,
        // context.getContentResolver(),
        // Telephony.Mms.CONTENT_URI,
        // values,
        // LOCATION_SELECTION,
        // new String[]{
        // Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND),
        // mLocationUrl
        // });
        // return null;
        // }
        // Store the downloaded message
        final PduPersister persister = PduPersister.getPduPersister(context);
        final Uri messageUri = persister.persist(pdu, Telephony.Mms.Inbox.CONTENT_URI, PduPersister.DUMMY_THREAD_ID, true, true, null);
        if (messageUri == null) {
            Timber.e("DownloadRequest.persistIfRequired: can not persist message");
            return null;
        }
        // Update some of the properties of the message
        final ContentValues values = new ContentValues();
        values.put(Telephony.Mms.DATE, System.currentTimeMillis() / 1000L);
        try {
            values.put(Telephony.Mms.DATE_SENT, retrieveConf.getDate());
        } catch (Exception ignored) {
        }
        values.put(Telephony.Mms.READ, 0);
        values.put(Telephony.Mms.SEEN, 0);
        if (!TextUtils.isEmpty(creator)) {
            values.put(Telephony.Mms.CREATOR, creator);
        }
        if (SubscriptionIdChecker.getInstance(context).canUseSubscriptionId()) {
            values.put(Telephony.Mms.SUBSCRIPTION_ID, subId);
        }
        try {
            context.getContentResolver().update(messageUri, values, null, null);
        } catch (SQLiteException e) {
            // in advance that it will fail, and we have to just try again
            if (values.containsKey(Telephony.Mms.SUBSCRIPTION_ID)) {
                values.remove(Telephony.Mms.SUBSCRIPTION_ID);
                context.getContentResolver().update(messageUri, values, null, null);
            } else {
                throw e;
            }
        }
        // Delete the corresponding NotificationInd
        SqliteWrapper.delete(context, context.getContentResolver(), Telephony.Mms.CONTENT_URI, LOCATION_SELECTION, new String[] { Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND), locationUrl });
        return messageUri;
    } catch (MmsException e) {
        Timber.e(e, "DownloadRequest.persistIfRequired: can not persist message");
    } catch (SQLiteException e) {
        Timber.e(e, "DownloadRequest.persistIfRequired: can not update message");
    } catch (RuntimeException e) {
        Timber.e(e, "DownloadRequest.persistIfRequired: can not parse response");
    } finally {
        Binder.restoreCallingIdentity(identity);
    }
    return null;
}
Also used : ContentValues(android.content.ContentValues) PduParser(com.google.android.mms.pdu_alt.PduParser) MmsException(com.google.android.mms.MmsException) PduPersister(com.google.android.mms.pdu_alt.PduPersister) GenericPdu(com.google.android.mms.pdu_alt.GenericPdu) SQLiteException(android.database.sqlite.SQLiteException) Uri(android.net.Uri) RetrieveConf(com.google.android.mms.pdu_alt.RetrieveConf) MmsException(com.google.android.mms.MmsException) MmsHttpException(com.android.mms.service_alt.exception.MmsHttpException) SQLiteException(android.database.sqlite.SQLiteException)

Example 10 with RetrieveConf

use of com.google.android.mms.pdu_alt.RetrieveConf in project Signal-Android by WhisperSystems.

the class MmsDownloadJob method onRun.

@Override
public void onRun() {
    if (SignalStore.account().getE164() == null) {
        throw new NotReadyException();
    }
    MessageDatabase database = SignalDatabase.mms();
    Optional<MmsDatabase.MmsNotificationInfo> notification = database.getNotification(messageId);
    if (!notification.isPresent()) {
        Log.w(TAG, "No notification for ID: " + messageId);
        return;
    }
    try {
        if (notification.get().getContentLocation() == null) {
            throw new MmsException("Notification content location was null.");
        }
        if (!SignalStore.account().isRegistered()) {
            throw new MmsException("Not registered");
        }
        database.markDownloadState(messageId, MmsDatabase.Status.DOWNLOAD_CONNECTING);
        String contentLocation = notification.get().getContentLocation();
        byte[] transactionId = new byte[0];
        try {
            if (notification.get().getTransactionId() != null) {
                transactionId = notification.get().getTransactionId().getBytes(CharacterSets.MIMENAME_ISO_8859_1);
            } else {
                Log.w(TAG, "No transaction ID!");
            }
        } catch (UnsupportedEncodingException e) {
            Log.w(TAG, e);
        }
        Log.i(TAG, "Downloading mms at " + Uri.parse(contentLocation).getHost() + ", subscription ID: " + notification.get().getSubscriptionId());
        RetrieveConf retrieveConf = new CompatMmsConnection(context).retrieve(contentLocation, transactionId, notification.get().getSubscriptionId());
        if (retrieveConf == null) {
            throw new MmsException("RetrieveConf was null");
        }
        storeRetrievedMms(contentLocation, messageId, threadId, retrieveConf, notification.get().getSubscriptionId(), notification.get().getFrom());
    } catch (ApnUnavailableException e) {
        Log.w(TAG, e);
        handleDownloadError(messageId, threadId, MmsDatabase.Status.DOWNLOAD_APN_UNAVAILABLE, automatic);
    } catch (MmsException e) {
        Log.w(TAG, e);
        handleDownloadError(messageId, threadId, MmsDatabase.Status.DOWNLOAD_HARD_FAILURE, automatic);
    } catch (MmsRadioException | IOException e) {
        Log.w(TAG, e);
        handleDownloadError(messageId, threadId, MmsDatabase.Status.DOWNLOAD_SOFT_FAILURE, automatic);
    }
}
Also used : MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) CompatMmsConnection(org.thoughtcrime.securesms.mms.CompatMmsConnection) MmsException(org.thoughtcrime.securesms.mms.MmsException) ApnUnavailableException(org.thoughtcrime.securesms.mms.ApnUnavailableException) MmsRadioException(org.thoughtcrime.securesms.mms.MmsRadioException) RetrieveConf(com.google.android.mms.pdu_alt.RetrieveConf)

Aggregations

RetrieveConf (com.google.android.mms.pdu_alt.RetrieveConf)11 PduParser (com.google.android.mms.pdu_alt.PduParser)8 IOException (java.io.IOException)8 MmsException (com.google.android.mms.MmsException)5 Uri (android.net.Uri)4 ContentValues (android.content.ContentValues)3 GenericPdu (com.google.android.mms.pdu_alt.GenericPdu)3 PduPersister (com.google.android.mms.pdu_alt.PduPersister)3 TargetApi (android.annotation.TargetApi)2 SmsManager (android.telephony.SmsManager)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 TimeoutException (java.util.concurrent.TimeoutException)2 ApnUnavailableException (org.thoughtcrime.securesms.mms.ApnUnavailableException)2 CompatMmsConnection (org.thoughtcrime.securesms.mms.CompatMmsConnection)2 MmsException (org.thoughtcrime.securesms.mms.MmsException)2 MmsRadioException (org.thoughtcrime.securesms.mms.MmsRadioException)2 MmsBodyProvider (org.thoughtcrime.securesms.providers.MmsBodyProvider)2 Intent (android.content.Intent)1 Resources (android.content.res.Resources)1