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

Commit 37e2ae39 authored by Jordan Liu's avatar Jordan Liu Committed by android-build-merger
Browse files

Merge "Add SCP handling in module"

am: 939d5d1f

Change-Id: Iecd54f847c2978b9079c4be7ff264e001f636004
parents dee384c9 939d5d1f
Loading
Loading
Loading
Loading
+26 −3
Original line number Diff line number Diff line
@@ -25,11 +25,13 @@ import android.os.AsyncResult;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.telephony.CellBroadcastService;
import android.telephony.ICellBroadcastService;
import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;

import com.android.internal.telephony.cdma.SmsMessage;

@@ -57,6 +59,7 @@ public class CellBroadcastServiceManager {
    /** New SMS cell broadcast received as an AsyncResult. */
    private static final int EVENT_NEW_GSM_SMS_CB = 0;
    private static final int EVENT_NEW_CDMA_SMS_CB = 1;
    private static final int EVENT_NEW_CDMA_SCP_MESSAGE = 2;
    private boolean mEnabled;

    public CellBroadcastServiceManager(Context context, Phone phone) {
@@ -66,7 +69,7 @@ public class CellBroadcastServiceManager {
    }

    /**
     * Send a GSM CB message to the CellBroadcastServieManager's handler.
     * Send a GSM CB message to the CellBroadcastServiceManager's handler.
     * @param m the message
     */
    public void sendGsmMessageToHandler(Message m) {
@@ -75,7 +78,7 @@ public class CellBroadcastServiceManager {
    }

    /**
     * Send a CDMA CB message to the CellBroadcastServieManager's handler.
     * Send a CDMA CB message to the CellBroadcastServiceManager's handler.
     * @param sms the SmsMessage to forward
     */
    public void sendCdmaMessageToHandler(SmsMessage sms) {
@@ -85,6 +88,17 @@ public class CellBroadcastServiceManager {
        mModuleCellBroadcastHandler.sendMessage(m);
    }

    /**
     * Send a CDMA Service Category Program message to the CellBroadcastServiceManager's handler.
     * @param sms the SCP message
     */
    public void sendCdmaScpMessageToHandler(SmsMessage sms, RemoteCallback callback) {
        Message m = Message.obtain();
        m.what = EVENT_NEW_CDMA_SCP_MESSAGE;
        m.obj = Pair.create(sms, callback);
        mModuleCellBroadcastHandler.sendMessage(m);
    }

    /**
     * Enable the CB module. The CellBroadcastService will be bound to and CB messages from the
     * RIL will be forwarded to the module.
@@ -140,7 +154,16 @@ public class CellBroadcastServiceManager {
                            SmsMessage sms = (SmsMessage) msg.obj;
                            cellBroadcastService.handleCdmaCellBroadcastSms(mPhone.getPhoneId(),
                                    sms.getEnvelopeBearerData(), sms.getEnvelopeServiceCategory());

                        } else if (msg.what == EVENT_NEW_CDMA_SCP_MESSAGE) {
                            mLocalLog.log("CDMA SCP message for phone " + mPhone.getPhoneId());
                            Pair<SmsMessage, RemoteCallback> smsAndCallback =
                                    (Pair<SmsMessage, RemoteCallback>) msg.obj;
                            SmsMessage sms = smsAndCallback.first;
                            RemoteCallback callback = smsAndCallback.second;
                            cellBroadcastService.handleCdmaScpMessage(mPhone.getPhoneId(),
                                    sms.getSmsCbProgramData(),
                                    sms.getOriginatingAddress(),
                                    callback);
                        }
                    } catch (RemoteException e) {
                        Log.e(TAG, "Failed to connect to default app: "
+171 −24
Original line number Diff line number Diff line
@@ -22,9 +22,13 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.Message;
import android.os.RemoteCallback;
import android.os.SystemProperties;
import android.provider.Telephony.Sms.Intents;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsCbMessage;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaSmsCbProgramResults;

import com.android.internal.telephony.CellBroadcastHandler;
import com.android.internal.telephony.CommandsInterface;
@@ -36,10 +40,15 @@ import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.SmsStorageMonitor;
import com.android.internal.telephony.TelephonyComponentFactory;
import com.android.internal.telephony.WspTypeDecoder;
import com.android.internal.telephony.cdma.sms.BearerData;
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import com.android.internal.util.HexDump;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

/**
@@ -50,17 +59,23 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
    private final CdmaSMSDispatcher mSmsDispatcher;
    private final CdmaServiceCategoryProgramHandler mServiceCategoryProgramHandler;
    private static CdmaCbTestBroadcastReceiver sTestBroadcastReceiver;
    private static CdmaScpTestBroadcastReceiver sTestScpBroadcastReceiver;

    private byte[] mLastDispatchedSmsFingerprint;
    private byte[] mLastAcknowledgedSmsFingerprint;

    // Callback used to process the result of an SCP message
    private RemoteCallback mScpCallback;

    private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean(
            com.android.internal.R.bool.config_duplicate_port_omadm_wappush);

    // When TEST_MODE is on we allow the test intent to trigger an SMS CB alert
    private static final boolean TEST_MODE = true; //STOPSHIP if true
    private static final boolean TEST_MODE = SystemProperties.getInt("ro.debuggable", 0) == 1;
    private static final String TEST_ACTION = "com.android.internal.telephony.cdma"
            + ".TEST_TRIGGER_CELL_BROADCAST";
    private static final String SCP_TEST_ACTION = "com.android.internal.telephony.cdma"
            + ".TEST_TRIGGER_SCP_MESSAGE";
    private static final String TOGGLE_CB_MODULE = "com.android.internal.telephony.cdma"
            + ".TOGGLE_CB_MODULE";

@@ -73,10 +88,63 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
                CellBroadcastHandler.makeCellBroadcastHandler(context, phone));
        mSmsDispatcher = smsDispatcher;
        mServiceCategoryProgramHandler = CdmaServiceCategoryProgramHandler.makeScpHandler(context,
                phone.mCi);
                phone.mCi, phone);
        phone.mCi.setOnNewCdmaSms(getHandler(), EVENT_NEW_SMS, null);

        mCellBroadcastServiceManager.enable();
        mScpCallback = new RemoteCallback(result -> {
            if (result == null) {
                loge("SCP results error: missing extras");
                return;
            }
            String sender = result.getString("sender");
            if (sender == null) {
                loge("SCP results error: missing sender extra.");
                return;
            }
            ArrayList<CdmaSmsCbProgramResults> results = result.getParcelableArrayList("results");
            if (results == null) {
                loge("SCP results error: missing results extra.");
                return;
            }

            BearerData bData = new BearerData();
            bData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
            bData.messageId = SmsMessage.getNextMessageId();
            bData.serviceCategoryProgramResults = results;
            byte[] encodedBearerData = BearerData.encode(bData);

            ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
            DataOutputStream dos = new DataOutputStream(baos);
            try {
                dos.writeInt(SmsEnvelope.TELESERVICE_SCPT);
                dos.writeInt(0); //servicePresent
                dos.writeInt(0); //serviceCategory
                CdmaSmsAddress destAddr = CdmaSmsAddress.parse(
                        PhoneNumberUtils.cdmaCheckAndProcessPlusCodeForSms(sender));
                dos.write(destAddr.digitMode);
                dos.write(destAddr.numberMode);
                dos.write(destAddr.ton); // number_type
                dos.write(destAddr.numberPlan);
                dos.write(destAddr.numberOfDigits);
                dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits
                // Subaddress is not supported.
                dos.write(0); //subaddressType
                dos.write(0); //subaddr_odd
                dos.write(0); //subaddr_nbr_of_digits
                dos.write(encodedBearerData.length);
                dos.write(encodedBearerData, 0, encodedBearerData.length);
                // Ignore the RIL response. TODO: implement retry if SMS send fails.
                mPhone.mCi.sendCdmaSms(baos.toByteArray(), null);
            } catch (IOException e) {
                loge("exception creating SCP results PDU", e);
            } finally {
                try {
                    dos.close();
                } catch (IOException ignored) {
                }
            }
        });
        if (TEST_MODE) {
            if (sTestBroadcastReceiver == null) {
                sTestBroadcastReceiver = new CdmaCbTestBroadcastReceiver();
@@ -85,6 +153,12 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
                filter.addAction(TOGGLE_CB_MODULE);
                context.registerReceiver(sTestBroadcastReceiver, filter);
            }
            if (sTestScpBroadcastReceiver == null) {
                sTestScpBroadcastReceiver = new CdmaScpTestBroadcastReceiver();
                IntentFilter filter = new IntentFilter();
                filter.addAction(SCP_TEST_ACTION);
                context.registerReceiver(sTestScpBroadcastReceiver, filter);
            }
        }
    }

@@ -113,6 +187,7 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {

    /**
     * Return true if this handler is for 3GPP2 messages; false for 3GPP format.
     *
     * @return true (3GPP2)
     */
    @Override
@@ -122,6 +197,7 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {

    /**
     * Process Cell Broadcast, Voicemail Notification, and other 3GPP/3GPP2-specific messages.
     *
     * @param smsb the SmsMessageBase object from the RIL
     * @return true if the message was handled here; false to continue processing
     */
@@ -168,7 +244,11 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
                break;

            case SmsEnvelope.TELESERVICE_SCPT:
                if (sEnableCbModule) {
                    mCellBroadcastServiceManager.sendCdmaScpMessageToHandler(sms, mScpCallback);
                } else {
                    mServiceCategoryProgramHandler.dispatchSmsMessage(sms);
                }
                return Intents.RESULT_SMS_HANDLED;

            case SmsEnvelope.TELESERVICE_FDEA_WAP:
@@ -218,6 +298,7 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {

    /**
     * Send an acknowledge message.
     *
     * @param success  indicates that last message was successfully received.
     * @param result   result code indicating any error
     * @param response callback message sent when operation completes.
@@ -235,6 +316,7 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {

    /**
     * Convert Android result code to CDMA SMS failure cause.
     *
     * @param rc the Android SMS intent result value
     * @return 0 for success, or a CDMA SMS failure cause value
     */
@@ -256,6 +338,7 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {

    /**
     * Handle {@link SmsEnvelope#TELESERVICE_VMN} and {@link SmsEnvelope#TELESERVICE_MWI}.
     *
     * @param sms the message to process
     */
    private void handleVoicemailTeleservice(SmsMessage sms) {
@@ -331,8 +414,10 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
        System.arraycopy(pdu, index, userData, 0, pdu.length - index);
        InboundSmsTracker tracker = TelephonyComponentFactory.getInstance()
                .inject(InboundSmsTracker.class.getName()).makeInboundSmsTracker(
                userData, timestamp, destinationPort, true, address, dispAddr, referenceNumber,
                segment, totalSegments, true, HexDump.toHexString(userData), false /* isClass0 */,
                        userData, timestamp, destinationPort, true, address, dispAddr,
                        referenceNumber,
                        segment, totalSegments, true, HexDump.toHexString(userData),
                        false /* isClass0 */,
                        mPhone.getSubId());

        // de-duping is done only for text messages
@@ -345,6 +430,7 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
     * - Some carriers make this mistake.
     * ex: MSGTYPE-TotalSegments-CurrentSegment
     * -SourcePortDestPort-SourcePortDestPort-OMADM PDU
     *
     * @param origPdu The WAP-WDP PDU segment
     * @param index   Current Index while parsing the PDU.
     * @return True if OrigPdu is OmaDM Push Message which has duplicate ports.
@@ -454,4 +540,65 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
            mCellBroadcastServiceManager.disable();
        }
    }

    /**
     * A broadcast receiver used for testing CDMA SCP messages. To trigger test CDMA SCP messages
     * with adb run e.g:
     *
     * adb shell am broadcast -a com.android.internal.telephony.cdma.TEST_TRIGGER_SCP_MESSAGE \
     * --es originating_address_string 1234567890 \
     * --es bearer_data_string 00031007B0122610880080B2091C5F1D3965DB95054D1CB2E1E883A6F41334E \
     * 6CA830EEC882872DFC32F2E9E40
     *
     * To toggle use the CDMA CB test broadcast receiver.
     */
    private class CdmaScpTestBroadcastReceiver extends CbTestBroadcastReceiver {

        CdmaScpTestBroadcastReceiver() {
            super(SCP_TEST_ACTION, null);
        }

        @Override
        protected void handleTestAction(Intent intent) {
            SmsEnvelope envelope = new SmsEnvelope();
            // the CdmaSmsAddress is not used for a test SCP message, but needs to be supplied to
            // avoid a null pointer exception in the platform
            CdmaSmsAddress nonNullAddress = new CdmaSmsAddress();
            nonNullAddress.origBytes = new byte[]{(byte) 0xFF};
            envelope.origAddress = nonNullAddress;

            // parse bearer data from intent
            String bearerDataString = intent.getStringExtra("bearer_data_string");
            envelope.bearerData = decodeHexString(bearerDataString);
            if (envelope.bearerData == null) {
                log("No bearer data, ignoring SCP test intent");
                return;
            }

            CdmaSmsAddress origAddr = new CdmaSmsAddress();
            String addressString = intent.getStringExtra("originating_address_string");
            origAddr.origBytes = decodeHexString(addressString);
            if (origAddr.origBytes == null) {
                log("No address data, ignoring SCP test intent");
                return;
            }
            SmsMessage sms = new SmsMessage(origAddr, envelope);
            sms.parseSms();
            if (sEnableCbModule) {
                mCellBroadcastServiceManager.sendCdmaScpMessageToHandler(sms, mScpCallback);
            } else {
                mServiceCategoryProgramHandler.dispatchSmsMessage(sms);
            }
        }

        @Override
        protected void handleToggleEnable() {
            // noop
        }

        @Override
        protected void handleToggleDisable(Context context) {
            // noop
        }
    }
}
+6 −4
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.telephony.cdma.CdmaSmsCbProgramData;
import android.telephony.cdma.CdmaSmsCbProgramResults;

import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.WakeLockStateMachine;
import com.android.internal.telephony.cdma.sms.BearerData;
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
@@ -51,8 +52,9 @@ public final class CdmaServiceCategoryProgramHandler extends WakeLockStateMachin
    /**
     * Create a new CDMA inbound SMS handler.
     */
    CdmaServiceCategoryProgramHandler(Context context, CommandsInterface commandsInterface) {
        super("CdmaServiceCategoryProgramHandler", context, null);
    CdmaServiceCategoryProgramHandler(Context context, CommandsInterface commandsInterface,
            Phone phone) {
        super("CdmaServiceCategoryProgramHandler", context, phone);
        mContext = context;
        mCi = commandsInterface;
    }
@@ -64,9 +66,9 @@ public final class CdmaServiceCategoryProgramHandler extends WakeLockStateMachin
     * @return the new SCPD handler
     */
    static CdmaServiceCategoryProgramHandler makeScpHandler(Context context,
            CommandsInterface commandsInterface) {
            CommandsInterface commandsInterface, Phone phone) {
        CdmaServiceCategoryProgramHandler handler = new CdmaServiceCategoryProgramHandler(
                context, commandsInterface);
                context, commandsInterface, phone);
        handler.start();
        return handler;
    }
+2 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncResult;
import android.os.Message;
import android.os.SystemProperties;
import android.provider.Telephony.Sms.Intents;

import com.android.internal.telephony.CommandsInterface;
@@ -46,7 +47,7 @@ public class GsmInboundSmsHandler extends InboundSmsHandler {
    private final UsimDataDownloadHandler mDataDownloadHandler;

    // When TEST_MODE is on we allow the test intent to trigger an SMS CB alert
    private static final boolean TEST_MODE = true; //STOPSHIP if true
    private static final boolean TEST_MODE = SystemProperties.getInt("ro.debuggable", 0) == 1;
    private static final String TEST_ACTION = "com.android.internal.telephony.gsm"
            + ".TEST_TRIGGER_CELL_BROADCAST";
    private static final String TOGGLE_CB_MODULE = "com.android.internal.telephony.gsm"