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

Commit 939d5d1f authored by Jordan Liu's avatar Jordan Liu Committed by Gerrit Code Review
Browse files

Merge "Add SCP handling in module"

parents 3c533928 c275d554
Loading
Loading
Loading
Loading
+26 −3
Original line number Original line Diff line number Diff line
@@ -25,11 +25,13 @@ import android.os.AsyncResult;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
import android.os.Message;
import android.os.Message;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.RemoteException;
import android.telephony.CellBroadcastService;
import android.telephony.CellBroadcastService;
import android.telephony.ICellBroadcastService;
import android.telephony.ICellBroadcastService;
import android.util.LocalLog;
import android.util.LocalLog;
import android.util.Log;
import android.util.Log;
import android.util.Pair;


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


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


    public CellBroadcastServiceManager(Context context, Phone phone) {
    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
     * @param m the message
     */
     */
    public void sendGsmMessageToHandler(Message m) {
    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
     * @param sms the SmsMessage to forward
     */
     */
    public void sendCdmaMessageToHandler(SmsMessage sms) {
    public void sendCdmaMessageToHandler(SmsMessage sms) {
@@ -85,6 +88,17 @@ public class CellBroadcastServiceManager {
        mModuleCellBroadcastHandler.sendMessage(m);
        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
     * Enable the CB module. The CellBroadcastService will be bound to and CB messages from the
     * RIL will be forwarded to the module.
     * RIL will be forwarded to the module.
@@ -140,7 +154,16 @@ public class CellBroadcastServiceManager {
                            SmsMessage sms = (SmsMessage) msg.obj;
                            SmsMessage sms = (SmsMessage) msg.obj;
                            cellBroadcastService.handleCdmaCellBroadcastSms(mPhone.getPhoneId(),
                            cellBroadcastService.handleCdmaCellBroadcastSms(mPhone.getPhoneId(),
                                    sms.getEnvelopeBearerData(), sms.getEnvelopeServiceCategory());
                                    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) {
                    } catch (RemoteException e) {
                        Log.e(TAG, "Failed to connect to default app: "
                        Log.e(TAG, "Failed to connect to default app: "
+171 −24
Original line number Original line Diff line number Diff line
@@ -22,9 +22,13 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.content.res.Resources;
import android.os.Message;
import android.os.Message;
import android.os.RemoteCallback;
import android.os.SystemProperties;
import android.provider.Telephony.Sms.Intents;
import android.provider.Telephony.Sms.Intents;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsCbMessage;
import android.telephony.SmsCbMessage;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaSmsCbProgramResults;


import com.android.internal.telephony.CellBroadcastHandler;
import com.android.internal.telephony.CellBroadcastHandler;
import com.android.internal.telephony.CommandsInterface;
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.SmsStorageMonitor;
import com.android.internal.telephony.TelephonyComponentFactory;
import com.android.internal.telephony.TelephonyComponentFactory;
import com.android.internal.telephony.WspTypeDecoder;
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.CdmaSmsAddress;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import com.android.internal.util.HexDump;
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;
import java.util.Arrays;


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


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


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

    private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean(
    private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean(
            com.android.internal.R.bool.config_duplicate_port_omadm_wappush);
            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
    // 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"
    private static final String TEST_ACTION = "com.android.internal.telephony.cdma"
            + ".TEST_TRIGGER_CELL_BROADCAST";
            + ".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"
    private static final String TOGGLE_CB_MODULE = "com.android.internal.telephony.cdma"
            + ".TOGGLE_CB_MODULE";
            + ".TOGGLE_CB_MODULE";


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


        mCellBroadcastServiceManager.enable();
        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 (TEST_MODE) {
            if (sTestBroadcastReceiver == null) {
            if (sTestBroadcastReceiver == null) {
                sTestBroadcastReceiver = new CdmaCbTestBroadcastReceiver();
                sTestBroadcastReceiver = new CdmaCbTestBroadcastReceiver();
@@ -85,6 +153,12 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
                filter.addAction(TOGGLE_CB_MODULE);
                filter.addAction(TOGGLE_CB_MODULE);
                context.registerReceiver(sTestBroadcastReceiver, filter);
                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 if this handler is for 3GPP2 messages; false for 3GPP format.
     *
     * @return true (3GPP2)
     * @return true (3GPP2)
     */
     */
    @Override
    @Override
@@ -122,6 +197,7 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {


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


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


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


    /**
    /**
     * Send an acknowledge message.
     * Send an acknowledge message.
     *
     * @param success  indicates that last message was successfully received.
     * @param success  indicates that last message was successfully received.
     * @param result   result code indicating any error
     * @param result   result code indicating any error
     * @param response callback message sent when operation completes.
     * @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.
     * Convert Android result code to CDMA SMS failure cause.
     *
     * @param rc the Android SMS intent result value
     * @param rc the Android SMS intent result value
     * @return 0 for success, or a CDMA SMS failure cause 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}.
     * Handle {@link SmsEnvelope#TELESERVICE_VMN} and {@link SmsEnvelope#TELESERVICE_MWI}.
     *
     * @param sms the message to process
     * @param sms the message to process
     */
     */
    private void handleVoicemailTeleservice(SmsMessage sms) {
    private void handleVoicemailTeleservice(SmsMessage sms) {
@@ -331,8 +414,10 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
        System.arraycopy(pdu, index, userData, 0, pdu.length - index);
        System.arraycopy(pdu, index, userData, 0, pdu.length - index);
        InboundSmsTracker tracker = TelephonyComponentFactory.getInstance()
        InboundSmsTracker tracker = TelephonyComponentFactory.getInstance()
                .inject(InboundSmsTracker.class.getName()).makeInboundSmsTracker(
                .inject(InboundSmsTracker.class.getName()).makeInboundSmsTracker(
                userData, timestamp, destinationPort, true, address, dispAddr, referenceNumber,
                        userData, timestamp, destinationPort, true, address, dispAddr,
                segment, totalSegments, true, HexDump.toHexString(userData), false /* isClass0 */,
                        referenceNumber,
                        segment, totalSegments, true, HexDump.toHexString(userData),
                        false /* isClass0 */,
                        mPhone.getSubId());
                        mPhone.getSubId());


        // de-duping is done only for text messages
        // de-duping is done only for text messages
@@ -345,6 +430,7 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
     * - Some carriers make this mistake.
     * - Some carriers make this mistake.
     * ex: MSGTYPE-TotalSegments-CurrentSegment
     * ex: MSGTYPE-TotalSegments-CurrentSegment
     * -SourcePortDestPort-SourcePortDestPort-OMADM PDU
     * -SourcePortDestPort-SourcePortDestPort-OMADM PDU
     *
     * @param origPdu The WAP-WDP PDU segment
     * @param origPdu The WAP-WDP PDU segment
     * @param index   Current Index while parsing the PDU.
     * @param index   Current Index while parsing the PDU.
     * @return True if OrigPdu is OmaDM Push Message which has duplicate ports.
     * @return True if OrigPdu is OmaDM Push Message which has duplicate ports.
@@ -454,4 +540,65 @@ public class CdmaInboundSmsHandler extends InboundSmsHandler {
            mCellBroadcastServiceManager.disable();
            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 Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import android.telephony.cdma.CdmaSmsCbProgramData;
import android.telephony.cdma.CdmaSmsCbProgramResults;
import android.telephony.cdma.CdmaSmsCbProgramResults;


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


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


    // When TEST_MODE is on we allow the test intent to trigger an SMS CB alert
    // 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"
    private static final String TEST_ACTION = "com.android.internal.telephony.gsm"
            + ".TEST_TRIGGER_CELL_BROADCAST";
            + ".TEST_TRIGGER_CELL_BROADCAST";
    private static final String TOGGLE_CB_MODULE = "com.android.internal.telephony.gsm"
    private static final String TOGGLE_CB_MODULE = "com.android.internal.telephony.gsm"