Search in sources :

Example 51 with UnsupportedAppUsage

use of android.compat.annotation.UnsupportedAppUsage in project android_frameworks_opt_telephony by LineageOS.

the class InboundSmsHandler method processMessagePart.

/**
 * Process the inbound SMS segment. If the message is complete, send it as an ordered
 * broadcast to interested receivers and return true. If the message is a segment of an
 * incomplete multi-part SMS, return false.
 * @param tracker the tracker containing the message segment to process
 * @return true if an ordered broadcast was sent; false if waiting for more message segments
 */
@UnsupportedAppUsage
private boolean processMessagePart(InboundSmsTracker tracker) {
    int messageCount = tracker.getMessageCount();
    byte[][] pdus;
    long[] timestamps;
    int destPort = tracker.getDestPort();
    boolean block = false;
    String address = tracker.getAddress();
    // Do not process when the message count is invalid.
    if (messageCount <= 0) {
        loge("processMessagePart: returning false due to invalid message count " + messageCount, tracker.getMessageId());
        return false;
    }
    if (messageCount == 1) {
        // single-part message
        pdus = new byte[][] { tracker.getPdu() };
        timestamps = new long[] { tracker.getTimestamp() };
        block = BlockChecker.isBlocked(mContext, tracker.getDisplayAddress(), null);
    } else {
        // multi-part message
        Cursor cursor = null;
        try {
            // used by several query selection arguments
            String refNumber = Integer.toString(tracker.getReferenceNumber());
            String count = Integer.toString(tracker.getMessageCount());
            // query for all segments and broadcast message if we have all the parts
            String[] whereArgs = { address, refNumber, count };
            cursor = mResolver.query(sRawUri, PDU_SEQUENCE_PORT_PROJECTION, tracker.getQueryForSegments(), whereArgs, null);
            int cursorCount = cursor.getCount();
            if (cursorCount < messageCount) {
                // Wait for the other message parts to arrive. It's also possible for the last
                // segment to arrive before processing the EVENT_BROADCAST_SMS for one of the
                // earlier segments. In that case, the broadcast will be sent as soon as all
                // segments are in the table, and any later EVENT_BROADCAST_SMS messages will
                // get a row count of 0 and return.
                log("processMessagePart: returning false. Only " + cursorCount + " of " + messageCount + " segments " + " have arrived. refNumber: " + refNumber, tracker.getMessageId());
                return false;
            }
            // All the parts are in place, deal with them
            pdus = new byte[messageCount][];
            timestamps = new long[messageCount];
            while (cursor.moveToNext()) {
                // subtract offset to convert sequence to 0-based array index
                int index = cursor.getInt(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(SEQUENCE_COLUMN)) - tracker.getIndexOffset();
                // UserDataHeader is invalid.
                if (index >= pdus.length || index < 0) {
                    loge(String.format("processMessagePart: invalid seqNumber = %d, messageCount = %d", index + tracker.getIndexOffset(), messageCount), tracker.getMessageId());
                    continue;
                }
                pdus[index] = HexDump.hexStringToByteArray(cursor.getString(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(PDU_COLUMN)));
                // It's not a bad idea to prefer the port from the first segment in other cases.
                if (index == 0 && !cursor.isNull(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(DESTINATION_PORT_COLUMN))) {
                    int port = cursor.getInt(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(DESTINATION_PORT_COLUMN));
                    // strip format flags and convert to real port number, or -1
                    port = InboundSmsTracker.getRealDestPort(port);
                    if (port != -1) {
                        destPort = port;
                    }
                }
                timestamps[index] = cursor.getLong(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(DATE_COLUMN));
                // check if display address should be blocked or not
                if (!block) {
                    // Depending on the nature of the gateway, the display origination address
                    // is either derived from the content of the SMS TP-OA field, or the TP-OA
                    // field contains a generic gateway address and the from address is added
                    // at the beginning in the message body. In that case only the first SMS
                    // (part of Multi-SMS) comes with the display originating address which
                    // could be used for block checking purpose.
                    block = BlockChecker.isBlocked(mContext, cursor.getString(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(DISPLAY_ADDRESS_COLUMN)), null);
                }
            }
            log("processMessagePart: all " + messageCount + " segments " + " received. refNumber: " + refNumber, tracker.getMessageId());
        } catch (SQLException e) {
            loge("processMessagePart: Can't access multipart SMS database, id: " + tracker.getMessageId(), e);
            return false;
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }
    final boolean isWapPush = (destPort == SmsHeader.PORT_WAP_PUSH);
    // At this point, all parts of the SMS are received. Update metrics for incoming SMS.
    // WAP-PUSH messages are handled below to also keep track of the result of the processing.
    String format = tracker.getFormat();
    if (!isWapPush) {
        mMetrics.writeIncomingSmsSession(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, block, tracker.getMessageId());
    }
    // Do not process null pdu(s). Check for that and return false in that case.
    List<byte[]> pduList = Arrays.asList(pdus);
    if (pduList.size() == 0 || pduList.contains(null)) {
        String errorMsg = "processMessagePart: returning false due to " + (pduList.size() == 0 ? "pduList.size() == 0" : "pduList.contains(null)");
        logeWithLocalLog(errorMsg, tracker.getMessageId());
        return false;
    }
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    if (isWapPush) {
        for (byte[] pdu : pdus) {
            // 3GPP needs to extract the User Data from the PDU; 3GPP2 has already done this
            if (format == SmsConstants.FORMAT_3GPP) {
                SmsMessage msg = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP);
                if (msg != null) {
                    pdu = msg.getUserData();
                } else {
                    loge("processMessagePart: SmsMessage.createFromPdu returned null", tracker.getMessageId());
                    mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, SmsConstants.FORMAT_3GPP, timestamps, false, tracker.getMessageId());
                    return false;
                }
            }
            output.write(pdu, 0, pdu.length);
        }
    }
    SmsBroadcastReceiver resultReceiver = new SmsBroadcastReceiver(tracker);
    if (!mUserManager.isUserUnlocked()) {
        log("processMessagePart: !isUserUnlocked; calling processMessagePartWithUserLocked. " + "Port: " + destPort, tracker.getMessageId());
        return processMessagePartWithUserLocked(tracker, (isWapPush ? new byte[][] { output.toByteArray() } : pdus), destPort, resultReceiver);
    }
    if (isWapPush) {
        int result = mWapPush.dispatchWapPdu(output.toByteArray(), resultReceiver, this, address, tracker.getSubId(), tracker.getMessageId());
        if (DBG) {
            log("processMessagePart: dispatchWapPdu() returned " + result, tracker.getMessageId());
        }
        // needs to be ignored, so treating it as a success case.
        if (result == Activity.RESULT_OK || result == Intents.RESULT_SMS_HANDLED) {
            mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, true, tracker.getMessageId());
        } else {
            mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), mLastSmsWasInjected, format, timestamps, false, tracker.getMessageId());
        }
        // result is Activity.RESULT_OK if an ordered broadcast was sent
        if (result == Activity.RESULT_OK) {
            return true;
        } else {
            deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), MARK_DELETED);
            loge("processMessagePart: returning false as the ordered broadcast for WAP push " + "was not sent", tracker.getMessageId());
            return false;
        }
    }
    // Always invoke SMS filters, even if the number ends up being blocked, to prevent
    // surprising bugs due to blocking numbers that happen to be used for visual voicemail SMS
    // or other carrier system messages.
    boolean filterInvoked = filterSms(pdus, destPort, tracker, resultReceiver, true, /* userUnlocked */
    block);
    if (!filterInvoked) {
        // the filter to delete the SMS once processing completes.
        if (block) {
            deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), DELETE_PERMANENTLY);
            log("processMessagePart: returning false as the phone number is blocked", tracker.getMessageId());
            return false;
        }
        dispatchSmsDeliveryIntent(pdus, format, destPort, resultReceiver, tracker.isClass0(), tracker.getSubId(), tracker.getMessageId());
    }
    return true;
}
Also used : SQLException(android.database.SQLException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Cursor(android.database.Cursor) SmsMessage(android.telephony.SmsMessage) UnsupportedAppUsage(android.compat.annotation.UnsupportedAppUsage)

Example 52 with UnsupportedAppUsage

use of android.compat.annotation.UnsupportedAppUsage in project android_frameworks_opt_telephony by LineageOS.

the class InboundSmsHandler method writeInboxMessage.

/**
 * Store a received SMS into Telephony provider
 *
 * @param intent The intent containing the received SMS
 * @return The URI of written message
 */
@UnsupportedAppUsage
private Uri writeInboxMessage(Intent intent) {
    final SmsMessage[] messages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
    if (messages == null || messages.length < 1) {
        loge("Failed to parse SMS pdu");
        return null;
    }
    // Sometimes, SmsMessage is null if it can’t be parsed correctly.
    for (final SmsMessage sms : messages) {
        if (sms == null) {
            loge("Can’t write null SmsMessage");
            return null;
        }
    }
    final ContentValues values = parseSmsMessage(messages);
    final long identity = Binder.clearCallingIdentity();
    try {
        return mContext.getContentResolver().insert(Telephony.Sms.Inbox.CONTENT_URI, values);
    } catch (Exception e) {
        loge("Failed to persist inbox message", e);
    } finally {
        Binder.restoreCallingIdentity(identity);
    }
    return null;
}
Also used : ContentValues(android.content.ContentValues) SmsMessage(android.telephony.SmsMessage) RemoteException(android.os.RemoteException) SQLException(android.database.SQLException) UnsupportedAppUsage(android.compat.annotation.UnsupportedAppUsage)

Example 53 with UnsupportedAppUsage

use of android.compat.annotation.UnsupportedAppUsage in project android_frameworks_opt_telephony by LineageOS.

the class InboundSmsHandler method handleSmsWhitelisting.

@UnsupportedAppUsage
private Bundle handleSmsWhitelisting(ComponentName target, boolean bgActivityStartAllowed) {
    String pkgName;
    String reason;
    if (target != null) {
        pkgName = target.getPackageName();
        reason = "sms-app";
    } else {
        pkgName = mContext.getPackageName();
        reason = "sms-broadcast";
    }
    BroadcastOptions bopts = null;
    Bundle bundle = null;
    if (bgActivityStartAllowed) {
        bopts = BroadcastOptions.makeBasic();
        bopts.setBackgroundActivityStartsAllowed(true);
        bundle = bopts.toBundle();
    }
    long duration = mPowerWhitelistManager.whitelistAppTemporarilyForEvent(pkgName, PowerWhitelistManager.EVENT_SMS, reason);
    if (bopts == null)
        bopts = BroadcastOptions.makeBasic();
    bopts.setTemporaryAppWhitelistDuration(duration);
    bundle = bopts.toBundle();
    return bundle;
}
Also used : BroadcastOptions(android.app.BroadcastOptions) Bundle(android.os.Bundle) UnsupportedAppUsage(android.compat.annotation.UnsupportedAppUsage)

Example 54 with UnsupportedAppUsage

use of android.compat.annotation.UnsupportedAppUsage in project android_frameworks_opt_telephony by LineageOS.

the class InboundSmsHandler method handleInjectSms.

/**
 * This method is called when a new SMS PDU is injected into application framework.
 * @param ar is the AsyncResult that has the SMS PDU to be injected.
 */
@UnsupportedAppUsage
private void handleInjectSms(AsyncResult ar) {
    int result;
    SmsDispatchersController.SmsInjectionCallback callback = null;
    try {
        callback = (SmsDispatchersController.SmsInjectionCallback) ar.userObj;
        SmsMessage sms = (SmsMessage) ar.result;
        if (sms == null) {
            loge("Null injected sms");
            result = RESULT_SMS_NULL_PDU;
        } else {
            mLastSmsWasInjected = true;
            result = dispatchMessage(sms.mWrappedSmsMessage);
        }
    } catch (RuntimeException ex) {
        loge("Exception dispatching message", ex);
        result = RESULT_SMS_DISPATCH_FAILURE;
    }
    if (callback != null) {
        callback.onSmsInjectedResult(result);
    }
}
Also used : SmsMessage(android.telephony.SmsMessage) UnsupportedAppUsage(android.compat.annotation.UnsupportedAppUsage)

Example 55 with UnsupportedAppUsage

use of android.compat.annotation.UnsupportedAppUsage in project android_frameworks_opt_telephony by LineageOS.

the class IccSmsInterfaceManager method setCellBroadcastConfig.

@UnsupportedAppUsage
private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) {
    if (DBG) {
        log("Calling setGsmBroadcastConfig with " + configs.length + " configurations");
    }
    enforceNotOnHandlerThread("setCellBroadcastConfig");
    synchronized (mLock) {
        Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE);
        mSuccess = false;
        mPhone.mCi.setGsmBroadcastConfig(configs, response);
        try {
            mLock.wait();
        } catch (InterruptedException e) {
            loge("interrupted while trying to set cell broadcast config");
        }
    }
    return mSuccess;
}
Also used : SmsMessage(android.telephony.SmsMessage) SmsCbMessage(android.telephony.SmsCbMessage) Message(android.os.Message) UnsupportedAppUsage(android.compat.annotation.UnsupportedAppUsage)

Aggregations

UnsupportedAppUsage (android.compat.annotation.UnsupportedAppUsage)71 Message (android.os.Message)18 SmsMessage (android.telephony.SmsMessage)9 Intent (android.content.Intent)6 SipPhone (com.android.internal.telephony.sip.SipPhone)6 SmsCbMessage (android.telephony.SmsCbMessage)5 Cursor (android.database.Cursor)4 PendingIntent (android.app.PendingIntent)3 PackageManager (android.content.pm.PackageManager)3 AsyncResult (android.os.AsyncResult)3 PersistableBundle (android.os.PersistableBundle)3 CarrierConfigManager (android.telephony.CarrierConfigManager)3 SubscriptionInfo (android.telephony.SubscriptionInfo)3 SQLException (android.database.SQLException)2 SQLiteException (android.database.sqlite.SQLiteException)2 PowerManager (android.os.PowerManager)2 RadioAccessFamily (android.telephony.RadioAccessFamily)2 ImsException (com.android.ims.ImsException)2 ImsUtInterface (com.android.ims.ImsUtInterface)2 AppState (com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState)2