Search in sources :

Example 1 with NotificationInd

use of com.google.android.mms.pdu.NotificationInd in project android-aosp-mms by slvn.

the class MessageUtils method getNotificationIndDetails.

private static String getNotificationIndDetails(Context context, Cursor cursor) {
    StringBuilder details = new StringBuilder();
    Resources res = context.getResources();
    long id = cursor.getLong(MessageListAdapter.COLUMN_ID);
    Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, id);
    NotificationInd nInd;
    try {
        nInd = (NotificationInd) 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: Mms Notification.
    details.append(res.getString(R.string.message_type_label));
    details.append(res.getString(R.string.multimedia_notification));
    // From: ***
    String from = extractEncStr(context, nInd.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));
    // Date: ***
    details.append('\n');
    details.append(res.getString(R.string.expire_on, MessageUtils.formatTimeStampString(context, nInd.getExpiry() * 1000L, true)));
    // Subject: ***
    details.append('\n');
    details.append(res.getString(R.string.subject_label));
    EncodedStringValue subject = nInd.getSubject();
    if (subject != null) {
        details.append(subject.getString());
    }
    // Message class: Personal/Advertisement/Infomational/Auto
    details.append('\n');
    details.append(res.getString(R.string.message_class_label));
    details.append(new String(nInd.getMessageClass()));
    // Message size: *** KB
    details.append('\n');
    details.append(res.getString(R.string.message_size_label));
    details.append(String.valueOf((nInd.getMessageSize() + 1023) / 1024));
    details.append(context.getString(R.string.kilobyte));
    return details.toString();
}
Also used : MmsException(com.google.android.mms.MmsException) EncodedStringValue(com.google.android.mms.pdu.EncodedStringValue) NotificationInd(com.google.android.mms.pdu.NotificationInd) Resources(android.content.res.Resources) Uri(android.net.Uri)

Example 2 with NotificationInd

use of com.google.android.mms.pdu.NotificationInd in project android_frameworks_opt_telephony by LineageOS.

the class WapPushOverSms method writeInboxMessage.

private void writeInboxMessage(int subId, GenericPdu pdu) {
    if (pdu == null) {
        Rlog.e(TAG, "Invalid PUSH PDU");
    }
    final PduPersister persister = PduPersister.getPduPersister(mContext);
    final int type = pdu.getMessageType();
    try {
        switch(type) {
            case MESSAGE_TYPE_DELIVERY_IND:
            case MESSAGE_TYPE_READ_ORIG_IND:
                {
                    final long threadId = getDeliveryOrReadReportThreadId(mContext, pdu);
                    if (threadId == -1) {
                        // The associated SendReq isn't found, therefore skip
                        // processing this PDU.
                        Rlog.e(TAG, "Failed to find delivery or read report's thread id");
                        break;
                    }
                    final Uri uri = persister.persist(pdu, Telephony.Mms.Inbox.CONTENT_URI, true, /*createThreadId*/
                    true, /*groupMmsEnabled*/
                    null);
                    if (uri == null) {
                        Rlog.e(TAG, "Failed to persist delivery or read report");
                        break;
                    }
                    // Update thread ID for ReadOrigInd & DeliveryInd.
                    final ContentValues values = new ContentValues(1);
                    values.put(Telephony.Mms.THREAD_ID, threadId);
                    if (SqliteWrapper.update(mContext, mContext.getContentResolver(), uri, values, null, /*where*/
                    null) != 1) {
                        Rlog.e(TAG, "Failed to update delivery or read report thread id");
                    }
                    break;
                }
            case MESSAGE_TYPE_NOTIFICATION_IND:
                {
                    final NotificationInd nInd = (NotificationInd) pdu;
                    Bundle configs = SmsManager.getSmsManagerForSubscriptionId(subId).getCarrierConfigValues();
                    if (configs != null && configs.getBoolean(SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID, false)) {
                        final byte[] contentLocation = nInd.getContentLocation();
                        if ('=' == contentLocation[contentLocation.length - 1]) {
                            byte[] transactionId = nInd.getTransactionId();
                            byte[] contentLocationWithId = new byte[contentLocation.length + transactionId.length];
                            System.arraycopy(contentLocation, 0, contentLocationWithId, 0, contentLocation.length);
                            System.arraycopy(transactionId, 0, contentLocationWithId, contentLocation.length, transactionId.length);
                            nInd.setContentLocation(contentLocationWithId);
                        }
                    }
                    if (!isDuplicateNotification(mContext, nInd)) {
                        final Uri uri = persister.persist(pdu, Telephony.Mms.Inbox.CONTENT_URI, true, /*createThreadId*/
                        true, /*groupMmsEnabled*/
                        null);
                        if (uri == null) {
                            Rlog.e(TAG, "Failed to save MMS WAP push notification ind");
                        }
                    } else {
                        Rlog.d(TAG, "Skip storing duplicate MMS WAP push notification ind: " + new String(nInd.getContentLocation()));
                    }
                    break;
                }
            default:
                Log.e(TAG, "Received unrecognized WAP Push PDU.");
        }
    } catch (MmsException e) {
        Log.e(TAG, "Failed to save MMS WAP push data: type=" + type, e);
    } catch (RuntimeException e) {
        Log.e(TAG, "Unexpected RuntimeException in persisting MMS WAP push data", e);
    }
}
Also used : ContentValues(android.content.ContentValues) MmsException(com.google.android.mms.MmsException) NotificationInd(com.google.android.mms.pdu.NotificationInd) PduPersister(com.google.android.mms.pdu.PduPersister) Bundle(android.os.Bundle) Uri(android.net.Uri)

Example 3 with NotificationInd

use of com.google.android.mms.pdu.NotificationInd in project android_frameworks_opt_telephony by LineageOS.

the class WapPushOverSms method decodeWapPdu.

/**
 * Decodes the wap push pdu. The decoded result is wrapped inside the {@link DecodedResult}
 * object. The caller of this method should check {@link DecodedResult#statusCode} for the
 * decoding status. It  can have the following values.
 *
 * Activity.RESULT_OK - the wap push pdu is successfully decoded and should be further processed
 * Intents.RESULT_SMS_HANDLED - the wap push pdu should be ignored.
 * Intents.RESULT_SMS_GENERIC_ERROR - the pdu is invalid.
 */
private DecodedResult decodeWapPdu(byte[] pdu, InboundSmsHandler handler) {
    DecodedResult result = new DecodedResult();
    if (DBG)
        Rlog.d(TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
    try {
        int index = 0;
        int transactionId = pdu[index++] & 0xFF;
        int pduType = pdu[index++] & 0xFF;
        // Should we "abort" if no subId for now just no supplying extra param below
        int phoneId = handler.getPhone().getPhoneId();
        if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) && (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
            index = mContext.getResources().getInteger(com.android.internal.R.integer.config_valid_wappush_index);
            if (index != -1) {
                transactionId = pdu[index++] & 0xff;
                pduType = pdu[index++] & 0xff;
                if (DBG)
                    Rlog.d(TAG, "index = " + index + " PDU Type = " + pduType + " transactionID = " + transactionId);
                // recheck wap push pduType
                if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) && (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
                    if (DBG)
                        Rlog.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
                    result.statusCode = Intents.RESULT_SMS_HANDLED;
                    return result;
                }
            } else {
                if (DBG)
                    Rlog.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
                result.statusCode = Intents.RESULT_SMS_HANDLED;
                return result;
            }
        }
        WspTypeDecoder pduDecoder = TelephonyComponentFactory.getInstance().makeWspTypeDecoder(pdu);
        /**
         * Parse HeaderLen(unsigned integer).
         * From wap-230-wsp-20010705-a section 8.1.2
         * The maximum size of a uintvar is 32 bits.
         * So it will be encoded in no more than 5 octets.
         */
        if (pduDecoder.decodeUintvarInteger(index) == false) {
            if (DBG)
                Rlog.w(TAG, "Received PDU. Header Length error.");
            result.statusCode = Intents.RESULT_SMS_GENERIC_ERROR;
            return result;
        }
        int headerLength = (int) pduDecoder.getValue32();
        index += pduDecoder.getDecodedDataLength();
        int headerStartIndex = index;
        /**
         * Parse Content-Type.
         * From wap-230-wsp-20010705-a section 8.4.2.24
         *
         * Content-type-value = Constrained-media | Content-general-form
         * Content-general-form = Value-length Media-type
         * Media-type = (Well-known-media | Extension-Media) *(Parameter)
         * Value-length = Short-length | (Length-quote Length)
         * Short-length = <Any octet 0-30>   (octet <= WAP_PDU_SHORT_LENGTH_MAX)
         * Length-quote = <Octet 31>         (WAP_PDU_LENGTH_QUOTE)
         * Length = Uintvar-integer
         */
        if (pduDecoder.decodeContentType(index) == false) {
            if (DBG)
                Rlog.w(TAG, "Received PDU. Header Content-Type error.");
            result.statusCode = Intents.RESULT_SMS_GENERIC_ERROR;
            return result;
        }
        String mimeType = pduDecoder.getValueString();
        long binaryContentType = pduDecoder.getValue32();
        index += pduDecoder.getDecodedDataLength();
        byte[] header = new byte[headerLength];
        System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
        byte[] intentData;
        if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
            intentData = pdu;
        } else {
            int dataIndex = headerStartIndex + headerLength;
            intentData = new byte[pdu.length - dataIndex];
            System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
        }
        int[] subIds = SubscriptionManager.getSubId(phoneId);
        int subId = (subIds != null) && (subIds.length > 0) ? subIds[0] : SmsManager.getDefaultSmsSubscriptionId();
        // Continue if PDU parsing fails: the default messaging app may successfully parse the
        // same PDU.
        GenericPdu parsedPdu = null;
        try {
            parsedPdu = new PduParser(intentData, shouldParseContentDisposition(subId)).parse();
        } catch (Exception e) {
            Rlog.e(TAG, "Unable to parse PDU: " + e.toString());
        }
        if (parsedPdu != null && parsedPdu.getMessageType() == MESSAGE_TYPE_NOTIFICATION_IND) {
            final NotificationInd nInd = (NotificationInd) parsedPdu;
            if (nInd.getFrom() != null && BlockChecker.isBlocked(mContext, nInd.getFrom().getString())) {
                result.statusCode = Intents.RESULT_SMS_HANDLED;
                return result;
            }
        }
        /**
         * Seek for application ID field in WSP header.
         * If application ID is found, WapPushManager substitute the message
         * processing. Since WapPushManager is optional module, if WapPushManager
         * is not found, legacy message processing will be continued.
         */
        if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
            index = (int) pduDecoder.getValue32();
            pduDecoder.decodeXWapApplicationId(index);
            String wapAppId = pduDecoder.getValueString();
            if (wapAppId == null) {
                wapAppId = Integer.toString((int) pduDecoder.getValue32());
            }
            result.wapAppId = wapAppId;
            String contentType = ((mimeType == null) ? Long.toString(binaryContentType) : mimeType);
            result.contentType = contentType;
            if (DBG)
                Rlog.v(TAG, "appid found: " + wapAppId + ":" + contentType);
        }
        result.subId = subId;
        result.phoneId = phoneId;
        result.parsedPdu = parsedPdu;
        result.mimeType = mimeType;
        result.transactionId = transactionId;
        result.pduType = pduType;
        result.header = header;
        result.intentData = intentData;
        result.contentTypeParameters = pduDecoder.getContentParameters();
        result.statusCode = Activity.RESULT_OK;
    } catch (ArrayIndexOutOfBoundsException aie) {
        // 0-byte WAP PDU or other unexpected WAP PDU contents can easily throw this;
        // log exception string without stack trace and return false.
        Rlog.e(TAG, "ignoring dispatchWapPdu() array index exception: " + aie);
        result.statusCode = Intents.RESULT_SMS_GENERIC_ERROR;
    }
    return result;
}
Also used : PduParser(com.google.android.mms.pdu.PduParser) NotificationInd(com.google.android.mms.pdu.NotificationInd) GenericPdu(com.google.android.mms.pdu.GenericPdu) MmsException(com.google.android.mms.MmsException) RemoteException(android.os.RemoteException) SQLiteException(android.database.sqlite.SQLiteException)

Example 4 with NotificationInd

use of com.google.android.mms.pdu.NotificationInd in project android-aosp-mms by slvn.

the class DownloadManager method getMessage.

private String getMessage(Uri uri) throws MmsException {
    NotificationInd ind = (NotificationInd) PduPersister.getPduPersister(mContext).load(uri);
    EncodedStringValue v = ind.getSubject();
    String subject = (v != null) ? v.getString() : mContext.getString(R.string.no_subject);
    v = ind.getFrom();
    String from = (v != null) ? Contact.get(v.getString(), false).getName() : mContext.getString(R.string.unknown_sender);
    return mContext.getString(R.string.dl_failure_notification, subject, from);
}
Also used : EncodedStringValue(com.google.android.mms.pdu.EncodedStringValue) NotificationInd(com.google.android.mms.pdu.NotificationInd)

Example 5 with NotificationInd

use of com.google.android.mms.pdu.NotificationInd in project android-aosp-mms by slvn.

the class DownloadManager method markState.

public void markState(final Uri uri, int state) {
    // Notify user if the message has expired.
    try {
        NotificationInd nInd = (NotificationInd) PduPersister.getPduPersister(mContext).load(uri);
        if ((nInd.getExpiry() < System.currentTimeMillis() / 1000L) && (state == STATE_DOWNLOADING || state == STATE_PRE_DOWNLOADING)) {
            mHandler.post(new Runnable() {

                public void run() {
                    Toast.makeText(mContext, R.string.service_message_not_found, Toast.LENGTH_LONG).show();
                }
            });
            SqliteWrapper.delete(mContext, mContext.getContentResolver(), uri, null, null);
            return;
        }
    } catch (MmsException e) {
        Log.e(TAG, e.getMessage(), e);
        return;
    }
    // Notify user if downloading permanently failed.
    if (state == STATE_PERMANENT_FAILURE) {
        mHandler.post(new Runnable() {

            public void run() {
                try {
                    Toast.makeText(mContext, getMessage(uri), Toast.LENGTH_LONG).show();
                } catch (MmsException e) {
                    Log.e(TAG, e.getMessage(), e);
                }
            }
        });
    } else if (!mAutoDownload) {
        state |= DEFERRED_MASK;
    }
    // Use the STATUS field to store the state of downloading process
    // because it's useless for M-Notification.ind.
    ContentValues values = new ContentValues(1);
    values.put(Mms.STATUS, state);
    SqliteWrapper.update(mContext, mContext.getContentResolver(), uri, values, null, null);
}
Also used : ContentValues(android.content.ContentValues) MmsException(com.google.android.mms.MmsException) NotificationInd(com.google.android.mms.pdu.NotificationInd)

Aggregations

NotificationInd (com.google.android.mms.pdu.NotificationInd)5 MmsException (com.google.android.mms.MmsException)4 ContentValues (android.content.ContentValues)2 Uri (android.net.Uri)2 EncodedStringValue (com.google.android.mms.pdu.EncodedStringValue)2 Resources (android.content.res.Resources)1 SQLiteException (android.database.sqlite.SQLiteException)1 Bundle (android.os.Bundle)1 RemoteException (android.os.RemoteException)1 GenericPdu (com.google.android.mms.pdu.GenericPdu)1 PduParser (com.google.android.mms.pdu.PduParser)1 PduPersister (com.google.android.mms.pdu.PduPersister)1