Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.telephony;
     18 
     19 import android.os.Bundle;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 import android.util.Log;
     23 
     24 /**
     25  * Contains phone state and service related information.
     26  *
     27  * The following phone information is included in returned ServiceState:
     28  *
     29  * <ul>
     30  *   <li>Service state: IN_SERVICE, OUT_OF_SERVICE, EMERGENCY_ONLY, POWER_OFF
     31  *   <li>Roaming indicator
     32  *   <li>Operator name, short name and numeric id
     33  *   <li>Network selection mode
     34  * </ul>
     35  */
     36 public class ServiceState implements Parcelable {
     37 
     38     static final String LOG_TAG = "PHONE";
     39 
     40     /**
     41      * Normal operation condition, the phone is registered
     42      * with an operator either in home network or in roaming.
     43      */
     44     public static final int STATE_IN_SERVICE = 0;
     45 
     46     /**
     47      * Phone is not registered with any operator, the phone
     48      * can be currently searching a new operator to register to, or not
     49      * searching to registration at all, or registration is denied, or radio
     50      * signal is not available.
     51      */
     52     public static final int STATE_OUT_OF_SERVICE = 1;
     53 
     54     /**
     55      * The phone is registered and locked.  Only emergency numbers are allowed. {@more}
     56      */
     57     public static final int STATE_EMERGENCY_ONLY = 2;
     58 
     59     /**
     60      * Radio of telephony is explicitly powered off.
     61      */
     62     public static final int STATE_POWER_OFF = 3;
     63 
     64 
     65     /**
     66      * Available radio technologies for GSM, UMTS and CDMA.
     67      */
     68     /** @hide */
     69     public static final int RADIO_TECHNOLOGY_UNKNOWN = 0;
     70     /** @hide */
     71     public static final int RADIO_TECHNOLOGY_GPRS = 1;
     72     /** @hide */
     73     public static final int RADIO_TECHNOLOGY_EDGE = 2;
     74     /** @hide */
     75     public static final int RADIO_TECHNOLOGY_UMTS = 3;
     76     /** @hide */
     77     public static final int RADIO_TECHNOLOGY_IS95A = 4;
     78     /** @hide */
     79     public static final int RADIO_TECHNOLOGY_IS95B = 5;
     80     /** @hide */
     81     public static final int RADIO_TECHNOLOGY_1xRTT = 6;
     82     /** @hide */
     83     public static final int RADIO_TECHNOLOGY_EVDO_0 = 7;
     84     /** @hide */
     85     public static final int RADIO_TECHNOLOGY_EVDO_A = 8;
     86     /** @hide */
     87     public static final int RADIO_TECHNOLOGY_HSDPA = 9;
     88     /** @hide */
     89     public static final int RADIO_TECHNOLOGY_HSUPA = 10;
     90     /** @hide */
     91     public static final int RADIO_TECHNOLOGY_HSPA = 11;
     92     /** @hide */
     93     public static final int RADIO_TECHNOLOGY_EVDO_B = 12;
     94     /** @hide */
     95     public static final int RADIO_TECHNOLOGY_EHRPD = 13;
     96     /** @hide */
     97     public static final int RADIO_TECHNOLOGY_LTE = 14;
     98     /** @hide */
     99     public static final int RADIO_TECHNOLOGY_HSPAP = 15;
    100 
    101     /**
    102      * Available registration states for GSM, UMTS and CDMA.
    103      */
    104     /** @hide */
    105     public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_NOT_SEARCHING = 0;
    106     /** @hide */
    107     public static final int REGISTRATION_STATE_HOME_NETWORK = 1;
    108     /** @hide */
    109     public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_SEARCHING = 2;
    110     /** @hide */
    111     public static final int REGISTRATION_STATE_REGISTRATION_DENIED = 3;
    112     /** @hide */
    113     public static final int REGISTRATION_STATE_UNKNOWN = 4;
    114     /** @hide */
    115     public static final int REGISTRATION_STATE_ROAMING = 5;
    116 
    117     private int mState = STATE_OUT_OF_SERVICE;
    118     private boolean mRoaming;
    119     private String mOperatorAlphaLong;
    120     private String mOperatorAlphaShort;
    121     private String mOperatorNumeric;
    122     private boolean mIsManualNetworkSelection;
    123 
    124     private boolean mIsEmergencyOnly;
    125 
    126     //***** CDMA
    127     private int mRadioTechnology;
    128     private boolean mCssIndicator;
    129     private int mNetworkId;
    130     private int mSystemId;
    131     private int mCdmaRoamingIndicator;
    132     private int mCdmaDefaultRoamingIndicator;
    133     private int mCdmaEriIconIndex;
    134     private int mCdmaEriIconMode;
    135 
    136     /**
    137      * Create a new ServiceState from a intent notifier Bundle
    138      *
    139      * This method is used by PhoneStateIntentReceiver and maybe by
    140      * external applications.
    141      *
    142      * @param m Bundle from intent notifier
    143      * @return newly created ServiceState
    144      * @hide
    145      */
    146     public static ServiceState newFromBundle(Bundle m) {
    147         ServiceState ret;
    148         ret = new ServiceState();
    149         ret.setFromNotifierBundle(m);
    150         return ret;
    151     }
    152 
    153     /**
    154      * Empty constructor
    155      */
    156     public ServiceState() {
    157     }
    158 
    159     /**
    160      * Copy constructors
    161      *
    162      * @param s Source service state
    163      */
    164     public ServiceState(ServiceState s) {
    165         copyFrom(s);
    166     }
    167 
    168     protected void copyFrom(ServiceState s) {
    169         mState = s.mState;
    170         mRoaming = s.mRoaming;
    171         mOperatorAlphaLong = s.mOperatorAlphaLong;
    172         mOperatorAlphaShort = s.mOperatorAlphaShort;
    173         mOperatorNumeric = s.mOperatorNumeric;
    174         mIsManualNetworkSelection = s.mIsManualNetworkSelection;
    175         mRadioTechnology = s.mRadioTechnology;
    176         mCssIndicator = s.mCssIndicator;
    177         mNetworkId = s.mNetworkId;
    178         mSystemId = s.mSystemId;
    179         mCdmaRoamingIndicator = s.mCdmaRoamingIndicator;
    180         mCdmaDefaultRoamingIndicator = s.mCdmaDefaultRoamingIndicator;
    181         mCdmaEriIconIndex = s.mCdmaEriIconIndex;
    182         mCdmaEriIconMode = s.mCdmaEriIconMode;
    183         mIsEmergencyOnly = s.mIsEmergencyOnly;
    184     }
    185 
    186     /**
    187      * Construct a ServiceState object from the given parcel.
    188      */
    189     public ServiceState(Parcel in) {
    190         mState = in.readInt();
    191         mRoaming = in.readInt() != 0;
    192         mOperatorAlphaLong = in.readString();
    193         mOperatorAlphaShort = in.readString();
    194         mOperatorNumeric = in.readString();
    195         mIsManualNetworkSelection = in.readInt() != 0;
    196         mRadioTechnology = in.readInt();
    197         mCssIndicator = (in.readInt() != 0);
    198         mNetworkId = in.readInt();
    199         mSystemId = in.readInt();
    200         mCdmaRoamingIndicator = in.readInt();
    201         mCdmaDefaultRoamingIndicator = in.readInt();
    202         mCdmaEriIconIndex = in.readInt();
    203         mCdmaEriIconMode = in.readInt();
    204         mIsEmergencyOnly = in.readInt() != 0;
    205     }
    206 
    207     public void writeToParcel(Parcel out, int flags) {
    208         out.writeInt(mState);
    209         out.writeInt(mRoaming ? 1 : 0);
    210         out.writeString(mOperatorAlphaLong);
    211         out.writeString(mOperatorAlphaShort);
    212         out.writeString(mOperatorNumeric);
    213         out.writeInt(mIsManualNetworkSelection ? 1 : 0);
    214         out.writeInt(mRadioTechnology);
    215         out.writeInt(mCssIndicator ? 1 : 0);
    216         out.writeInt(mNetworkId);
    217         out.writeInt(mSystemId);
    218         out.writeInt(mCdmaRoamingIndicator);
    219         out.writeInt(mCdmaDefaultRoamingIndicator);
    220         out.writeInt(mCdmaEriIconIndex);
    221         out.writeInt(mCdmaEriIconMode);
    222         out.writeInt(mIsEmergencyOnly ? 1 : 0);
    223     }
    224 
    225     public int describeContents() {
    226         return 0;
    227     }
    228 
    229     public static final Parcelable.Creator<ServiceState> CREATOR =
    230             new Parcelable.Creator<ServiceState>() {
    231         public ServiceState createFromParcel(Parcel in) {
    232             return new ServiceState(in);
    233         }
    234 
    235         public ServiceState[] newArray(int size) {
    236             return new ServiceState[size];
    237         }
    238     };
    239 
    240     /**
    241      * Get current service state of phone
    242      *
    243      * @see #STATE_IN_SERVICE
    244      * @see #STATE_OUT_OF_SERVICE
    245      * @see #STATE_EMERGENCY_ONLY
    246      * @see #STATE_POWER_OFF
    247      */
    248     public int getState() {
    249         return mState;
    250     }
    251 
    252     /**
    253      * Get current roaming indicator of phone
    254      * (note: not just decoding from TS 27.007 7.2)
    255      *
    256      * @return true if TS 27.007 7.2 roaming is true
    257      *              and ONS is different from SPN
    258      *
    259      */
    260     public boolean getRoaming() {
    261         return mRoaming;
    262     }
    263 
    264     /**
    265      * @hide
    266      */
    267     public boolean isEmergencyOnly() {
    268         return mIsEmergencyOnly;
    269     }
    270 
    271     /**
    272      * @hide
    273      */
    274     public int getCdmaRoamingIndicator(){
    275         return this.mCdmaRoamingIndicator;
    276     }
    277 
    278     /**
    279      * @hide
    280      */
    281     public int getCdmaDefaultRoamingIndicator(){
    282         return this.mCdmaDefaultRoamingIndicator;
    283     }
    284 
    285     /**
    286      * @hide
    287      */
    288     public int getCdmaEriIconIndex() {
    289         return this.mCdmaEriIconIndex;
    290     }
    291 
    292     /**
    293      * @hide
    294      */
    295     public int getCdmaEriIconMode() {
    296         return this.mCdmaEriIconMode;
    297     }
    298 
    299     /**
    300      * Get current registered operator name in long alphanumeric format.
    301      *
    302      * In GSM/UMTS, long format can be up to 16 characters long.
    303      * In CDMA, returns the ERI text, if set. Otherwise, returns the ONS.
    304      *
    305      * @return long name of operator, null if unregistered or unknown
    306      */
    307     public String getOperatorAlphaLong() {
    308         return mOperatorAlphaLong;
    309     }
    310 
    311     /**
    312      * Get current registered operator name in short alphanumeric format.
    313      *
    314      * In GSM/UMTS, short format can be up to 8 characters long.
    315      *
    316      * @return short name of operator, null if unregistered or unknown
    317      */
    318     public String getOperatorAlphaShort() {
    319         return mOperatorAlphaShort;
    320     }
    321 
    322     /**
    323      * Get current registered operator numeric id.
    324      *
    325      * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
    326      * network code.
    327      *
    328      * @return numeric format of operator, null if unregistered or unknown
    329      */
    330     /*
    331      * The country code can be decoded using
    332      * {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}.
    333      */
    334     public String getOperatorNumeric() {
    335         return mOperatorNumeric;
    336     }
    337 
    338     /**
    339      * Get current network selection mode.
    340      *
    341      * @return true if manual mode, false if automatic mode
    342      */
    343     public boolean getIsManualSelection() {
    344         return mIsManualNetworkSelection;
    345     }
    346 
    347     @Override
    348     public int hashCode() {
    349         return ((mState * 0x1234)
    350                 + (mRoaming ? 1 : 0)
    351                 + (mIsManualNetworkSelection ? 1 : 0)
    352                 + ((null == mOperatorAlphaLong) ? 0 : mOperatorAlphaLong.hashCode())
    353                 + ((null == mOperatorAlphaShort) ? 0 : mOperatorAlphaShort.hashCode())
    354                 + ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode())
    355                 + mCdmaRoamingIndicator
    356                 + mCdmaDefaultRoamingIndicator
    357                 + (mIsEmergencyOnly ? 1 : 0));
    358     }
    359 
    360     @Override
    361     public boolean equals (Object o) {
    362         ServiceState s;
    363 
    364         try {
    365             s = (ServiceState) o;
    366         } catch (ClassCastException ex) {
    367             return false;
    368         }
    369 
    370         if (o == null) {
    371             return false;
    372         }
    373 
    374         return (mState == s.mState
    375                 && mRoaming == s.mRoaming
    376                 && mIsManualNetworkSelection == s.mIsManualNetworkSelection
    377                 && equalsHandlesNulls(mOperatorAlphaLong, s.mOperatorAlphaLong)
    378                 && equalsHandlesNulls(mOperatorAlphaShort, s.mOperatorAlphaShort)
    379                 && equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric)
    380                 && equalsHandlesNulls(mRadioTechnology, s.mRadioTechnology)
    381                 && equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
    382                 && equalsHandlesNulls(mNetworkId, s.mNetworkId)
    383                 && equalsHandlesNulls(mSystemId, s.mSystemId)
    384                 && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
    385                 && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
    386                         s.mCdmaDefaultRoamingIndicator)
    387                 && mIsEmergencyOnly == s.mIsEmergencyOnly);
    388     }
    389 
    390     /**
    391      * Convert radio technology to String
    392      *
    393      * @param radioTechnology
    394      * @return String representation of the RAT
    395      *
    396      * @hide
    397      */
    398     public static String radioTechnologyToString(int rt) {
    399         String rtString;
    400 
    401         switch(rt) {
    402             case 0:
    403                 rtString = "Unknown";
    404                 break;
    405             case 1:
    406                 rtString = "GPRS";
    407                 break;
    408             case 2:
    409                 rtString = "EDGE";
    410                 break;
    411             case 3:
    412                 rtString = "UMTS";
    413                 break;
    414             case 4:
    415                 rtString = "CDMA-IS95A";
    416                 break;
    417             case 5:
    418                 rtString = "CDMA-IS95B";
    419                 break;
    420             case 6:
    421                 rtString = "1xRTT";
    422                 break;
    423             case 7:
    424                 rtString = "EvDo-rev.0";
    425                 break;
    426             case 8:
    427                 rtString = "EvDo-rev.A";
    428                 break;
    429             case 9:
    430                 rtString = "HSDPA";
    431                 break;
    432             case 10:
    433                 rtString = "HSUPA";
    434                 break;
    435             case 11:
    436                 rtString = "HSPA";
    437                 break;
    438             case 12:
    439                 rtString = "EvDo-rev.B";
    440                 break;
    441             case 13:
    442                 rtString = "eHRPD";
    443                 break;
    444             case 14:
    445                 rtString = "LTE";
    446                 break;
    447             case 15:
    448                 rtString = "HSPAP";
    449                 break;
    450             default:
    451                 rtString = "Unexpected";
    452                 Log.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
    453                 break;
    454         }
    455         return rtString + ":" + rt;
    456     }
    457 
    458     @Override
    459     public String toString() {
    460         String radioTechnology = radioTechnologyToString(mRadioTechnology);
    461 
    462         return (mState + " " + (mRoaming ? "roaming" : "home")
    463                 + " " + mOperatorAlphaLong
    464                 + " " + mOperatorAlphaShort
    465                 + " " + mOperatorNumeric
    466                 + " " + (mIsManualNetworkSelection ? "(manual)" : "")
    467                 + " " + radioTechnology
    468                 + " " + (mCssIndicator ? "CSS supported" : "CSS not supported")
    469                 + " " + mNetworkId
    470                 + " " + mSystemId
    471                 + " RoamInd=" + mCdmaRoamingIndicator
    472                 + " DefRoamInd=" + mCdmaDefaultRoamingIndicator
    473                 + " EmergOnly=" + mIsEmergencyOnly);
    474     }
    475 
    476     private void setNullState(int state) {
    477         mState = state;
    478         mRoaming = false;
    479         mOperatorAlphaLong = null;
    480         mOperatorAlphaShort = null;
    481         mOperatorNumeric = null;
    482         mIsManualNetworkSelection = false;
    483         mRadioTechnology = 0;
    484         mCssIndicator = false;
    485         mNetworkId = -1;
    486         mSystemId = -1;
    487         mCdmaRoamingIndicator = -1;
    488         mCdmaDefaultRoamingIndicator = -1;
    489         mCdmaEriIconIndex = -1;
    490         mCdmaEriIconMode = -1;
    491         mIsEmergencyOnly = false;
    492     }
    493 
    494     public void setStateOutOfService() {
    495         setNullState(STATE_OUT_OF_SERVICE);
    496     }
    497 
    498     public void setStateOff() {
    499         setNullState(STATE_POWER_OFF);
    500     }
    501 
    502     public void setState(int state) {
    503         mState = state;
    504     }
    505 
    506     public void setRoaming(boolean roaming) {
    507         mRoaming = roaming;
    508     }
    509 
    510 
    511     /**
    512      * @hide
    513      */
    514     public void setEmergencyOnly(boolean emergencyOnly) {
    515         mIsEmergencyOnly = emergencyOnly;
    516     }
    517 
    518     /**
    519      * @hide
    520      */
    521     public void setCdmaRoamingIndicator(int roaming) {
    522         this.mCdmaRoamingIndicator = roaming;
    523     }
    524 
    525     /**
    526      * @hide
    527      */
    528     public void setCdmaDefaultRoamingIndicator (int roaming) {
    529         this.mCdmaDefaultRoamingIndicator = roaming;
    530     }
    531 
    532     /**
    533      * @hide
    534      */
    535     public void setCdmaEriIconIndex(int index) {
    536         this.mCdmaEriIconIndex = index;
    537     }
    538 
    539     /**
    540      * @hide
    541      */
    542     public void setCdmaEriIconMode(int mode) {
    543         this.mCdmaEriIconMode = mode;
    544     }
    545 
    546     public void setOperatorName(String longName, String shortName, String numeric) {
    547         mOperatorAlphaLong = longName;
    548         mOperatorAlphaShort = shortName;
    549         mOperatorNumeric = numeric;
    550     }
    551 
    552     /**
    553      * In CDMA, mOperatorAlphaLong can be set from the ERI text.
    554      * This is done from the CDMAPhone and not from the CdmaServiceStateTracker.
    555      *
    556      * @hide
    557      */
    558     public void setOperatorAlphaLong(String longName) {
    559         mOperatorAlphaLong = longName;
    560     }
    561 
    562     public void setIsManualSelection(boolean isManual) {
    563         mIsManualNetworkSelection = isManual;
    564     }
    565 
    566     /**
    567      * Test whether two objects hold the same data values or both are null.
    568      *
    569      * @param a first obj
    570      * @param b second obj
    571      * @return true if two objects equal or both are null
    572      */
    573     private static boolean equalsHandlesNulls (Object a, Object b) {
    574         return (a == null) ? (b == null) : a.equals (b);
    575     }
    576 
    577     /**
    578      * Set ServiceState based on intent notifier map.
    579      *
    580      * @param m intent notifier map
    581      * @hide
    582      */
    583     private void setFromNotifierBundle(Bundle m) {
    584         mState = m.getInt("state");
    585         mRoaming = m.getBoolean("roaming");
    586         mOperatorAlphaLong = m.getString("operator-alpha-long");
    587         mOperatorAlphaShort = m.getString("operator-alpha-short");
    588         mOperatorNumeric = m.getString("operator-numeric");
    589         mIsManualNetworkSelection = m.getBoolean("manual");
    590         mRadioTechnology = m.getInt("radioTechnology");
    591         mCssIndicator = m.getBoolean("cssIndicator");
    592         mNetworkId = m.getInt("networkId");
    593         mSystemId = m.getInt("systemId");
    594         mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
    595         mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
    596         mIsEmergencyOnly = m.getBoolean("emergencyOnly");
    597     }
    598 
    599     /**
    600      * Set intent notifier Bundle based on service state.
    601      *
    602      * @param m intent notifier Bundle
    603      * @hide
    604      */
    605     public void fillInNotifierBundle(Bundle m) {
    606         m.putInt("state", mState);
    607         m.putBoolean("roaming", Boolean.valueOf(mRoaming));
    608         m.putString("operator-alpha-long", mOperatorAlphaLong);
    609         m.putString("operator-alpha-short", mOperatorAlphaShort);
    610         m.putString("operator-numeric", mOperatorNumeric);
    611         m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection));
    612         m.putInt("radioTechnology", mRadioTechnology);
    613         m.putBoolean("cssIndicator", mCssIndicator);
    614         m.putInt("networkId", mNetworkId);
    615         m.putInt("systemId", mSystemId);
    616         m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
    617         m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
    618         m.putBoolean("emergencyOnly", Boolean.valueOf(mIsEmergencyOnly));
    619     }
    620 
    621     //***** CDMA
    622     /** @hide */
    623     public void setRadioTechnology(int state) {
    624         this.mRadioTechnology = state;
    625     }
    626 
    627     /** @hide */
    628     public void setCssIndicator(int css) {
    629         this.mCssIndicator = (css != 0);
    630     }
    631 
    632     /** @hide */
    633     public void setSystemAndNetworkId(int systemId, int networkId) {
    634         this.mSystemId = systemId;
    635         this.mNetworkId = networkId;
    636     }
    637 
    638     /** @hide */
    639     public int getRadioTechnology() {
    640         return this.mRadioTechnology;
    641     }
    642 
    643     /** @hide */
    644     public int getCssIndicator() {
    645         return this.mCssIndicator ? 1 : 0;
    646     }
    647 
    648     /** @hide */
    649     public int getNetworkId() {
    650         return this.mNetworkId;
    651     }
    652 
    653     /** @hide */
    654     public int getSystemId() {
    655         return this.mSystemId;
    656     }
    657 }
    658