ServiceState.java revision f57276154aaa587524374db8e0d7228383611bf3
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    /**
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    @Override
391    public String toString() {
392        String radioTechnology = new String("Error in radioTechnology");
393        switch(this.mRadioTechnology) {
394        case 0:
395            radioTechnology = "Unknown";
396            break;
397        case 1:
398            radioTechnology = "GPRS";
399            break;
400        case 2:
401            radioTechnology = "EDGE";
402            break;
403        case 3:
404            radioTechnology = "UMTS";
405            break;
406        case 4:
407            radioTechnology = "IS95A";
408            break;
409        case 5:
410            radioTechnology = "IS95B";
411            break;
412        case 6:
413            radioTechnology = "1xRTT";
414            break;
415        case 7:
416            radioTechnology = "EvDo rev. 0";
417            break;
418        case 8:
419            radioTechnology = "EvDo rev. A";
420            break;
421        case 9:
422            radioTechnology = "HSDPA";
423            break;
424        case 10:
425            radioTechnology = "HSUPA";
426            break;
427        case 11:
428            radioTechnology = "HSPA";
429            break;
430        case 12:
431            radioTechnology = "EvDo rev. B";
432            break;
433        case 13:
434            radioTechnology = "eHRPD";
435            break;
436        case 14:
437            radioTechnology = "LTE";
438            break;
439        case 15:
440            radioTechnology = "HSPAP";
441            break;
442        default:
443            Log.w(LOG_TAG, "mRadioTechnology variable out of range.");
444        break;
445        }
446
447        return (mState + " " + (mRoaming ? "roaming" : "home")
448                + " " + mOperatorAlphaLong
449                + " " + mOperatorAlphaShort
450                + " " + mOperatorNumeric
451                + " " + (mIsManualNetworkSelection ? "(manual)" : "")
452                + " " + radioTechnology
453                + " " + (mCssIndicator ? "CSS supported" : "CSS not supported")
454                + " " + mNetworkId
455                + " " + mSystemId
456                + " RoamInd=" + mCdmaRoamingIndicator
457                + " DefRoamInd=" + mCdmaDefaultRoamingIndicator
458                + " EmergOnly=" + mIsEmergencyOnly);
459    }
460
461    public void setStateOutOfService() {
462        mState = STATE_OUT_OF_SERVICE;
463        mRoaming = false;
464        mOperatorAlphaLong = null;
465        mOperatorAlphaShort = null;
466        mOperatorNumeric = null;
467        mIsManualNetworkSelection = false;
468        mRadioTechnology = 0;
469        mCssIndicator = false;
470        mNetworkId = -1;
471        mSystemId = -1;
472        mCdmaRoamingIndicator = -1;
473        mCdmaDefaultRoamingIndicator = -1;
474        mCdmaEriIconIndex = -1;
475        mCdmaEriIconMode = -1;
476        mIsEmergencyOnly = false;
477    }
478
479    // TODO - can't this be combined with the above method?
480    public void setStateOff() {
481        mState = STATE_POWER_OFF;
482        mRoaming = false;
483        mOperatorAlphaLong = null;
484        mOperatorAlphaShort = null;
485        mOperatorNumeric = null;
486        mIsManualNetworkSelection = false;
487        mRadioTechnology = 0;
488        mCssIndicator = false;
489        mNetworkId = -1;
490        mSystemId = -1;
491        mCdmaRoamingIndicator = -1;
492        mCdmaDefaultRoamingIndicator = -1;
493        mCdmaEriIconIndex = -1;
494        mCdmaEriIconMode = -1;
495        mIsEmergencyOnly = false;
496    }
497
498    public void setState(int state) {
499        mState = state;
500    }
501
502    public void setRoaming(boolean roaming) {
503        mRoaming = roaming;
504    }
505
506
507    /**
508     * @hide
509     */
510    public void setEmergencyOnly(boolean emergencyOnly) {
511        mIsEmergencyOnly = emergencyOnly;
512    }
513
514    /**
515     * @hide
516     */
517    public void setCdmaRoamingIndicator(int roaming) {
518        this.mCdmaRoamingIndicator = roaming;
519    }
520
521    /**
522     * @hide
523     */
524    public void setCdmaDefaultRoamingIndicator (int roaming) {
525        this.mCdmaDefaultRoamingIndicator = roaming;
526    }
527
528    /**
529     * @hide
530     */
531    public void setCdmaEriIconIndex(int index) {
532        this.mCdmaEriIconIndex = index;
533    }
534
535    /**
536     * @hide
537     */
538    public void setCdmaEriIconMode(int mode) {
539        this.mCdmaEriIconMode = mode;
540    }
541
542    public void setOperatorName(String longName, String shortName, String numeric) {
543        mOperatorAlphaLong = longName;
544        mOperatorAlphaShort = shortName;
545        mOperatorNumeric = numeric;
546    }
547
548    /**
549     * In CDMA, mOperatorAlphaLong can be set from the ERI text.
550     * This is done from the CDMAPhone and not from the CdmaServiceStateTracker.
551     *
552     * @hide
553     */
554    public void setCdmaEriText(String longName) {
555        mOperatorAlphaLong = longName;
556    }
557
558    public void setIsManualSelection(boolean isManual) {
559        mIsManualNetworkSelection = isManual;
560    }
561
562    /**
563     * Test whether two objects hold the same data values or both are null.
564     *
565     * @param a first obj
566     * @param b second obj
567     * @return true if two objects equal or both are null
568     */
569    private static boolean equalsHandlesNulls (Object a, Object b) {
570        return (a == null) ? (b == null) : a.equals (b);
571    }
572
573    /**
574     * Set ServiceState based on intent notifier map.
575     *
576     * @param m intent notifier map
577     * @hide
578     */
579    private void setFromNotifierBundle(Bundle m) {
580        mState = m.getInt("state");
581        mRoaming = m.getBoolean("roaming");
582        mOperatorAlphaLong = m.getString("operator-alpha-long");
583        mOperatorAlphaShort = m.getString("operator-alpha-short");
584        mOperatorNumeric = m.getString("operator-numeric");
585        mIsManualNetworkSelection = m.getBoolean("manual");
586        mRadioTechnology = m.getInt("radioTechnology");
587        mCssIndicator = m.getBoolean("cssIndicator");
588        mNetworkId = m.getInt("networkId");
589        mSystemId = m.getInt("systemId");
590        mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
591        mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
592        mIsEmergencyOnly = m.getBoolean("emergencyOnly");
593    }
594
595    /**
596     * Set intent notifier Bundle based on service state.
597     *
598     * @param m intent notifier Bundle
599     * @hide
600     */
601    public void fillInNotifierBundle(Bundle m) {
602        m.putInt("state", mState);
603        m.putBoolean("roaming", Boolean.valueOf(mRoaming));
604        m.putString("operator-alpha-long", mOperatorAlphaLong);
605        m.putString("operator-alpha-short", mOperatorAlphaShort);
606        m.putString("operator-numeric", mOperatorNumeric);
607        m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection));
608        m.putInt("radioTechnology", mRadioTechnology);
609        m.putBoolean("cssIndicator", mCssIndicator);
610        m.putInt("networkId", mNetworkId);
611        m.putInt("systemId", mSystemId);
612        m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
613        m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
614        m.putBoolean("emergencyOnly", Boolean.valueOf(mIsEmergencyOnly));
615    }
616
617    //***** CDMA
618    /** @hide */
619    public void setRadioTechnology(int state) {
620        this.mRadioTechnology = state;
621    }
622
623    /** @hide */
624    public void setCssIndicator(int css) {
625        this.mCssIndicator = (css != 0);
626    }
627
628    /** @hide */
629    public void setSystemAndNetworkId(int systemId, int networkId) {
630        this.mSystemId = systemId;
631        this.mNetworkId = networkId;
632    }
633
634    /** @hide */
635    public int getRadioTechnology() {
636        return this.mRadioTechnology;
637    }
638
639    /** @hide */
640    public int getCssIndicator() {
641        return this.mCssIndicator ? 1 : 0;
642    }
643
644    /** @hide */
645    public int getNetworkId() {
646        return this.mNetworkId;
647    }
648
649    /** @hide */
650    public int getSystemId() {
651        return this.mSystemId;
652    }
653}
654