FileDocCategorySizeDatePackage
ServiceStateTracker.javaAPI DocAndroid 5.1 API44380Thu Mar 12 22:22:54 GMT 2015com.android.internal.telephony

ServiceStateTracker

public abstract class ServiceStateTracker extends android.os.Handler
{@hide}

Fields Summary
private static final String
LOG_TAG
protected static final boolean
DBG
protected static final boolean
VDBG
protected static final String
PROP_FORCE_ROAMING
protected CommandsInterface
mCi
protected com.android.internal.telephony.uicc.UiccController
mUiccController
protected com.android.internal.telephony.uicc.UiccCardApplication
mUiccApplcation
protected com.android.internal.telephony.uicc.IccRecords
mIccRecords
protected PhoneBase
mPhoneBase
protected boolean
mVoiceCapable
public android.telephony.ServiceState
mSS
protected android.telephony.ServiceState
mNewSS
private static final long
LAST_CELL_INFO_LIST_MAX_AGE_MS
protected long
mLastCellInfoListTime
protected List
mLastCellInfoList
protected final android.telephony.CellInfo
mCellInfo
protected android.telephony.SignalStrength
mSignalStrength
public RestrictedState
mRestrictedState
public static final int
OTASP_UNINITIALIZED
public static final int
OTASP_UNKNOWN
public static final int
OTASP_NEEDED
public static final int
OTASP_NOT_NEEDED
protected int[]
mPollingContext
A unique identifier to track requests associated with a poll and ignore stale responses. The value is a count-down of expected responses in this pollingContext.
protected boolean
mDesiredPowerState
protected boolean
mDontPollSignalStrength
By default, strength polling is enabled. However, if we're getting unsolicited signal strength updates from the radio, set value to true and don't bother polling any more.
protected android.os.RegistrantList
mVoiceRoamingOnRegistrants
protected android.os.RegistrantList
mVoiceRoamingOffRegistrants
protected android.os.RegistrantList
mDataRoamingOnRegistrants
protected android.os.RegistrantList
mDataRoamingOffRegistrants
protected android.os.RegistrantList
mAttachedRegistrants
protected android.os.RegistrantList
mDetachedRegistrants
protected android.os.RegistrantList
mDataRegStateOrRatChangedRegistrants
protected android.os.RegistrantList
mNetworkAttachedRegistrants
protected android.os.RegistrantList
mPsRestrictEnabledRegistrants
protected android.os.RegistrantList
mPsRestrictDisabledRegistrants
protected boolean
mPendingRadioPowerOffAfterDataOff
protected int
mPendingRadioPowerOffAfterDataOffTag
protected static final int
POLL_PERIOD_MILLIS
Signal strength poll rate.
public static final int
DEFAULT_GPRS_CHECK_PERIOD_MILLIS
Waiting period before recheck gprs and voice registration.
protected static final int
EVENT_RADIO_STATE_CHANGED
GSM events
protected static final int
EVENT_NETWORK_STATE_CHANGED
protected static final int
EVENT_GET_SIGNAL_STRENGTH
protected static final int
EVENT_POLL_STATE_REGISTRATION
protected static final int
EVENT_POLL_STATE_GPRS
protected static final int
EVENT_POLL_STATE_OPERATOR
protected static final int
EVENT_POLL_SIGNAL_STRENGTH
protected static final int
EVENT_NITZ_TIME
protected static final int
EVENT_SIGNAL_STRENGTH_UPDATE
protected static final int
EVENT_RADIO_AVAILABLE
protected static final int
EVENT_POLL_STATE_NETWORK_SELECTION_MODE
protected static final int
EVENT_GET_LOC_DONE
protected static final int
EVENT_SIM_RECORDS_LOADED
protected static final int
EVENT_SIM_READY
protected static final int
EVENT_LOCATION_UPDATES_ENABLED
protected static final int
EVENT_GET_PREFERRED_NETWORK_TYPE
protected static final int
EVENT_SET_PREFERRED_NETWORK_TYPE
protected static final int
EVENT_RESET_PREFERRED_NETWORK_TYPE
protected static final int
EVENT_CHECK_REPORT_GPRS
protected static final int
EVENT_RESTRICTED_STATE_CHANGED
protected static final int
EVENT_POLL_STATE_REGISTRATION_CDMA
CDMA events
protected static final int
EVENT_POLL_STATE_OPERATOR_CDMA
protected static final int
EVENT_RUIM_READY
protected static final int
EVENT_RUIM_RECORDS_LOADED
protected static final int
EVENT_POLL_SIGNAL_STRENGTH_CDMA
protected static final int
EVENT_GET_SIGNAL_STRENGTH_CDMA
protected static final int
EVENT_NETWORK_STATE_CHANGED_CDMA
protected static final int
EVENT_GET_LOC_DONE_CDMA
protected static final int
EVENT_NV_LOADED
protected static final int
EVENT_POLL_STATE_CDMA_SUBSCRIPTION
protected static final int
EVENT_NV_READY
protected static final int
EVENT_ERI_FILE_LOADED
protected static final int
EVENT_OTA_PROVISION_STATUS_CHANGE
protected static final int
EVENT_SET_RADIO_POWER_OFF
protected static final int
EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED
protected static final int
EVENT_CDMA_PRL_VERSION_CHANGED
protected static final int
EVENT_RADIO_ON
public static final int
EVENT_ICC_CHANGED
protected static final int
EVENT_GET_CELL_INFO_LIST
protected static final int
EVENT_UNSOL_CELL_INFO_LIST
protected static final int
EVENT_CHANGE_IMS_STATE
protected static final int
EVENT_IMS_STATE_CHANGED
protected static final int
EVENT_IMS_STATE_DONE
protected static final String
TIMEZONE_PROPERTY
protected static final String[]
GMT_COUNTRY_CODES
List of ISO codes for countries that can have an offset of GMT+0 when not in daylight savings time. This ignores some small places such as the Canary Islands (Spain) and Danmarkshavn (Denmark). The list must be sorted by code.
protected static final String
REGISTRATION_DENIED_GEN
Reason for registration denial.
protected static final String
REGISTRATION_DENIED_AUTH
protected boolean
mImsRegistrationOnOff
protected boolean
mAlarmSwitch
protected android.content.IntentFilter
mIntentFilter
protected android.app.PendingIntent
mRadioOffIntent
protected static final String
ACTION_RADIO_OFF
protected boolean
mPowerOffDelayNeed
protected boolean
mDeviceShuttingDown
protected boolean
mSpnUpdatePending
Keep track of SPN display rules, so we only broadcast intent if something changes.
protected String
mCurSpn
protected String
mCurPlmn
protected boolean
mCurShowPlmn
protected boolean
mCurShowSpn
private boolean
mImsRegistered
protected android.telephony.SubscriptionManager
mSubscriptionManager
protected SubscriptionController
mSubscriptionController
protected final SstSubscriptionsChangedListener
mOnSubscriptionsChangedListener
private android.telephony.SignalStrength
mLastSignalStrength
private boolean
mWantContinuousLocationUpdates
These two flags manage the behavior of the cell lock -- the lock should be held if either flag is true. The intention is to allow temporary acquisition of the lock to get a single update. Such a lock grab and release can thus be made to not interfere with more permanent lock holds -- in other words, the lock will only be released if both flags are false, and so releases by temporary users will only affect the lock state if there is no continuous user.
private boolean
mWantSingleLocationUpdate
Constructors Summary
protected ServiceStateTracker(PhoneBase phoneBase, CommandsInterface ci, android.telephony.CellInfo cellInfo)

        mPhoneBase = phoneBase;
        mCellInfo = cellInfo;
        mCi = ci;
        mVoiceCapable = mPhoneBase.getContext().getResources().getBoolean(
                com.android.internal.R.bool.config_voice_capable);
        mUiccController = UiccController.getInstance();
        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
        mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
        mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null);

        mSubscriptionController = SubscriptionController.getInstance();
        mSubscriptionManager = SubscriptionManager.from(phoneBase.getContext());
        mSubscriptionManager
            .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);

        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
            ServiceState.rilRadioTechnologyToString(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
        mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null);
    
Methods Summary
protected voidcancelPollState()
Cancel a pending (if any) pollState() operation

        // This will effectively cancel the rest of the poll requests.
        mPollingContext = new int[1];
    
protected voidcheckCorrectThread()
Verifies the current thread is the same as the thread originally used in the initialization of this instance. Throws RuntimeException if not.

exception
RuntimeException if the current thread is not the thread that originally obtained this PhoneBase instance.

        if (Thread.currentThread() != getLooper().getThread()) {
            throw new RuntimeException(
                    "ServiceStateTracker must be used from within one thread");
        }
    
public voiddisableLocationUpdates()

        mWantContinuousLocationUpdates = false;
        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
            mCi.setLocationUpdates(false, null);
        }
    
protected voiddisableSingleLocationUpdate()

        mWantSingleLocationUpdate = false;
        if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
            mCi.setLocationUpdates(false, null);
        }
    
public voiddispose()

        mCi.unSetOnSignalStrengthUpdate(this);
        mUiccController.unregisterForIccChanged(this);
        mCi.unregisterForCellInfoList(this);
        mSubscriptionManager
            .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        pw.println("ServiceStateTracker:");
        pw.println(" mSS=" + mSS);
        pw.println(" mNewSS=" + mNewSS);
        pw.println(" mCellInfo=" + mCellInfo);
        pw.println(" mRestrictedState=" + mRestrictedState);
        pw.println(" mPollingContext=" + mPollingContext);
        pw.println(" mDesiredPowerState=" + mDesiredPowerState);
        pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength);
        pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
        pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
        pw.flush();
    
public voidenableLocationUpdates()

        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
        mWantContinuousLocationUpdates = true;
        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
    
public voidenableSingleLocationUpdate()

        if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
        mWantSingleLocationUpdate = true;
        mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
    
public java.util.ListgetAllCellInfo()

return
all available cell information or null if none.

        CellInfoResult result = new CellInfoResult();
        if (VDBG) log("SST.getAllCellInfo(): E");
        int ver = mCi.getRilVersion();
        if (ver >= 8) {
            if (isCallerOnDifferentThread()) {
                if ((SystemClock.elapsedRealtime() - mLastCellInfoListTime)
                        > LAST_CELL_INFO_LIST_MAX_AGE_MS) {
                    Message msg = obtainMessage(EVENT_GET_CELL_INFO_LIST, result);
                    synchronized(result.lockObj) {
                        result.list = null;
                        mCi.getCellInfoList(msg);
                        try {
                            result.lockObj.wait(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    if (DBG) log("SST.getAllCellInfo(): return last, back to back calls");
                    result.list = mLastCellInfoList;
                }
            } else {
                if (DBG) log("SST.getAllCellInfo(): return last, same thread can't block");
                result.list = mLastCellInfoList;
            }
        } else {
            if (DBG) log("SST.getAllCellInfo(): not implemented");
            result.list = null;
        }
        synchronized(result.lockObj) {
            if (result.list != null) {
                if (DBG) log("SST.getAllCellInfo(): X size=" + result.list.size()
                        + " list=" + result.list);
                return result.list;
            } else {
                if (DBG) log("SST.getAllCellInfo(): X size=0 list=null");
                return null;
            }
        }
    
public abstract intgetCurrentDataConnectionState()

public booleangetDesiredPowerState()

        return mDesiredPowerState;
    
protected java.lang.StringgetHomeOperatorNumeric()

        return ((TelephonyManager) mPhoneBase.getContext().
                getSystemService(Context.TELEPHONY_SERVICE)).
                getSimOperatorNumericForPhone(mPhoneBase.getPhoneId());
    
protected abstract PhonegetPhone()

protected intgetPhoneId()

        return mPhoneBase.getPhoneId();
    
public android.telephony.SignalStrengthgetSignalStrength()

return
signal strength

        synchronized(mCellInfo) {
            return mSignalStrength;
        }
    
public java.lang.StringgetSystemProperty(java.lang.String property, java.lang.String defValue)

        return TelephonyManager.getTelephonyProperty(mPhoneBase.getPhoneId(), property, defValue);
    
public voidhandleMessage(android.os.Message msg)

        switch (msg.what) {
            case EVENT_SET_RADIO_POWER_OFF:
                synchronized(this) {
                    if (mPendingRadioPowerOffAfterDataOff &&
                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
                        hangupAndPowerOff();
                        mPendingRadioPowerOffAfterDataOffTag += 1;
                        mPendingRadioPowerOffAfterDataOff = false;
                    } else {
                        log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
                                "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
                    }
                }
                break;

            case EVENT_ICC_CHANGED:
                onUpdateIccAvailability();
                break;

            case EVENT_GET_CELL_INFO_LIST: {
                AsyncResult ar = (AsyncResult) msg.obj;
                CellInfoResult result = (CellInfoResult) ar.userObj;
                synchronized(result.lockObj) {
                    if (ar.exception != null) {
                        log("EVENT_GET_CELL_INFO_LIST: error ret null, e=" + ar.exception);
                        result.list = null;
                    } else {
                        result.list = (List<CellInfo>) ar.result;

                        if (VDBG) {
                            log("EVENT_GET_CELL_INFO_LIST: size=" + result.list.size()
                                    + " list=" + result.list);
                        }
                    }
                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
                    mLastCellInfoList = result.list;
                    result.lockObj.notify();
                }
                break;
            }

            case EVENT_UNSOL_CELL_INFO_LIST: {
                AsyncResult ar = (AsyncResult) msg.obj;
                if (ar.exception != null) {
                    log("EVENT_UNSOL_CELL_INFO_LIST: error ignoring, e=" + ar.exception);
                } else {
                    List<CellInfo> list = (List<CellInfo>) ar.result;
                    if (DBG) {
                        log("EVENT_UNSOL_CELL_INFO_LIST: size=" + list.size()
                                + " list=" + list);
                    }
                    mLastCellInfoListTime = SystemClock.elapsedRealtime();
                    mLastCellInfoList = list;
                    mPhoneBase.notifyCellInfo(list);
                }
                break;
            }

            case  EVENT_IMS_STATE_CHANGED: // received unsol
                mCi.getImsRegistrationState(this.obtainMessage(EVENT_IMS_STATE_DONE));
                break;

            case EVENT_IMS_STATE_DONE:
                AsyncResult ar = (AsyncResult) msg.obj;
                if (ar.exception == null) {
                    int[] responseArray = (int[])ar.result;
                    mImsRegistered = (responseArray[0] == 1) ? true : false;
                }
                break;

            default:
                log("Unhandled message with number: " + msg.what);
                break;
        }
    
protected abstract voidhandlePollStateResult(int what, android.os.AsyncResult ar)

protected abstract voidhangupAndPowerOff()
Hang up all voice call and turn off radio. Implemented by derived class.

protected booleaninSameCountry(java.lang.String operatorNumeric)
Check ISO country by MCC to see if phone is roaming in same registered country

        if (TextUtils.isEmpty(operatorNumeric) || (operatorNumeric.length() < 5)) {
            // Not a valid network
            return false;
        }
        final String homeNumeric = getHomeOperatorNumeric();
        if (TextUtils.isEmpty(homeNumeric) || (homeNumeric.length() < 5)) {
            // Not a valid SIM MCC
            return false;
        }
        boolean inSameCountry = true;
        final String networkMCC = operatorNumeric.substring(0, 3);
        final String homeMCC = homeNumeric.substring(0, 3);
        final String networkCountry = MccTable.countryCodeForMcc(Integer.parseInt(networkMCC));
        final String homeCountry = MccTable.countryCodeForMcc(Integer.parseInt(homeMCC));
        if (networkCountry.isEmpty() || homeCountry.isEmpty()) {
            // Not a valid country
            return false;
        }
        inSameCountry = homeCountry.equals(networkCountry);
        if (inSameCountry) {
            return inSameCountry;
        }
        // special same country cases
        if ("us".equals(homeCountry) && "vi".equals(networkCountry)) {
            inSameCountry = true;
        } else if ("vi".equals(homeCountry) && "us".equals(networkCountry)) {
            inSameCountry = true;
        }
        return inSameCountry;
    
protected booleanisCallerOnDifferentThread()

        boolean value = Thread.currentThread() != getLooper().getThread();
        if (VDBG) log("isCallerOnDifferentThread: " + value);
        return value;
    
public abstract booleanisConcurrentVoiceAndDataAllowed()

public booleanisImsRegistered()

        return mImsRegistered;
    
protected abstract voidlog(java.lang.String s)

protected abstract voidloge(java.lang.String s)

protected voidnotifyDataRegStateRilRadioTechnologyChanged()
Notify all mDataConnectionRatChangeRegistrants using an AsyncResult in msg.obj where AsyncResult#result contains the new RAT as an Integer Object.

        int rat = mSS.getRilDataRadioTechnology();
        int drs = mSS.getDataRegState();
        if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
        mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
                ServiceState.rilRadioTechnologyToString(rat));
        mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));
    
protected booleannotifySignalStrength()

       
        boolean notified = false;
        synchronized(mCellInfo) {
            if (!mSignalStrength.equals(mLastSignalStrength)) {
                try {
                    mPhoneBase.notifySignalStrength();
                    notified = true;
                } catch (NullPointerException ex) {
                    loge("updateSignalStrength() Phone already destroyed: " + ex
                            + "SignalStrength not notified");
                }
            }
        }
        return notified;
    
protected booleanonSignalStrengthResult(android.os.AsyncResult ar, boolean isGsm)
send signal-strength-changed notification if changed Called both for solicited and unsolicited signal strength updates

return
true if the signal strength changed and a notification was sent.

        SignalStrength oldSignalStrength = mSignalStrength;

        // This signal is used for both voice and data radio signal so parse
        // all fields

        if ((ar.exception == null) && (ar.result != null)) {
            mSignalStrength = (SignalStrength) ar.result;
            mSignalStrength.validateInput();
            mSignalStrength.setGsm(isGsm);
        } else {
            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
            mSignalStrength = new SignalStrength(isGsm);
        }

        return notifySignalStrength();
    
protected abstract voidonUpdateIccAvailability()

public abstract voidpollState()

public voidpowerOffRadioSafely(com.android.internal.telephony.dataconnection.DcTrackerBase dcTracker)
Clean up existing voice and data connection then turn off radio power. Hang up the existing voice calls to decrease call drop rate.

        synchronized (this) {
            if (!mPendingRadioPowerOffAfterDataOff) {
                // In some network, deactivate PDP connection cause releasing of RRC connection,
                // which MM/IMSI detaching request needs. Without this detaching, network can
                // not release the network resources previously attached.
                // So we are avoiding data detaching on these networks.
                String[] networkNotClearData = mPhoneBase.getContext().getResources()
                        .getStringArray(com.android.internal.R.array.networks_not_clear_data);
                String currentNetwork = mSS.getOperatorNumeric();
                if ((networkNotClearData != null) && (currentNetwork != null)) {
                    for (int i = 0; i < networkNotClearData.length; i++) {
                        if (currentNetwork.equals(networkNotClearData[i])) {
                            // Don't clear data connection for this carrier
                            if (DBG)
                                log("Not disconnecting data for " + currentNetwork);
                            hangupAndPowerOff();
                            return;
                        }
                    }
                }
                // To minimize race conditions we call cleanUpAllConnections on
                // both if else paths instead of before this isDisconnected test.
                if (dcTracker.isDisconnected()) {
                    // To minimize race conditions we do this after isDisconnected
                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
                    if (DBG) log("Data disconnected, turn off radio right away.");
                    hangupAndPowerOff();
                } else {
                    dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
                    Message msg = Message.obtain(this);
                    msg.what = EVENT_SET_RADIO_POWER_OFF;
                    msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
                    if (sendMessageDelayed(msg, 30000)) {
                        if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
                        mPendingRadioPowerOffAfterDataOff = true;
                    } else {
                        log("Cannot send delayed Msg, turn off radio right away.");
                        hangupAndPowerOff();
                    }
                }
            }
        }
    
public booleanprocessPendingRadioPowerOffAfterDataOff()
process the pending request to turn radio off after data is disconnected return true if there is pending request to process; false otherwise.

        synchronized(this) {
            if (mPendingRadioPowerOffAfterDataOff) {
                if (DBG) log("Process pending request to turn radio off.");
                mPendingRadioPowerOffAfterDataOffTag += 1;
                hangupAndPowerOff();
                mPendingRadioPowerOffAfterDataOff = false;
                return true;
            }
            return false;
        }
    
public voidreRegisterNetwork(android.os.Message onComplete)
Re-register network by toggling preferred network type. This is a work-around to deregister and register network since there is no ril api to set COPS=2 (deregister) only.

param
onComplete is dispatched when this is complete. it will be an AsyncResult, and onComplete.obj.exception will be non-null on failure.

        mCi.getPreferredNetworkType(
                obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
    
public voidregisterForDataConnectionAttached(android.os.Handler h, int what, java.lang.Object obj)
Registration point for transition into DataConnection attached.

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mAttachedRegistrants.add(r);

        if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
            r.notifyRegistrant();
        }
    
public voidregisterForDataConnectionDetached(android.os.Handler h, int what, java.lang.Object obj)
Registration point for transition into DataConnection detached.

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mDetachedRegistrants.add(r);

        if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
            r.notifyRegistrant();
        }
    
public voidregisterForDataRegStateOrRatChanged(android.os.Handler h, int what, java.lang.Object obj)
Registration for DataConnection RIL Data Radio Technology changing. The new radio technology will be returned AsyncResult#result as an Integer Object. The AsyncResult will be in the notification Message#obj.

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mDataRegStateOrRatChangedRegistrants.add(r);
        notifyDataRegStateRilRadioTechnologyChanged();
    
public voidregisterForDataRoamingOff(android.os.Handler h, int what, java.lang.Object obj)
Registration point for roaming off of mobile data combined roaming is true when roaming is true and ONS differs SPN

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mDataRoamingOffRegistrants.add(r);

        if (!mSS.getDataRoaming()) {
            r.notifyRegistrant();
        }
    
public voidregisterForDataRoamingOn(android.os.Handler h, int what, java.lang.Object obj)
Registration point for combined roaming on of mobile data combined roaming is true when roaming is true and ONS differs SPN

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mDataRoamingOnRegistrants.add(r);

        if (mSS.getDataRoaming()) {
            r.notifyRegistrant();
        }
    
public voidregisterForNetworkAttached(android.os.Handler h, int what, java.lang.Object obj)
Registration point for transition into network attached.

param
h handler to notify
param
what what code of message when delivered
param
obj in Message.obj

        Registrant r = new Registrant(h, what, obj);

        mNetworkAttachedRegistrants.add(r);
        if (mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
            r.notifyRegistrant();
        }
    
public voidregisterForPsRestrictedDisabled(android.os.Handler h, int what, java.lang.Object obj)
Registration point for transition out of packet service restricted zone.

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mPsRestrictDisabledRegistrants.add(r);

        if (mRestrictedState.isPsRestricted()) {
            r.notifyRegistrant();
        }
    
public voidregisterForPsRestrictedEnabled(android.os.Handler h, int what, java.lang.Object obj)
Registration point for transition into packet service restricted zone.

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mPsRestrictEnabledRegistrants.add(r);

        if (mRestrictedState.isPsRestricted()) {
            r.notifyRegistrant();
        }
    
public voidregisterForVoiceRoamingOff(android.os.Handler h, int what, java.lang.Object obj)
Registration point for roaming off of mobile voice combined roaming is true when roaming is true and ONS differs SPN

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mVoiceRoamingOffRegistrants.add(r);

        if (!mSS.getVoiceRoaming()) {
            r.notifyRegistrant();
        }
    
public voidregisterForVoiceRoamingOn(android.os.Handler h, int what, java.lang.Object obj)
Registration point for combined roaming on of mobile voice combined roaming is true when roaming is true and ONS differs SPN

param
h handler to notify
param
what what code of message when delivered
param
obj placed in Message.obj

        Registrant r = new Registrant(h, what, obj);
        mVoiceRoamingOnRegistrants.add(r);

        if (mSS.getVoiceRoaming()) {
            r.notifyRegistrant();
        }
    
voidrequestShutdown()

        if (mDeviceShuttingDown == true) return;
        mDeviceShuttingDown = true;
        mDesiredPowerState = false;
        setPowerStateToDesired();
    
public abstract voidsetImsRegistrationState(boolean registered)

protected abstract voidsetPowerStateToDesired()

public voidsetRadioPower(boolean power)

        mDesiredPowerState = power;

        setPowerStateToDesired();
    
protected abstract voidsetRoamingType(android.telephony.ServiceState currentServiceState)

protected booleanshouldFixTimeZoneNow(PhoneBase phoneBase, java.lang.String operatorNumeric, java.lang.String prevOperatorNumeric, boolean needToFixTimeZone)
Return true if time zone needs fixing.

param
phoneBase
param
operatorNumeric
param
prevOperatorNumeric
param
needToFixTimeZone
return
true if time zone needs to be fixed

        // Return false if the mcc isn't valid as we don't know where we are.
        // Return true if we have an IccCard and the mcc changed or we
        // need to fix it because when the NITZ time came in we didn't
        // know the country code.

        // If mcc is invalid then we'll return false
        int mcc;
        try {
            mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
        } catch (Exception e) {
            if (DBG) {
                log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
                        " retVal=false");
            }
            return false;
        }

        // If prevMcc is invalid will make it different from mcc
        // so we'll return true if the card exists.
        int prevMcc;
        try {
            prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
        } catch (Exception e) {
            prevMcc = mcc + 1;
        }

        // Determine if the Icc card exists
        boolean iccCardExist = false;
        if (mUiccApplcation != null) {
            iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN;
        }

        // Determine retVal
        boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
        if (DBG) {
            long ctm = System.currentTimeMillis();
            log("shouldFixTimeZoneNow: retVal=" + retVal +
                    " iccCardExist=" + iccCardExist +
                    " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
                    " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
                    " needToFixTimeZone=" + needToFixTimeZone +
                    " ltod=" + TimeUtils.logTimeOfDay(ctm));
        }
        return retVal;
    
public voidunregisterForDataConnectionAttached(android.os.Handler h)

        mAttachedRegistrants.remove(h);
    
public voidunregisterForDataConnectionDetached(android.os.Handler h)

        mDetachedRegistrants.remove(h);
    
public voidunregisterForDataRegStateOrRatChanged(android.os.Handler h)

        mDataRegStateOrRatChangedRegistrants.remove(h);
    
public voidunregisterForDataRoamingOff(android.os.Handler h)

        mDataRoamingOffRegistrants.remove(h);
    
public voidunregisterForDataRoamingOn(android.os.Handler h)

        mDataRoamingOnRegistrants.remove(h);
    
public voidunregisterForNetworkAttached(android.os.Handler h)

        mNetworkAttachedRegistrants.remove(h);
    
public voidunregisterForPsRestrictedDisabled(android.os.Handler h)

        mPsRestrictDisabledRegistrants.remove(h);
    
public voidunregisterForPsRestrictedEnabled(android.os.Handler h)

        mPsRestrictEnabledRegistrants.remove(h);
    
public voidunregisterForVoiceRoamingOff(android.os.Handler h)

        mVoiceRoamingOffRegistrants.remove(h);
    
public voidunregisterForVoiceRoamingOn(android.os.Handler h)

        mVoiceRoamingOnRegistrants.remove(h);
    
protected voidupdateCarrierMccMncConfiguration(java.lang.String newOp, java.lang.String oldOp, android.content.Context context)

        // if we have a change in operator, notify wifi (even to/from none)
        if (((newOp == null) && (TextUtils.isEmpty(oldOp) == false)) ||
                ((newOp != null) && (newOp.equals(oldOp) == false))) {
            log("update mccmnc=" + newOp + " fromServiceState=true");
            MccTable.updateMccMncConfiguration(context, newOp, true);
        }
    
protected voidupdatePhoneObject()

        if (mPhoneBase.getContext().getResources().
                getBoolean(com.android.internal.R.bool.config_switch_phone_on_voice_reg_state_change)) {
            // If the phone is not registered on a network, no need to update.
            boolean isRegistered = mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE ||
                    mSS.getVoiceRegState() == ServiceState.STATE_EMERGENCY_ONLY;
            if (!isRegistered) {
                Rlog.d(LOG_TAG, "updatePhoneObject: Ignore update");
                return;
            }
            mPhoneBase.updatePhoneObject(mSS.getRilVoiceRadioTechnology());
        }
    
protected abstract voidupdateSpnDisplay()

protected voiduseDataRegStateForDataOnlyDevices()
Some operators have been known to report registration failure data only devices, to fix that use DataRegState.

        if (mVoiceCapable == false) {
            if (DBG) {
                log("useDataRegStateForDataOnlyDevice: VoiceRegState=" + mNewSS.getVoiceRegState()
                    + " DataRegState=" + mNewSS.getDataRegState());
            }
            // TODO: Consider not lying and instead have callers know the difference. 
            mNewSS.setVoiceRegState(mNewSS.getDataRegState());
        }