Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04406d95 authored by Sailesh Nepal's avatar Sailesh Nepal Committed by Android (Google) Code Review
Browse files

Merge "Add carrier regex filtering to VisualVoicemailSmsFilter" into nyc-mr1-dev

parents 9d20ef64 585c4649
Loading
Loading
Loading
Loading
+69 −13
Original line number Diff line number Diff line
@@ -15,17 +15,21 @@
 */
package com.android.internal.telephony;

import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.provider.VoicemailContract;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.telephony.VisualVoicemailSmsFilterSettings;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.telephony.VisualVoicemailSmsParser.WrappedMessageData;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

public class VisualVoicemailSmsFilter {

@@ -33,6 +37,8 @@ public class VisualVoicemailSmsFilter {

    private static final String SYSTEM_VVM_CLIENT_PACKAGE = "com.android.phone";

    private static Map<String, List<Pattern>> sPatterns;

    /**
     * Attempt to parse the incoming SMS as a visual voicemail SMS. If the parsing succeeded, A
     * {@link VoicemailContract.ACTION_VOICEMAIL_SMS_RECEIVED} intent will be sent to the visual
@@ -42,6 +48,11 @@ public class VisualVoicemailSmsFilter {
     *
     * <p>[clientPrefix]:[prefix]:([key]=[value];)*
     *
     * Additionally, if the SMS does not match the format, but matches the regex specified by the
     * carrier in {@link com.android.internal.R.array.config_vvmSmsFilterRegexes}, the SMS will
     * still be dropped and a {@link VoicemailContract.ACTION_VOICEMAIL_SMS_RECEIVED} with {@link
     * VoicemailContract#EXTRA_VOICEMAIL_SMS_MESSAGE_BODY} will be sent.
     *
     * @return true if the SMS has been parsed to be a visual voicemail SMS and should be dropped
     */
    public static boolean filter(Context context, byte[][] pdus, String format, int destPort,
@@ -69,34 +80,79 @@ public class VisualVoicemailSmsFilter {
            WrappedMessageData messageData = VisualVoicemailSmsParser
                .parseAlternativeFormat(asciiMessage);
            if (messageData != null) {
                sendVvmSmsBroadcast(context, vvmClientPackage, subId, messageData);
                sendVvmSmsBroadcast(context, vvmClientPackage, subId, messageData, null);
            }
            // Confidence for what the message actually is is low. Don't remove the message and let
            // system decide. Usually because it is not parsable it will be dropped.
            return false;
        } else {
        }
        String clientPrefix = settings.clientPrefix;
        WrappedMessageData messageData = VisualVoicemailSmsParser
            .parse(clientPrefix, messageBody);
        if (messageData != null) {
                sendVvmSmsBroadcast(context, vvmClientPackage, subId, messageData);
            sendVvmSmsBroadcast(context, vvmClientPackage, subId, messageData, null);
            return true;
        }

        buildPatternsMap(context);
        String mccMnc = telephonyManager.getSimOperator(subId);

        List<Pattern> patterns = sPatterns.get(mccMnc);
        if (patterns == null || patterns.isEmpty()) {
            return false;
        }

        for (Pattern pattern : patterns) {
            if (pattern.matcher(messageBody).matches()) {
                Log.w(TAG, "Incoming SMS matches pattern " + pattern + " but has illegal format, "
                    + "still dropping as VVM SMS");
                sendVvmSmsBroadcast(context, vvmClientPackage, subId, null, messageBody);
                return true;
            }
        }
        return false;
    }

    private static void buildPatternsMap(Context context) {
        if (sPatterns != null) {
            return;
        }
        sPatterns = new ArrayMap<>();
        // TODO(twyen): build from CarrierConfig once public API can be updated.
        for (String entry : context.getResources()
            .getStringArray(com.android.internal.R.array.config_vvmSmsFilterRegexes)) {
            String[] mccMncList = entry.split(";")[0].split(",");
            Pattern pattern = Pattern.compile(entry.split(";")[1]);

            for (String mccMnc : mccMncList) {
                if (!sPatterns.containsKey(mccMnc)) {
                    sPatterns.put(mccMnc, new ArrayList<>());
                }
                sPatterns.get(mccMnc).add(pattern);
            }
        }
    }

    private static void sendVvmSmsBroadcast(Context context, String vvmClientPackage, int subId,
        WrappedMessageData messageData) {
        @Nullable WrappedMessageData messageData, @Nullable String messageBody) {
        Log.i(TAG, "VVM SMS received");
        Intent intent = new Intent(VoicemailContract.ACTION_VOICEMAIL_SMS_RECEIVED);
        if (messageData != null) {
            intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_PREFIX, messageData.prefix);
            intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_FIELDS, messageData.fields);
        }
        if (messageBody != null) {
            intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_MESSAGE_BODY, messageBody);
        }
        intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_SUBID, subId);
        intent.setPackage(vvmClientPackage);
        context.sendBroadcast(intent);
    }

    /**
     * @return the message body of the SMS, or {@code null} if it can not be parsed.
     */
    @Nullable
    private static String getFullMessage(byte[][] pdus, String format) {
        StringBuilder builder = new StringBuilder();
        for (byte pdu[] : pdus) {