ServiceState.java revision 56c2d2ff27536a1d8edf0037cd41ff3ea3272fd9
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
17package android.telephony;
18
19import android.os.Bundle;
20import android.os.Parcel;
21import android.os.Parcelable;
22import 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 */
36public 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 explictly 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
93    /**
94     * Available registration states for GSM, UMTS and CDMA.
95     */
96    /** @hide */
97    public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_NOT_SEARCHING = 0;
98    /** @hide */
99    public static final int REGISTRATION_STATE_HOME_NETWORK = 1;
100    /** @hide */
101    public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_SEARCHING = 2;
102    /** @hide */
103    public static final int REGISTRATION_STATE_REGISTRATION_DENIED = 3;
104    /** @hide */
105    public static final int REGISTRATION_STATE_UNKNOWN = 4;
106    /** @hide */
107    public static final int REGISTRATION_STATE_ROAMING = 5;
108
109    private int mState = STATE_OUT_OF_SERVICE;
110    private boolean mRoaming;
111    private String mOperatorAlphaLong;
112    private String mOperatorAlphaShort;
113    private String mOperatorNumeric;
114    private boolean mIsManualNetworkSelection;
115
116    private boolean mIsEmergencyOnly;
117
118    //***** CDMA
119    private int mRadioTechnology;
120    private boolean mCssIndicator;
121    private int mNetworkId;
122    private int mSystemId;
123    private int mCdmaRoamingIndicator;
124    private int mCdmaDefaultRoamingIndicator;
125    private int mCdmaEriIconIndex;
126    private int mCdmaEriIconMode;
127
128    /**
129     * Create a new ServiceState from a intent notifier Bundle
130     *
131     * This method is used by PhoneStateIntentReceiver and maybe by
132     * external applications.
133     *
134     * @param m Bundle from intent notifier
135     * @return newly created ServiceState
136     * @hide
137     */
138    public static ServiceState newFromBundle(Bundle m) {
139        ServiceState ret;
140        ret = new ServiceState();
141        ret.setFromNotifierBundle(m);
142        return ret;
143    }
144
145    /**
146     * Empty constructor
147     */
148    public ServiceState() {
149    }
150
151    /**
152     * Copy constructors
153     *
154     * @param s Source service state
155     */
156    public ServiceState(ServiceState s) {
157        copyFrom(s);
158    }
159
160    protected void copyFrom(ServiceState s) {
161        mState = s.mState;
162        mRoaming = s.mRoaming;
163        mOperatorAlphaLong = s.mOperatorAlphaLong;
164        mOperatorAlphaShort = s.mOperatorAlphaShort;
165        mOperatorNumeric = s.mOperatorNumeric;
166        mIsManualNetworkSelection = s.mIsManualNetworkSelection;
167        mRadioTechnology = s.mRadioTechnology;
168        mCssIndicator = s.mCssIndicator;
169        mNetworkId = s.mNetworkId;
170        mSystemId = s.mSystemId;
171        mCdmaRoamingIndicator = s.mCdmaRoamingIndicator;
172        mCdmaDefaultRoamingIndicator = s.mCdmaDefaultRoamingIndicator;
173        mCdmaEriIconIndex = s.mCdmaEriIconIndex;
174        mCdmaEriIconMode = s.mCdmaEriIconMode;
175        mIsEmergencyOnly = s.mIsEmergencyOnly;
176    }
177
178    /**
179     * Construct a ServiceState object from the given parcel.
180     */
181    public ServiceState(Parcel in) {
182        mState = in.readInt();
183        mRoaming = in.readInt() != 0;
184        mOperatorAlphaLong = in.readString();
185        mOperatorAlphaShort = in.readString();
186        mOperatorNumeric = in.readString();
187        mIsManualNetworkSelection = in.readInt() != 0;
188        mRadioTechnology = in.readInt();
189        mCssIndicator = (in.readInt() != 0);
190        mNetworkId = in.readInt();
191        mSystemId = in.readInt();
192        mCdmaRoamingIndicator = in.readInt();
193        mCdmaDefaultRoamingIndicator = in.readInt();
194        mCdmaEriIconIndex = in.readInt();
195        mCdmaEriIconMode = in.readInt();
196        mIsEmergencyOnly = in.readInt() != 0;
197    }
198
199    public void writeToParcel(Parcel out, int flags) {
200        out.writeInt(mState);
201        out.writeInt(mRoaming ? 1 : 0);
202        out.writeString(mOperatorAlphaLong);
203        out.writeString(mOperatorAlphaShort);
204        out.writeString(mOperatorNumeric);
205        out.writeInt(mIsManualNetworkSelection ? 1 : 0);
206        out.writeInt(mRadioTechnology);
207        out.writeInt(mCssIndicator ? 1 : 0);
208        out.writeInt(mNetworkId);
209        out.writeInt(mSystemId);
210        out.writeInt(mCdmaRoamingIndicator);
211        out.writeInt(mCdmaDefaultRoamingIndicator);
212        out.writeInt(mCdmaEriIconIndex);
213        out.writeInt(mCdmaEriIconMode);
214        out.writeInt(mIsEmergencyOnly ? 1 : 0);
215    }
216
217    public int describeContents() {
218        return 0;
219    }
220
221    public static final Parcelable.Creator<ServiceState> CREATOR = new Parcelable.Creator() {
222        public ServiceState createFromParcel(Parcel in) {
223            return new ServiceState(in);
224        }
225
226        public ServiceState[] newArray(int size) {
227            return new ServiceState[size];
228        }
229    };
230
231    /**
232     * Get current servcie state of phone
233     *
234     * @see #STATE_IN_SERVICE
235     * @see #STATE_OUT_OF_SERVICE
236     * @see #STATE_EMERGENCY_ONLY
237     * @see #STATE_POWER_OFF
238     */
239    public int getState() {
240        return mState;
241    }
242
243    /**
244     * Get current roaming indicator of phone
245     * (note: not just decoding from TS 27.007 7.2)
246     *
247     * @return true if TS 27.007 7.2 roaming is true
248     *              and ONS is different from SPN
249     *
250     */
251    public boolean getRoaming() {
252        return mRoaming;
253    }
254
255    /**
256     * @hide
257     */
258    public boolean isEmergencyOnly() {
259        return mIsEmergencyOnly;
260    }
261
262    /**
263     * @hide
264     */
265    public int getCdmaRoamingIndicator(){
266        return this.mCdmaRoamingIndicator;
267    }
268
269    /**
270     * @hide
271     */
272    public int getCdmaDefaultRoamingIndicator(){
273        return this.mCdmaDefaultRoamingIndicator;
274    }
275
276    /**
277     * @hide
278     */
279    public int getCdmaEriIconIndex() {
280        return this.mCdmaEriIconIndex;
281    }
282
283    /**
284     * @hide
285     */
286    public int getCdmaEriIconMode() {
287        return this.mCdmaEriIconMode;
288    }
289
290    /**
291     * Get current registered operator name in long alphanumeric format
292     *
293     * In GSM/UMTS, long format can be upto 16 characters long
294     * In CDMA, returns the ERI text, if set, otherwise the ONS
295     *
296     * @return long name of operator, null if unregistered or unknown
297     */
298    public String getOperatorAlphaLong() {
299        return mOperatorAlphaLong;
300    }
301
302    /**
303     * Get current registered operator name in short lphanumeric format
304     *
305     * In GSM/UMST, short format can be upto 8 characters long
306     *
307     * @return short name of operator, null if unregistered or unknown
308     */
309    public String getOperatorAlphaShort() {
310        return mOperatorAlphaShort;
311    }
312
313    /**
314     * Get current registered operator numeric id
315     *
316     * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
317     * network code
318     *
319     * The country code can be decoded using MccTable.countryCodeForMcc()
320     *
321     * @return numeric format of operator, null if unregistered or unknown
322     */
323    public String getOperatorNumeric() {
324        return mOperatorNumeric;
325    }
326
327    /**
328     * Get current network selection mode
329     *
330     * @return true if manual mode, false if automatic mode
331     */
332    public boolean getIsManualSelection() {
333        return mIsManualNetworkSelection;
334    }
335
336    @Override
337    public int hashCode() {
338        return ((mState * 0x1234)
339                + (mRoaming ? 1 : 0)
340                + (mIsManualNetworkSelection ? 1 : 0)
341                + ((null == mOperatorAlphaLong) ? 0 : mOperatorAlphaLong.hashCode())
342                + ((null == mOperatorAlphaShort) ? 0 : mOperatorAlphaShort.hashCode())
343                + ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode())
344                + mCdmaRoamingIndicator
345                + mCdmaDefaultRoamingIndicator
346                + (mIsEmergencyOnly ? 1 : 0));
347    }
348
349    @Override
350    public boolean equals (Object o) {
351        ServiceState s;
352
353        try {
354            s = (ServiceState) o;
355        } catch (ClassCastException ex) {
356            return false;
357        }
358
359        if (o == null) {
360            return false;
361        }
362
363        return (mState == s.mState
364                && mRoaming == s.mRoaming
365                && mIsManualNetworkSelection == s.mIsManualNetworkSelection
366                && equalsHandlesNulls(mOperatorAlphaLong, s.mOperatorAlphaLong)
367                && equalsHandlesNulls(mOperatorAlphaShort, s.mOperatorAlphaShort)
368                && equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric)
369                && equalsHandlesNulls(mRadioTechnology, s.mRadioTechnology)
370                && equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
371                && equalsHandlesNulls(mNetworkId, s.mNetworkId)
372                && equalsHandlesNulls(mSystemId, s.mSystemId)
373                && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
374                && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
375                        s.mCdmaDefaultRoamingIndicator)
376                && mIsEmergencyOnly == s.mIsEmergencyOnly);
377    }
378
379    @Override
380    public String toString() {
381        String radioTechnology = new String("Error in radioTechnology");
382
383        switch(this.mRadioTechnology) {
384        case 0:
385            radioTechnology = "Unknown";
386            break;
387        case 1:
388            radioTechnology = "GPRS";
389            break;
390        case 2:
391            radioTechnology = "EDGE";
392            break;
393        case 3:
394            radioTechnology = "UMTS";
395            break;
396        case 4:
397            radioTechnology = "IS95A";
398            break;
399        case 5:
400            radioTechnology = "IS95B";
401            break;
402        case 6:
403            radioTechnology = "1xRTT";
404            break;
405        case 7:
406            radioTechnology = "EvDo rev. 0";
407            break;
408        case 8:
409            radioTechnology = "EvDo rev. A";
410            break;
411        case 9:
412            radioTechnology = "HSDPA";
413            break;
414        case 10:
415            radioTechnology = "HSUPA";
416            break;
417        case 11:
418            radioTechnology = "HSPA";
419            break;
420        default:
421            Log.w(LOG_TAG, "mRadioTechnology variable out of range.");
422        break;
423        }
424
425        return (mState + " " + (mRoaming ? "roaming" : "home")
426                + " " + mOperatorAlphaLong
427                + " " + mOperatorAlphaShort
428                + " " + mOperatorNumeric
429                + " " + (mIsManualNetworkSelection ? "(manual)" : "")
430                + " " + radioTechnology
431                + " " + (mCssIndicator ? "CSS supported" : "CSS not supported")
432                + " " + mNetworkId
433                + " " + mSystemId
434                + "RoamInd: " + mCdmaRoamingIndicator
435                + "DefRoamInd: " + mCdmaDefaultRoamingIndicator
436                + "EmergOnly: " + mIsEmergencyOnly);
437    }
438
439    public void setStateOutOfService() {
440        mState = STATE_OUT_OF_SERVICE;
441        mRoaming = false;
442        mOperatorAlphaLong = null;
443        mOperatorAlphaShort = null;
444        mOperatorNumeric = null;
445        mIsManualNetworkSelection = false;
446        mRadioTechnology = 0;
447        mCssIndicator = false;
448        mNetworkId = -1;
449        mSystemId = -1;
450        mCdmaRoamingIndicator = -1;
451        mCdmaDefaultRoamingIndicator = -1;
452        mCdmaEriIconIndex = -1;
453        mCdmaEriIconMode = -1;
454        mIsEmergencyOnly = false;
455    }
456
457    // TODO - can't this be combined with the above func..
458    public void setStateOff() {
459        mState = STATE_POWER_OFF;
460        mRoaming = false;
461        mOperatorAlphaLong = null;
462        mOperatorAlphaShort = null;
463        mOperatorNumeric = null;
464        mIsManualNetworkSelection = false;
465        mRadioTechnology = 0;
466        mCssIndicator = false;
467        mNetworkId = -1;
468        mSystemId = -1;
469        mCdmaRoamingIndicator = -1;
470        mCdmaDefaultRoamingIndicator = -1;
471        mCdmaEriIconIndex = -1;
472        mCdmaEriIconMode = -1;
473        mIsEmergencyOnly = false;
474    }
475
476    public void setState(int state) {
477        mState = state;
478    }
479
480    public void setRoaming(boolean roaming) {
481        mRoaming = roaming;
482    }
483
484
485    /**
486     * @hide
487     */
488    public void setEmergencyOnly(boolean emergencyOnly) {
489        mIsEmergencyOnly = emergencyOnly;
490    }
491
492    /**
493     * @hide
494     */
495    public void setCdmaRoamingIndicator(int roaming) {
496        this.mCdmaRoamingIndicator = roaming;
497    }
498
499    /**
500     * @hide
501     */
502    public void setCdmaDefaultRoamingIndicator (int roaming) {
503        this.mCdmaDefaultRoamingIndicator = roaming;
504    }
505
506    /**
507     * @hide
508     */
509    public void setCdmaEriIconIndex(int index) {
510        this.mCdmaEriIconIndex = index;
511    }
512
513    /**
514     * @hide
515     */
516    public void setCdmaEriIconMode(int mode) {
517        this.mCdmaEriIconMode = mode;
518    }
519
520    public void setOperatorName(String longName, String shortName, String numeric) {
521        mOperatorAlphaLong = longName;
522        mOperatorAlphaShort = shortName;
523        mOperatorNumeric = numeric;
524    }
525
526    /**
527     * In CDMA mOperatorAlphaLong can be set from the ERI
528     * text, this is done from the CDMAPhone and not from the CdmaServiceStateTracker
529     *
530     * @hide
531     */
532    public void setCdmaEriText(String longName) {
533        mOperatorAlphaLong = longName;
534    }
535
536    public void setIsManualSelection(boolean isManual) {
537        mIsManualNetworkSelection = isManual;
538    }
539
540    /**
541     * Test whether two objects hold the same data values or both are null
542     *
543     * @param a first obj
544     * @param b second obj
545     * @return true if two objects equal or both are null
546     */
547    private static boolean equalsHandlesNulls (Object a, Object b) {
548        return (a == null) ? (b == null) : a.equals (b);
549    }
550
551    /**
552     * Set ServiceState based on intent notifier map
553     *
554     * @param m intent notifier map
555     * @hide
556     */
557    private void setFromNotifierBundle(Bundle m) {
558        mState = m.getInt("state");
559        mRoaming = m.getBoolean("roaming");
560        mOperatorAlphaLong = m.getString("operator-alpha-long");
561        mOperatorAlphaShort = m.getString("operator-alpha-short");
562        mOperatorNumeric = m.getString("operator-numeric");
563        mIsManualNetworkSelection = m.getBoolean("manual");
564        mRadioTechnology = m.getInt("radioTechnology");
565        mCssIndicator = m.getBoolean("cssIndicator");
566        mNetworkId = m.getInt("networkId");
567        mSystemId = m.getInt("systemId");
568        mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
569        mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
570        mIsEmergencyOnly = m.getBoolean("emergencyOnly");
571    }
572
573    /**
574     * Set intent notifier Bundle based on service state
575     *
576     * @param m intent notifier Bundle
577     * @hide
578     */
579    public void fillInNotifierBundle(Bundle m) {
580        m.putInt("state", mState);
581        m.putBoolean("roaming", Boolean.valueOf(mRoaming));
582        m.putString("operator-alpha-long", mOperatorAlphaLong);
583        m.putString("operator-alpha-short", mOperatorAlphaShort);
584        m.putString("operator-numeric", mOperatorNumeric);
585        m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection));
586        m.putInt("radioTechnology", mRadioTechnology);
587        m.putBoolean("cssIndicator", mCssIndicator);
588        m.putInt("networkId", mNetworkId);
589        m.putInt("systemId", mSystemId);
590        m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
591        m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
592        m.putBoolean("emergencyOnly", Boolean.valueOf(mIsEmergencyOnly));
593    }
594
595    //***** CDMA
596    /** @hide */
597    public void setRadioTechnology(int state) {
598        this.mRadioTechnology = state;
599    }
600
601    /** @hide */
602    public void setCssIndicator(int css) {
603        this.mCssIndicator = (css != 0);
604    }
605
606    /** @hide */
607    public void setSystemAndNetworkId(int systemId, int networkId) {
608        this.mSystemId = systemId;
609        this.mNetworkId = networkId;
610    }
611
612    /** @hide */
613    public int getRadioTechnology() {
614        return this.mRadioTechnology;
615    }
616
617    /** @hide */
618    public int getCssIndicator() {
619        return this.mCssIndicator ? 1 : 0;
620    }
621
622    /** @hide */
623    public int getNetworkId() {
624        return this.mNetworkId;
625    }
626
627    /** @hide */
628    public int getSystemId() {
629        return this.mSystemId;
630    }
631}
632