/*
* 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:
*
*
* - Service state: IN_SERVICE, OUT_OF_SERVICE, EMERGENCY_ONLY, POWER_OFF
*
- Roaming indicator
*
- Operator name, short name and numeric id
*
- Network selection mode
*
*/
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;
}
}