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