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