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