/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; /** * Contains phone state and service related information. * * The following phone information is included in returned ServiceState: * * */ public class ServiceState implements Parcelable { static final String LOG_TAG = "PHONE"; /** * Normal operation condition, the phone is registered * with an operator either in home network or in roaming. */ public static final int STATE_IN_SERVICE = 0; /** * Phone is not registered with any operator, the phone * can be currently searching a new operator to register to, or not * searching to registration at all, or registration is denied, or radio * signal is not available. */ public static final int STATE_OUT_OF_SERVICE = 1; /** * The phone is registered and locked. Only emergency numbers are allowed. {@more} */ public static final int STATE_EMERGENCY_ONLY = 2; /** * Radio of telephony is explicitly powered off. */ public static final int STATE_POWER_OFF = 3; /** * Available radio technologies for GSM, UMTS and CDMA. */ /** @hide */ public static final int RADIO_TECHNOLOGY_UNKNOWN = 0; /** @hide */ public static final int RADIO_TECHNOLOGY_GPRS = 1; /** @hide */ public static final int RADIO_TECHNOLOGY_EDGE = 2; /** @hide */ public static final int RADIO_TECHNOLOGY_UMTS = 3; /** @hide */ public static final int RADIO_TECHNOLOGY_IS95A = 4; /** @hide */ public static final int RADIO_TECHNOLOGY_IS95B = 5; /** @hide */ public static final int RADIO_TECHNOLOGY_1xRTT = 6; /** @hide */ public static final int RADIO_TECHNOLOGY_EVDO_0 = 7; /** @hide */ public static final int RADIO_TECHNOLOGY_EVDO_A = 8; /** @hide */ public static final int RADIO_TECHNOLOGY_HSDPA = 9; /** @hide */ public static final int RADIO_TECHNOLOGY_HSUPA = 10; /** @hide */ public static final int RADIO_TECHNOLOGY_HSPA = 11; /** @hide */ public static final int RADIO_TECHNOLOGY_EVDO_B = 12; /** @hide */ public static final int RADIO_TECHNOLOGY_EHRPD = 13; /** @hide */ public static final int RADIO_TECHNOLOGY_LTE = 14; /** @hide */ public static final int RADIO_TECHNOLOGY_HSPAP = 15; /** * Available registration states for GSM, UMTS and CDMA. */ /** @hide */ public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_NOT_SEARCHING = 0; /** @hide */ public static final int REGISTRATION_STATE_HOME_NETWORK = 1; /** @hide */ public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_SEARCHING = 2; /** @hide */ public static final int REGISTRATION_STATE_REGISTRATION_DENIED = 3; /** @hide */ public static final int REGISTRATION_STATE_UNKNOWN = 4; /** @hide */ public static final int REGISTRATION_STATE_ROAMING = 5; private int mState = STATE_OUT_OF_SERVICE; private boolean mRoaming; private String mOperatorAlphaLong; private String mOperatorAlphaShort; private String mOperatorNumeric; private boolean mIsManualNetworkSelection; private boolean mIsEmergencyOnly; //***** CDMA private int mRadioTechnology; private boolean mCssIndicator; private int mNetworkId; private int mSystemId; private int mCdmaRoamingIndicator; private int mCdmaDefaultRoamingIndicator; private int mCdmaEriIconIndex; private int mCdmaEriIconMode; /** * Create a new ServiceState from a intent notifier Bundle * * This method is used by PhoneStateIntentReceiver and maybe by * external applications. * * @param m Bundle from intent notifier * @return newly created ServiceState * @hide */ public static ServiceState newFromBundle(Bundle m) { ServiceState ret; ret = new ServiceState(); ret.setFromNotifierBundle(m); return ret; } /** * Empty constructor */ public ServiceState() { } /** * Copy constructors * * @param s Source service state */ public ServiceState(ServiceState s) { copyFrom(s); } protected void copyFrom(ServiceState s) { mState = s.mState; mRoaming = s.mRoaming; mOperatorAlphaLong = s.mOperatorAlphaLong; mOperatorAlphaShort = s.mOperatorAlphaShort; mOperatorNumeric = s.mOperatorNumeric; mIsManualNetworkSelection = s.mIsManualNetworkSelection; mRadioTechnology = s.mRadioTechnology; mCssIndicator = s.mCssIndicator; mNetworkId = s.mNetworkId; mSystemId = s.mSystemId; mCdmaRoamingIndicator = s.mCdmaRoamingIndicator; mCdmaDefaultRoamingIndicator = s.mCdmaDefaultRoamingIndicator; mCdmaEriIconIndex = s.mCdmaEriIconIndex; mCdmaEriIconMode = s.mCdmaEriIconMode; mIsEmergencyOnly = s.mIsEmergencyOnly; } /** * Construct a ServiceState object from the given parcel. */ public ServiceState(Parcel in) { mState = in.readInt(); mRoaming = in.readInt() != 0; mOperatorAlphaLong = in.readString(); mOperatorAlphaShort = in.readString(); mOperatorNumeric = in.readString(); mIsManualNetworkSelection = in.readInt() != 0; mRadioTechnology = in.readInt(); mCssIndicator = (in.readInt() != 0); mNetworkId = in.readInt(); mSystemId = in.readInt(); mCdmaRoamingIndicator = in.readInt(); mCdmaDefaultRoamingIndicator = in.readInt(); mCdmaEriIconIndex = in.readInt(); mCdmaEriIconMode = in.readInt(); mIsEmergencyOnly = in.readInt() != 0; } public void writeToParcel(Parcel out, int flags) { out.writeInt(mState); out.writeInt(mRoaming ? 1 : 0); out.writeString(mOperatorAlphaLong); out.writeString(mOperatorAlphaShort); out.writeString(mOperatorNumeric); out.writeInt(mIsManualNetworkSelection ? 1 : 0); out.writeInt(mRadioTechnology); out.writeInt(mCssIndicator ? 1 : 0); out.writeInt(mNetworkId); out.writeInt(mSystemId); out.writeInt(mCdmaRoamingIndicator); out.writeInt(mCdmaDefaultRoamingIndicator); out.writeInt(mCdmaEriIconIndex); out.writeInt(mCdmaEriIconMode); out.writeInt(mIsEmergencyOnly ? 1 : 0); } public int describeContents() { return 0; } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public ServiceState createFromParcel(Parcel in) { return new ServiceState(in); } public ServiceState[] newArray(int size) { return new ServiceState[size]; } }; /** * Get current service state of phone * * @see #STATE_IN_SERVICE * @see #STATE_OUT_OF_SERVICE * @see #STATE_EMERGENCY_ONLY * @see #STATE_POWER_OFF */ public int getState() { return mState; } /** * Get current roaming indicator of phone * (note: not just decoding from TS 27.007 7.2) * * @return true if TS 27.007 7.2 roaming is true * and ONS is different from SPN * */ public boolean getRoaming() { return mRoaming; } /** * @hide */ public boolean isEmergencyOnly() { return mIsEmergencyOnly; } /** * @hide */ public int getCdmaRoamingIndicator(){ return this.mCdmaRoamingIndicator; } /** * @hide */ public int getCdmaDefaultRoamingIndicator(){ return this.mCdmaDefaultRoamingIndicator; } /** * @hide */ public int getCdmaEriIconIndex() { return this.mCdmaEriIconIndex; } /** * @hide */ public int getCdmaEriIconMode() { return this.mCdmaEriIconMode; } /** * Get current registered operator name in long alphanumeric format. * * In GSM/UMTS, long format can be up to 16 characters long. * In CDMA, returns the ERI text, if set. Otherwise, returns the ONS. * * @return long name of operator, null if unregistered or unknown */ public String getOperatorAlphaLong() { return mOperatorAlphaLong; } /** * Get current registered operator name in short alphanumeric format. * * In GSM/UMTS, short format can be up to 8 characters long. * * @return short name of operator, null if unregistered or unknown */ public String getOperatorAlphaShort() { return mOperatorAlphaShort; } /** * Get current registered operator numeric id. * * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit * network code. * * @return numeric format of operator, null if unregistered or unknown */ /* * The country code can be decoded using * {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}. */ public String getOperatorNumeric() { return mOperatorNumeric; } /** * Get current network selection mode. * * @return true if manual mode, false if automatic mode */ public boolean getIsManualSelection() { return mIsManualNetworkSelection; } @Override public int hashCode() { return ((mState * 0x1234) + (mRoaming ? 1 : 0) + (mIsManualNetworkSelection ? 1 : 0) + ((null == mOperatorAlphaLong) ? 0 : mOperatorAlphaLong.hashCode()) + ((null == mOperatorAlphaShort) ? 0 : mOperatorAlphaShort.hashCode()) + ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode()) + mCdmaRoamingIndicator + mCdmaDefaultRoamingIndicator + (mIsEmergencyOnly ? 1 : 0)); } @Override public boolean equals (Object o) { ServiceState s; try { s = (ServiceState) o; } catch (ClassCastException ex) { return false; } if (o == null) { return false; } return (mState == s.mState && mRoaming == s.mRoaming && mIsManualNetworkSelection == s.mIsManualNetworkSelection && equalsHandlesNulls(mOperatorAlphaLong, s.mOperatorAlphaLong) && equalsHandlesNulls(mOperatorAlphaShort, s.mOperatorAlphaShort) && equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric) && equalsHandlesNulls(mRadioTechnology, s.mRadioTechnology) && equalsHandlesNulls(mCssIndicator, s.mCssIndicator) && equalsHandlesNulls(mNetworkId, s.mNetworkId) && equalsHandlesNulls(mSystemId, s.mSystemId) && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator) && equalsHandlesNulls(mCdmaDefaultRoamingIndicator, s.mCdmaDefaultRoamingIndicator) && mIsEmergencyOnly == s.mIsEmergencyOnly); } /** * Convert radio technology to String * * @param radioTechnology * @return String representation of the RAT * * @hide */ public static String radioTechnologyToString(int rt) { String rtString; switch(rt) { case 0: rtString = "Unknown"; break; case 1: rtString = "GPRS"; break; case 2: rtString = "EDGE"; break; case 3: rtString = "UMTS"; break; case 4: rtString = "CDMA-IS95A"; break; case 5: rtString = "CDMA-IS95B"; break; case 6: rtString = "1xRTT"; break; case 7: rtString = "EvDo-rev.0"; break; case 8: rtString = "EvDo-rev.A"; break; case 9: rtString = "HSDPA"; break; case 10: rtString = "HSUPA"; break; case 11: rtString = "HSPA"; break; case 12: rtString = "EvDo-rev.B"; break; case 13: rtString = "eHRPD"; break; case 14: rtString = "LTE"; break; case 15: rtString = "HSPAP"; break; default: rtString = "Unexpected"; Log.w(LOG_TAG, "Unexpected radioTechnology=" + rt); break; } return rtString + ":" + rt; } @Override public String toString() { String radioTechnology = radioTechnologyToString(mRadioTechnology); return (mState + " " + (mRoaming ? "roaming" : "home") + " " + mOperatorAlphaLong + " " + mOperatorAlphaShort + " " + mOperatorNumeric + " " + (mIsManualNetworkSelection ? "(manual)" : "") + " " + radioTechnology + " " + (mCssIndicator ? "CSS supported" : "CSS not supported") + " " + mNetworkId + " " + mSystemId + " RoamInd=" + mCdmaRoamingIndicator + " DefRoamInd=" + mCdmaDefaultRoamingIndicator + " EmergOnly=" + mIsEmergencyOnly); } private void setNullState(int state) { mState = state; mRoaming = false; mOperatorAlphaLong = null; mOperatorAlphaShort = null; mOperatorNumeric = null; mIsManualNetworkSelection = false; mRadioTechnology = 0; mCssIndicator = false; mNetworkId = -1; mSystemId = -1; mCdmaRoamingIndicator = -1; mCdmaDefaultRoamingIndicator = -1; mCdmaEriIconIndex = -1; mCdmaEriIconMode = -1; mIsEmergencyOnly = false; } public void setStateOutOfService() { setNullState(STATE_OUT_OF_SERVICE); } public void setStateOff() { setNullState(STATE_POWER_OFF); } public void setState(int state) { mState = state; } public void setRoaming(boolean roaming) { mRoaming = roaming; } /** * @hide */ public void setEmergencyOnly(boolean emergencyOnly) { mIsEmergencyOnly = emergencyOnly; } /** * @hide */ public void setCdmaRoamingIndicator(int roaming) { this.mCdmaRoamingIndicator = roaming; } /** * @hide */ public void setCdmaDefaultRoamingIndicator (int roaming) { this.mCdmaDefaultRoamingIndicator = roaming; } /** * @hide */ public void setCdmaEriIconIndex(int index) { this.mCdmaEriIconIndex = index; } /** * @hide */ public void setCdmaEriIconMode(int mode) { this.mCdmaEriIconMode = mode; } public void setOperatorName(String longName, String shortName, String numeric) { mOperatorAlphaLong = longName; mOperatorAlphaShort = shortName; mOperatorNumeric = numeric; } /** * In CDMA, mOperatorAlphaLong can be set from the ERI text. * This is done from the CDMAPhone and not from the CdmaServiceStateTracker. * * @hide */ public void setOperatorAlphaLong(String longName) { mOperatorAlphaLong = longName; } public void setIsManualSelection(boolean isManual) { mIsManualNetworkSelection = isManual; } /** * Test whether two objects hold the same data values or both are null. * * @param a first obj * @param b second obj * @return true if two objects equal or both are null */ private static boolean equalsHandlesNulls (Object a, Object b) { return (a == null) ? (b == null) : a.equals (b); } /** * Set ServiceState based on intent notifier map. * * @param m intent notifier map * @hide */ private void setFromNotifierBundle(Bundle m) { mState = m.getInt("state"); mRoaming = m.getBoolean("roaming"); mOperatorAlphaLong = m.getString("operator-alpha-long"); mOperatorAlphaShort = m.getString("operator-alpha-short"); mOperatorNumeric = m.getString("operator-numeric"); mIsManualNetworkSelection = m.getBoolean("manual"); mRadioTechnology = m.getInt("radioTechnology"); mCssIndicator = m.getBoolean("cssIndicator"); mNetworkId = m.getInt("networkId"); mSystemId = m.getInt("systemId"); mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator"); mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator"); mIsEmergencyOnly = m.getBoolean("emergencyOnly"); } /** * Set intent notifier Bundle based on service state. * * @param m intent notifier Bundle * @hide */ public void fillInNotifierBundle(Bundle m) { m.putInt("state", mState); m.putBoolean("roaming", Boolean.valueOf(mRoaming)); m.putString("operator-alpha-long", mOperatorAlphaLong); m.putString("operator-alpha-short", mOperatorAlphaShort); m.putString("operator-numeric", mOperatorNumeric); m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection)); m.putInt("radioTechnology", mRadioTechnology); m.putBoolean("cssIndicator", mCssIndicator); m.putInt("networkId", mNetworkId); m.putInt("systemId", mSystemId); m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator); m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator); m.putBoolean("emergencyOnly", Boolean.valueOf(mIsEmergencyOnly)); } //***** CDMA /** @hide */ public void setRadioTechnology(int state) { this.mRadioTechnology = state; } /** @hide */ public void setCssIndicator(int css) { this.mCssIndicator = (css != 0); } /** @hide */ public void setSystemAndNetworkId(int systemId, int networkId) { this.mSystemId = systemId; this.mNetworkId = networkId; } /** @hide */ public int getRadioTechnology() { return this.mRadioTechnology; } /** @hide */ public int getCssIndicator() { return this.mCssIndicator ? 1 : 0; } /** @hide */ public int getNetworkId() { return this.mNetworkId; } /** @hide */ public int getSystemId() { return this.mSystemId; } }