FileDocCategorySizeDatePackage
GSMPhone.javaAPI DocAndroid 1.5 API54940Wed May 06 22:42:02 BST 2009com.android.internal.telephony.gsm

GSMPhone

public class GSMPhone extends com.android.internal.telephony.PhoneBase
{@hide}

Fields Summary
static final String
LOG_TAG
private static final boolean
LOCAL_DEBUG
public static final String
NETWORK_SELECTION_KEY
public static final String
DATA_DISABLED_ON_BOOT_KEY
public static final String
CIPHERING_KEY
public static final String
CLIR_KEY
public static final String
VM_NUMBER
public static final String
VM_SIM_IMSI
public static final String
DNS_SERVER_CHECK_DISABLED_KEY
CallTracker
mCT
ServiceStateTracker
mSST
CommandsInterface
mCM
SMSDispatcher
mSMS
DataConnectionTracker
mDataConnection
SIMFileHandler
mSIMFileHandler
SIMRecords
mSIMRecords
GsmSimCard
mSimCard
com.android.internal.telephony.gsm.stk.StkService
mStkService
MyHandler
h
ArrayList
mPendingMMIs
SimPhoneBookInterfaceManager
mSimPhoneBookIntManager
SimSmsInterfaceManager
mSimSmsIntManager
com.android.internal.telephony.PhoneSubInfo
mSubInfo
boolean
mDnsCheckDisabled
android.os.Registrant
mPostDialHandler
android.os.RegistrantList
mSsnRegistrants
List of Registrants to receive Supplementary Service Notifications.
Thread
debugPortThread
ServerSocket
debugSocket
private int
mReportedRadioResets
private int
mReportedAttemptedConnects
private int
mReportedSuccessfulConnects
private String
mImei
private String
mImeiSv
private String
mVmNumber
static final int
EVENT_RADIO_AVAILABLE
static final int
EVENT_SSN
Supplemnetary Service Notification received.
static final int
EVENT_SIM_RECORDS_LOADED
static final int
EVENT_MMI_DONE
static final int
EVENT_RADIO_ON
static final int
EVENT_GET_BASEBAND_VERSION_DONE
static final int
EVENT_USSD
static final int
EVENT_RADIO_OFF_OR_NOT_AVAILABLE
static final int
EVENT_GET_IMEI_DONE
static final int
EVENT_GET_IMEISV_DONE
static final int
EVENT_GET_SIM_STATUS_DONE
static final int
EVENT_SET_CALL_FORWARD_DONE
static final int
EVENT_GET_CALL_FORWARD_DONE
static final int
EVENT_CALL_RING
static final int
EVENT_SET_NETWORK_MANUAL_COMPLETE
static final int
EVENT_SET_NETWORK_AUTOMATIC_COMPLETE
static final int
EVENT_SET_CLIR_COMPLETE
static final int
EVENT_REGISTERED_TO_NETWORK
static final int
EVENT_SET_VM_NUMBER_DONE
Constructors Summary
public GSMPhone(android.content.Context context, CommandsInterface ci, com.android.internal.telephony.PhoneNotifier notifier)


    //***** Constructors

    
          
    
        this(context,ci,notifier, false);
    
public GSMPhone(android.content.Context context, CommandsInterface ci, com.android.internal.telephony.PhoneNotifier notifier, boolean unitTestMode)

        super(notifier, context, unitTestMode);

        h = new MyHandler();
        mCM = ci;

        if (ci instanceof SimulatedRadioControl) {
            mSimulatedRadioControl = (SimulatedRadioControl) ci;
        }

        mCT = new CallTracker(this);
        mSST = new ServiceStateTracker (this);
        mSMS = new SMSDispatcher(this);
        mSIMFileHandler = new SIMFileHandler(this);
        mSIMRecords = new SIMRecords(this);
        mDataConnection = new DataConnectionTracker (this);
        mSimCard = new GsmSimCard(this);
        if (!unitTestMode) {
            mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this);
            mSimSmsIntManager = new SimSmsInterfaceManager(this);
            mSubInfo = new PhoneSubInfo(this);
        }
        mStkService = StkService.getInstance(mCM, mSIMRecords, mContext,
                mSIMFileHandler, mSimCard);
                
        mCM.registerForAvailable(h, EVENT_RADIO_AVAILABLE, null);
        mSIMRecords.registerForRecordsLoaded(h, EVENT_SIM_RECORDS_LOADED, null);
        mCM.registerForOffOrNotAvailable(h, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, 
                                                    null);
        mCM.registerForOn(h, EVENT_RADIO_ON, null);
        mCM.setOnUSSD(h, EVENT_USSD, null);
        mCM.setOnSuppServiceNotification(h, EVENT_SSN, null);
        mCM.setOnCallRing(h, EVENT_CALL_RING, null);
        mSST.registerForNetworkAttach(h, EVENT_REGISTERED_TO_NETWORK, null);

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);

        if (false) {
            try {
                //debugSocket = new LocalServerSocket("com.android.internal.telephony.debug");
                debugSocket = new ServerSocket();
                debugSocket.setReuseAddress(true);
                debugSocket.bind (new InetSocketAddress("127.0.0.1", 6666));

                debugPortThread
                    = new Thread(
                        new Runnable() {
                            public void run() {
                                for(;;) {
                                    try {
                                        Socket sock;
                                        sock = debugSocket.accept();
                                        Log.i(LOG_TAG, "New connection; resetting radio");
                                        mCM.resetRadio(null);
                                        sock.close();
                                    } catch (IOException ex) {
                                        Log.w(LOG_TAG, 
                                            "Exception accepting socket", ex);
                                    }
                                }
                            }
                        },
                        "GSMPhone debug");

                debugPortThread.start();

            } catch (IOException ex) {
                Log.w(LOG_TAG, "Failure to open com.android.internal.telephony.debug socket", ex);
            }
        }
    
Methods Summary
public voidacceptCall()

        mCT.acceptCall();
    
public booleancanConference()

        return mCT.canConference();
    
public booleancanDial()

        return mCT.canDial();
    
public booleancanTransfer()

        return mCT.canTransfer();
    
public voidclearDisconnected()

    
        mCT.clearDisconnected();
    
public voidconference()

        mCT.conference();
    
public com.android.internal.telephony.Connectiondial(java.lang.String dialString)

        // Need to make sure dialString gets parsed properly
        String newDialString = PhoneNumberUtils.stripSeparators(dialString);

        // handle in-call MMI first if applicable
        if (handleInCallMmiCommands(newDialString)) {
            return null;
        }

        // Only look at the Network portion for mmi
        String networkPortion = PhoneNumberUtils.extractNetworkPortion(newDialString);
        GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this);
        if (LOCAL_DEBUG) Log.d(LOG_TAG,
                               "dialing w/ mmi '" + mmi + "'...");

        if (mmi == null) {
            return mCT.dial(newDialString);
        } else if (mmi.isTemporaryModeCLIR()) {
            return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode());
        } else {
            mPendingMMIs.add(mmi);
            mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
            mmi.processCode();

            // FIXME should this return null or something else?
            return null;
        }
    
public intdisableApnType(java.lang.String type)

        return mDataConnection.disableApnType(type);
    
public booleandisableDataConnectivity()

        return mDataConnection.setDataEnabled(false);
    
public voiddisableDnsCheck(boolean b)
Disables the DNS check (i.e., allows "0.0.0.0"). Useful for lab testing environment.

param
b true disables the check, false enables.

        mDnsCheckDisabled = b;
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);        
        editor.commit();
    
public voiddisableLocationUpdates()

        mSST.disableLocationUpdates();
    
public intenableApnType(java.lang.String type)

        return mDataConnection.enableApnType(type);
    
public booleanenableDataConnectivity()

        return mDataConnection.setDataEnabled(true);
    
public voidenableLocationUpdates()

        mSST.enableLocationUpdates();
    
public voidexplicitCallTransfer()

        mCT.explicitCallTransfer();
    
public java.lang.StringgetActiveApn()

        return mDataConnection.getActiveApnString();
    
public java.lang.String[]getActiveApnTypes()

        return mDataConnection.getActiveApnTypes();
    
public voidgetAvailableNetworks(android.os.Message response)

        mCM.getAvailableNetworks(response);
    
public com.android.internal.telephony.CallgetBackgroundCall()

        return mCT.backgroundCall;
    
public booleangetCallForwardingIndicator()

        return mSIMRecords.getVoiceCallForwardingFlag();
    
public voidgetCallForwardingOption(int commandInterfaceCFReason, android.os.Message onComplete)

        
        if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) {
            if (LOCAL_DEBUG) Log.d(LOG_TAG, "requesting call forwarding query.");
            Message resp;
            if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
                resp = h.obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete);
            } else {
                resp = onComplete;
            }
            mCM.queryCallForwardStatus(commandInterfaceCFReason,0,null,resp);
        }
    
public voidgetCallWaiting(android.os.Message onComplete)

        mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
    
public android.telephony.CellLocationgetCellLocation()

        return mSST.cellLoc;
    
public java.util.ListgetCurrentPdpList()

        return mDataConnection.getAllPdps();
    
public DataActivityStategetDataActivityState()

        DataActivityState ret = DataActivityState.NONE;

        if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) {
            switch (mDataConnection.activity) {

            case DATAIN:
                ret = DataActivityState.DATAIN;
            break;

            case DATAOUT:
                ret = DataActivityState.DATAOUT;
            break;

            case DATAINANDOUT:
                ret = DataActivityState.DATAINANDOUT;
            break;
            }
        }

        return ret;
    
public DataStategetDataConnectionState()

        DataState ret = DataState.DISCONNECTED;

        if ((SystemProperties.get("adb.connected", "").length() > 0)
                && (SystemProperties.get("android.net.use-adb-networking", "")
                .length() > 0)) {
            // We're connected to an ADB host and we have USB networking
            // turned on. No matter what the radio state is,
            // we report data connected

            ret = DataState.CONNECTED;
        } else if (mSST.getCurrentGprsState()
                != ServiceState.STATE_IN_SERVICE) {
            // If we're out of service, open TCP sockets may still work
            // but no data will flow
            ret = DataState.DISCONNECTED;
        } else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */
            switch (mDataConnection.state) {
            case FAILED:
            case IDLE:
                ret = DataState.DISCONNECTED;
            break;

            case CONNECTED:
            case DISCONNECTING:
                if ( mCT.state != Phone.State.IDLE
                        && !mSST.isConcurrentVoiceAndData()) {
                    ret = DataState.SUSPENDED;
                } else {
                    ret = DataState.CONNECTED;
                }
            break;

            case INITING:
            case CONNECTING:
            case SCANNING:
                ret = DataState.CONNECTING;
            break;
            }
        }

        return ret;
    
public booleangetDataRoamingEnabled()

        return mDataConnection.getDataOnRoamingEnabled();
    
public java.lang.StringgetDeviceId()

        return mImei;
    
public java.lang.StringgetDeviceSvn()

        return mImeiSv;
    
public java.lang.String[]getDnsServers(java.lang.String apnType)

        return mDataConnection.getDnsServers(apnType);
    
public com.android.internal.telephony.CallgetForegroundCall()

        return mCT.foregroundCall;
    
public java.lang.StringgetGateway(java.lang.String apnType)

        return mDataConnection.getGateway(apnType);
    
public java.lang.StringgetInterfaceName(java.lang.String apnType)

        return mDataConnection.getInterfaceName(apnType);
    
public java.lang.StringgetIpAddress(java.lang.String apnType)

        return mDataConnection.getIpAddress(apnType);
    
public java.lang.StringgetLine1AlphaTag()

        String ret;

        ret = mSIMRecords.getMsisdnAlphaTag();

        if (ret == null || ret.length() == 0) {
            return mContext.getText(
                    com.android.internal.R.string.defaultMsisdnAlphaTag).toString();
        }

        return ret;
    
public java.lang.StringgetLine1Number()

        return mSIMRecords.getMsisdnNumber();
    
public booleangetMessageWaitingIndicator()

        return mSIMRecords.getVoiceMessageWaiting();
    
public booleangetMute()

        return mCT.getMute();
    
public voidgetNeighboringCids(android.os.Message response)

        mCM.getNeighboringCids(response);
    
public voidgetOutgoingCallerIdDisplay(android.os.Message onComplete)

        mCM.getCLIR(onComplete);
    
public voidgetPdpContextList(android.os.Message response)

        mCM.getPDPContextList(response);
    
public java.util.ListgetPendingMmiCodes()

        return mPendingMMIs;
    
public java.lang.StringgetPhoneName()

        return "GSM";
    
public voidgetPreferredNetworkType(android.os.Message response)

        mCM.getPreferredNetworkType(response);
    
public com.android.internal.telephony.CallgetRingingCall()

        return mCT.ringingCall;
    
private java.lang.StringgetSavedNetworkSelection()
Method to retrieve the saved operator id from the Shared Preferences

        // open the shared preferences and search with our key. 
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        return sp.getString(NETWORK_SELECTION_KEY, "");
    
public android.telephony.ServiceStategetServiceState()

        return mSST.ss;
    
public intgetSignalStrengthASU()

        return mSST.rssi == 99 ? -1 : mSST.rssi;
    
public com.android.internal.telephony.SimCardgetSimCard()

        return mSimCard;
    
public booleangetSimRecordsLoaded()

        return mSIMRecords.getRecordsLoaded();
    
public java.lang.StringgetSimSerialNumber()

        return mSIMRecords.iccid;
    
public Phone.StategetState()

        return mCT.state;
    
public java.lang.StringgetSubscriberId()

        return mSIMRecords.imsi;
    
private java.lang.StringgetVmSimImsi()

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        return sp.getString(VM_SIM_IMSI, null);
    
public java.lang.StringgetVoiceMailAlphaTag()

        String ret;

        ret = mSIMRecords.getVoiceMailAlphaTag();

        if (ret == null || ret.length() == 0) {
            return mContext.getText(
                com.android.internal.R.string.defaultVoiceMailAlphaTag).toString();
        }

        return ret;        
    
public java.lang.StringgetVoiceMailNumber()

        // Read from the SIM. If its null, try reading from the shared preference area.
        String number = mSIMRecords.getVoiceMailNumber();        
        if (TextUtils.isEmpty(number)) {
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
            number = sp.getString(VM_NUMBER, null);
        }        
        return number;
    
private booleanhandleCallDeflectionIncallSupplementaryService(java.lang.String dialString)

        if (dialString.length() > 1) {
            return false;
        }

        if (getRingingCall().getState() != Call.State.IDLE) {
            if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 0: rejectCall");
            try {
                mCT.rejectCall();
            } catch (CallStateException e) {
                if (LOCAL_DEBUG) Log.d(LOG_TAG,
                    "reject failed", e);
                notifySuppServiceFailed(Phone.SuppService.REJECT);
            }
        } else if (getBackgroundCall().getState() != Call.State.IDLE) {
            if (LOCAL_DEBUG) Log.d(LOG_TAG,
                    "MmiCode 0: hangupWaitingOrBackground");
            mCT.hangupWaitingOrBackground();
        }

        return true;
    
private booleanhandleCallHoldIncallSupplementaryService(java.lang.String dialString)

        int len = dialString.length();

        if (len > 2) {
            return false;
        }

        GSMCall call = (GSMCall) getForegroundCall();

        if (len > 1) {
            try {
                char ch = dialString.charAt(1);
                int callIndex = ch - '0";
                GSMConnection conn = mCT.getConnectionByIndex(call, callIndex);
                
                // gsm index starts at 1, up to 5 connections in a call,
                if (conn != null && callIndex >= 1 && callIndex <= CallTracker.MAX_CONNECTIONS) {
                    if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 2: separate call "+
                            callIndex);
                    mCT.separate(conn);
                } else {
                    if (LOCAL_DEBUG) Log.d(LOG_TAG, "separate: invalid call index "+
                            callIndex);
                    notifySuppServiceFailed(Phone.SuppService.SEPARATE);
                }
            } catch (CallStateException e) {
                if (LOCAL_DEBUG) Log.d(LOG_TAG,
                    "separate failed", e);
                notifySuppServiceFailed(Phone.SuppService.SEPARATE);
            }
        } else {
            try {
                if (getRingingCall().getState() != Call.State.IDLE) {
                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
                    "MmiCode 2: accept ringing call");
                    mCT.acceptCall();
                } else {
                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
                    "MmiCode 2: switchWaitingOrHoldingAndActive");
                    mCT.switchWaitingOrHoldingAndActive();
                }
            } catch (CallStateException e) {
                if (LOCAL_DEBUG) Log.d(LOG_TAG,
                    "switch failed", e);
                notifySuppServiceFailed(Phone.SuppService.SWITCH);
            }
        }

        return true;
    
private booleanhandleCallWaitingIncallSupplementaryService(java.lang.String dialString)

        int len = dialString.length();

        if (len > 2) {
            return false;
        }

        GSMCall call = (GSMCall) getForegroundCall();

        try {
            if (len > 1) {
                char ch = dialString.charAt(1);
                int callIndex = ch - '0";

                if (callIndex >= 1 && callIndex <= CallTracker.MAX_CONNECTIONS) {
                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
                            "MmiCode 1: hangupConnectionByIndex " +
                            callIndex);
                    mCT.hangupConnectionByIndex(call, callIndex);
                }
            } else {
                if (call.getState() != Call.State.IDLE) {
                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
                            "MmiCode 1: hangup foreground");
                    //mCT.hangupForegroundResumeBackground();
                    mCT.hangup(call);
                } else {
                    if (LOCAL_DEBUG) Log.d(LOG_TAG,
                            "MmiCode 1: switchWaitingOrHoldingAndActive");
                    mCT.switchWaitingOrHoldingAndActive();
                }
            }
        } catch (CallStateException e) {
            if (LOCAL_DEBUG) Log.d(LOG_TAG,
                "hangup failed", e);
            notifySuppServiceFailed(Phone.SuppService.HANGUP);
        }

        return true;
    
private booleanhandleCcbsIncallSupplementaryService(java.lang.String dialString)

        if (dialString.length() > 1) {
            return false;
        }

        Log.i(LOG_TAG, "MmiCode 5: CCBS not supported!");
        // Treat it as an "unknown" service.
        notifySuppServiceFailed(Phone.SuppService.UNKNOWN);
        return true;
    
private voidhandleCfuQueryResult(CallForwardInfo[] infos)

        if (infos == null || infos.length == 0) {
            // Assume the default is not active
            // Set unconditional CFF in SIM to false
            mSIMRecords.setVoiceCallForwardingFlag(1, false);
        } else {
            for (int i = 0, s = infos.length; i < s; i++) {
                if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
                    mSIMRecords.setVoiceCallForwardingFlag(1, (infos[i].status == 1));
                    // should only have the one
                    break;
                }
            }
        }
    
private booleanhandleEctIncallSupplementaryService(java.lang.String dialString)


        int len = dialString.length();

        if (len != 1) {
            return false;
        }

        if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 4: explicit call transfer");
        try {
            explicitCallTransfer();
        } catch (CallStateException e) {
            if (LOCAL_DEBUG) Log.d(LOG_TAG,
                "transfer failed", e);
            notifySuppServiceFailed(Phone.SuppService.TRANSFER);
        }
        return true;
    
public booleanhandleInCallMmiCommands(java.lang.String dialString)

        if (!isInCall()) {
            return false;
        }

        if (TextUtils.isEmpty(dialString)) {
            return false;
        }

        boolean result = false;
        char ch = dialString.charAt(0);
        switch (ch) {
            case '0":
                result = handleCallDeflectionIncallSupplementaryService(
                        dialString);
                break;
            case '1":
                result = handleCallWaitingIncallSupplementaryService(
                        dialString);
                break;
            case '2":
                result = handleCallHoldIncallSupplementaryService(dialString);
                break;
            case '3":
                result = handleMultipartyIncallSupplementaryService(dialString);
                break;
            case '4":
                result = handleEctIncallSupplementaryService(dialString);
                break;
            case '5":
                result = handleCcbsIncallSupplementaryService(dialString);
                break;
            default:
                break;
        }

        return result;
    
private booleanhandleMultipartyIncallSupplementaryService(java.lang.String dialString)

        if (dialString.length() > 1) {
            return false;
        }

        if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 3: merge calls");
        try {
            conference();
        } catch (CallStateException e) {
            if (LOCAL_DEBUG) Log.d(LOG_TAG,
                "conference failed", e);
            notifySuppServiceFailed(Phone.SuppService.CONFERENCE);
        }
        return true;
    
public booleanhandlePinMmi(java.lang.String dialString)

        GsmMmiCode mmi = GsmMmiCode.newFromDialString(dialString, this);
        
        if (mmi != null && mmi.isPinCommand()) {
            mPendingMMIs.add(mmi);
            mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
            mmi.processCode();
            return true;
        }
        
        return false;        
    
private voidhandleSetSelectNetwork(android.os.AsyncResult ar)
Used to track the settings upon completion of the network change.

        // look for our wrapper within the asyncresult, skip the rest if it 
        // is null. 
        if (!(ar.userObj instanceof NetworkSelectMessage)) {
            if (LOCAL_DEBUG) Log.d(LOG_TAG, "unexpected result from user object.");
            return;
        }
        
        NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
        
        // found the object, now we send off the message we had originally
        // attached to the request. 
        if (nsm.message != null) {
            if (LOCAL_DEBUG) Log.d(LOG_TAG, "sending original message to recipient");
            AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
            nsm.message.sendToTarget();
        }
        
        // open the shared preferences editor, and write the value.
        // nsm.operatorNumeric is "" if we're in automatic.selection.
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric);
        
        // commit and log the result.
        if (! editor.commit()) {
            Log.e(LOG_TAG, "failed to commit network selection preference");
        }

    
public voidinvokeOemRilRequestRaw(byte[] data, android.os.Message response)

        mCM.invokeOemRilRequestRaw(data, response);
    
public voidinvokeOemRilRequestStrings(java.lang.String[] strings, android.os.Message response)

        mCM.invokeOemRilRequestStrings(strings, response);
    
private booleanisCfEnable(int action)

        return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION);
    
public booleanisDataConnectivityPossible()
The only circumstances under which we report that data connectivity is not possible are
  • Data roaming is disallowed and we are roaming.
  • The current data state is {@code DISCONNECTED} for a reason other than having explicitly disabled connectivity. In other words, data is not available because the phone is out of coverage or some like reason.

return
{@code true} if data connectivity is possible, {@code false} otherwise.

        // TODO: Currently checks if any GPRS connection is active. Should it only
        // check for "default"?
        boolean noData = mDataConnection.getDataEnabled() &&
            getDataConnectionState() == DataState.DISCONNECTED;
        return !noData && getSimCard().getState() == SimCard.State.READY &&
                getServiceState().getState() == ServiceState.STATE_IN_SERVICE &&
            (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming());
    
public booleanisDnsCheckDisabled()
Returns true if the DNS check is currently disabled.

        return mDnsCheckDisabled;
    
booleanisInCall()

        Call.State foregroundCallState = getForegroundCall().getState();
        Call.State backgroundCallState = getBackgroundCall().getState();
        Call.State ringingCallState = getRingingCall().getState();

       return (foregroundCallState.isAlive() ||
                backgroundCallState.isAlive() ||
                ringingCallState.isAlive());
    
private booleanisValidCommandInterfaceCFAction(int commandInterfaceCFAction)

        switch (commandInterfaceCFAction) {
            case CF_ACTION_DISABLE:
            case CF_ACTION_ENABLE:
            case CF_ACTION_REGISTRATION:
            case CF_ACTION_ERASURE:
                return true;
            default:
                return false;
        }
    
private booleanisValidCommandInterfaceCFReason(int commandInterfaceCFReason)

        switch (commandInterfaceCFReason) {
            case CF_REASON_UNCONDITIONAL:
            case CF_REASON_BUSY:
            case CF_REASON_NO_REPLY:
            case CF_REASON_NOT_REACHABLE:
            case CF_REASON_ALL:
            case CF_REASON_ALL_CONDITIONAL:
                return true;
            default:
                return false;
        }
    
voidnotifyCallForwardingIndicator()

        mNotifier.notifyCallForwardingChanged(this);
    
voidnotifyCallStateChanged()
Notifies registrants (ie, activities in the Phone app) about changes to call state (including Phone and Connection changes).

        /* we'd love it if this was package-scoped*/
        super.notifyCallStateChangedP();
    
voidnotifyDataActivity()

        mNotifier.notifyDataActivity(this);
    
voidnotifyDataConnection(java.lang.String reason)

        mNotifier.notifyDataConnection(this, reason);
    
voidnotifyDataConnectionFailed(java.lang.String reason)

        mNotifier.notifyDataConnectionFailed(this, reason);
    
voidnotifyDisconnect(com.android.internal.telephony.Connection cn)

        mDisconnectRegistrants.notifyResult(cn);
    
voidnotifyIncomingRing()
Notifiy registrants of a RING event.

    
        AsyncResult ar = new AsyncResult(null, this, null);
        mIncomingRingRegistrants.notifyRegistrants(ar);
    
voidnotifyLocationChanged()

        mNotifier.notifyCellLocation(this);
    
voidnotifyMessageWaitingIndicator()

        mNotifier.notifyMessageWaitingChanged(this);
    
voidnotifyNewRingingConnection(com.android.internal.telephony.Connection c)

        /* we'd love it if this was package-scoped*/
        super.notifyNewRingingConnectionP(c);
    
voidnotifyPhoneStateChanged()
Notify any interested party of a Phone state change.

        mNotifier.notifyPhoneState(this);
    
voidnotifyServiceStateChanged(android.telephony.ServiceState ss)

        super.notifyServiceStateChangedP(ss);
    
voidnotifySignalStrength()

        mNotifier.notifySignalStrength(this);
    
voidnotifySuppServiceFailed(SuppService code)

        mSuppServiceFailedRegistrants.notifyResult(code);
    
voidnotifyUnknownConnection()

        mUnknownConnectionRegistrants.notifyResult(this);
    
private voidonIncomingUSSD(int ussdMode, java.lang.String ussdMessage)
ussdMode is one of CommandsInterface.USSD_MODE_*

        boolean isUssdError;
        boolean isUssdRequest;
        
        isUssdRequest 
            = (ussdMode == CommandsInterface.USSD_MODE_REQUEST);

        isUssdError 
            = (ussdMode != CommandsInterface.USSD_MODE_NOTIFY
                && ussdMode != CommandsInterface.USSD_MODE_REQUEST);
    
        // See comments in GsmMmiCode.java
        // USSD requests aren't finished until one
        // of these two events happen
        GsmMmiCode found = null;
        for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
            if(mPendingMMIs.get(i).isPendingUSSD()) {
                found = mPendingMMIs.get(i);
                break;
            }
        }

        if (found != null) {
            // Complete pending USSD

            if (isUssdError) {
                found.onUssdFinishedError();
            } else {
                found.onUssdFinished(ussdMessage, isUssdRequest);
            }
        } else { // pending USSD not found
            // The network may initiate its own USSD request

            // ignore everything that isnt a Notify or a Request
            // also, discard if there is no message to present
            if (!isUssdError && ussdMessage != null) {
                GsmMmiCode mmi;
                mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage, 
                                                   isUssdRequest,
                                                   GSMPhone.this);
                onNetworkInitiatedUssd(mmi);
            }
        }
    
voidonMMIDone(GsmMmiCode mmi)
Removes the given MMI from the pending list and notifies registrants that it is complete.

param
mmi MMI that is done

        /* Only notify complete if it's on the pending list. 
         * Otherwise, it's already been handled (eg, previously canceled).
         * The exception is cancellation of an incoming USSD-REQUEST, which is
         * not on the list.
         */
        if (mPendingMMIs.remove(mmi) || mmi.isUssdRequest()) {
            mMmiCompleteRegistrants.notifyRegistrants(
                new AsyncResult(null, mmi, null));
        }
    
private voidonNetworkInitiatedUssd(GsmMmiCode mmi)

        mMmiCompleteRegistrants.notifyRegistrants(
            new AsyncResult(null, mmi, null));
    
public voidqueryAvailableBandMode(android.os.Message response)

        mCM.queryAvailableBandMode(response);
    
public voidregisterForSuppServiceNotification(android.os.Handler h, int what, java.lang.Object obj)

        mSsnRegistrants.addUnique(h, what, obj);
        if (mSsnRegistrants.size() == 1) mCM.setSuppServiceNotifications(true, null);
    
public voidrejectCall()

        mCT.rejectCall();
    
voidrestoreSavedNetworkSelection(android.os.Message response)
Method to restore the previously saved operator id, or reset to automatic selection, all depending upon the value in the shared preferences.

        // retrieve the operator id
        String networkSelection = getSavedNetworkSelection();
        
        // set to auto if the id is empty, otherwise select the network.
        if (TextUtils.isEmpty(networkSelection)) {
            mCM.setNetworkSelectionModeAutomatic(response);
        } else {
            mCM.setNetworkSelectionModeManual(networkSelection, response);
        }
    
voidsaveClirSetting(int commandInterfaceCLIRMode)
Saves CLIR setting so that we can re-apply it as necessary (in case the RIL resets it across reboots).

        // open the shared preferences editor, and write the value.
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt(CLIR_KEY, commandInterfaceCLIRMode);
        
        // commit and log the result.
        if (! editor.commit()) {
            Log.e(LOG_TAG, "failed to commit CLIR preference");
        }

    
public voidselectNetworkManually(com.android.internal.telephony.gsm.NetworkInfo network, android.os.Message response)

        // wrap the response message in our own message along with
        // the operator's id.
        NetworkSelectMessage nsm = new NetworkSelectMessage();
        nsm.message = response;
        nsm.operatorNumeric = network.operatorNumeric;
        
        // get the message
        Message msg = h.obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);

        mCM.setNetworkSelectionModeManual(network.operatorNumeric, msg);
    
public voidsendDtmf(char c)

        if (!PhoneNumberUtils.is12Key(c)) {
            Log.e(LOG_TAG, 
                    "sendDtmf called with invalid character '" + c + "'");
        } else {
            if (mCT.state ==  Phone.State.OFFHOOK) {
                mCM.sendDtmf(c, null);
            }
        }
    
public voidsendUssdResponse(java.lang.String ussdMessge)

        GsmMmiCode mmi = GsmMmiCode.newFromUssdUserInput(ussdMessge, this);
        mPendingMMIs.add(mmi);
        mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
        mmi.sendUssd(ussdMessge);
    
public voidsetBandMode(int bandMode, android.os.Message response)

        mCM.setBandMode(bandMode, response);
    
public voidsetCallForwardingOption(int commandInterfaceCFAction, int commandInterfaceCFReason, java.lang.String dialingNumber, int timerSeconds, android.os.Message onComplete)

            
        if ((isValidCommandInterfaceCFAction(commandInterfaceCFAction)) && 
            (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) {
            
            Message resp;
            if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
                resp = h.obtainMessage(EVENT_SET_CALL_FORWARD_DONE,
                        isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, onComplete);
            } else {
                resp = onComplete;
            }
            mCM.setCallForward(commandInterfaceCFAction,
                    commandInterfaceCFReason,
                    CommandsInterface.SERVICE_CLASS_VOICE,
                    dialingNumber,
                    timerSeconds,
                    resp);
        }
    
public voidsetCallWaiting(boolean enable, android.os.Message onComplete)

        mCM.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
    
public voidsetDataRoamingEnabled(boolean enable)

        mDataConnection.setDataOnRoamingEnabled(enable);
    
public voidsetLine1Number(java.lang.String alphaTag, java.lang.String number, android.os.Message onComplete)

        mSIMRecords.setMsisdnNumber(alphaTag, number, onComplete);
    
public voidsetMute(boolean muted)

        mCT.setMute(muted);
    
public voidsetNetworkSelectionModeAutomatic(android.os.Message response)

        // wrap the response message in our own message along with
        // an empty string (to indicate automatic selection) for the 
        // operator's id.
        NetworkSelectMessage nsm = new NetworkSelectMessage();
        nsm.message = response;
        nsm.operatorNumeric = "";
        
        // get the message
        Message msg = h.obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
        if (LOCAL_DEBUG) 
            Log.d(LOG_TAG, "wrapping and sending message to connect automatically");

        mCM.setNetworkSelectionModeAutomatic(msg);
    
public voidsetOnPostDialCharacter(android.os.Handler h, int what, java.lang.Object obj)

        mPostDialHandler = new Registrant(h, what, obj);
    
public voidsetOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, android.os.Message onComplete)

        mCM.setCLIR(commandInterfaceCLIRMode,
                h.obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete));
    
public voidsetPreferredNetworkType(int networkType, android.os.Message response)

        mCM.setPreferredNetworkType(networkType, response);
    
public voidsetRadioPower(boolean power)

        mSST.setRadioPower(power);
    
voidsetSystemProperty(java.lang.String property, java.lang.String value)
Set a system property, unless we're in unit test mode

        if(getUnitTestMode()) {
            return;
        }
        SystemProperties.set(property, value);
    
private voidsetVmSimImsi(java.lang.String imsi)

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(VM_SIM_IMSI, imsi);
        editor.commit();
    
public voidsetVoiceMailNumber(java.lang.String alphaTag, java.lang.String voiceMailNumber, android.os.Message onComplete)

        
        Message resp;        
        mVmNumber = voiceMailNumber;
        resp = h.obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
        mSIMRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
    
public voidsimulateDataConnection(Phone.DataState state)
simulateDataConnection simulates various data connection states. This messes with DataConnectionTracker's internal states, but doesn't actually change the underlying radio connection states.

param
state Phone.DataState enum.

        DataConnectionTracker.State dcState;

        switch (state) {
            case CONNECTED:
                dcState = DataConnectionTracker.State.CONNECTED;
                break;
            case SUSPENDED:
                dcState = DataConnectionTracker.State.CONNECTED;
                break;
            case DISCONNECTED:
                dcState = DataConnectionTracker.State.FAILED;
                break;
            default:
                dcState = DataConnectionTracker.State.CONNECTING;
                break;
        }

        mDataConnection.setState(dcState);
        notifyDataConnection(null);
    
public voidstartDtmf(char c)

        if (!PhoneNumberUtils.is12Key(c)) {
            Log.e(LOG_TAG,
                "startDtmf called with invalid character '" + c + "'");
        } else {
            mCM.startDtmf(c, null);
        }
    
public voidstopDtmf()

        mCM.stopDtmf(null);
    
private voidstoreVoiceMailNumber(java.lang.String number)

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(VM_NUMBER, number);        
        editor.commit();
        setVmSimImsi(getSubscriberId());
    
public voidswitchHoldingAndActive()

        mCT.switchWaitingOrHoldingAndActive();
    
private voidsyncClirSetting()
Make sure the network knows our preferred setting.

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        int clirSetting = sp.getInt(CLIR_KEY, -1);
        if (clirSetting >= 0) {
            mCM.setCLIR(clirSetting, null);
        }
    
public voidunregisterForSuppServiceNotification(android.os.Handler h)

        mSsnRegistrants.remove(h);
        if (mSsnRegistrants.size() == 0) mCM.setSuppServiceNotifications(false, null);
    
booleanupdateCurrentCarrierInProvider()
Sets the "current" field in the telephony provider according to the SIM's operator

return
true for success; false otherwise.

        if (mSIMRecords != null) {
            try {
                Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
                ContentValues map = new ContentValues();
                map.put(Telephony.Carriers.NUMERIC, mSIMRecords.getSIMOperatorNumeric());
                mContext.getContentResolver().insert(uri, map);
                return true;
            } catch (SQLException e) {
                Log.e(LOG_TAG, "Can't store current operator", e);
            }
        }
        return false;
    
voidupdateMessageWaitingIndicator(boolean mwi)

        // this also calls notifyMessageWaitingIndicator()
        mSIMRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0);
    
public voidupdateServiceLocation(android.os.Message response)

        mSST.getLacAndCid(response);