ServiceState.java revision 4adacd23d4c91569b16fe50419f1a91f68d805bd
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    /** @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 = new Parcelable.Creator() {
224        public ServiceState createFromParcel(Parcel in) {
225            return new ServiceState(in);
226        }
227
228        public ServiceState[] newArray(int size) {
229            return new ServiceState[size];
230        }
231    };
232
233    /**
234     * Get current servcie state of phone
235     *
236     * @see #STATE_IN_SERVICE
237     * @see #STATE_OUT_OF_SERVICE
238     * @see #STATE_EMERGENCY_ONLY
239     * @see #STATE_POWER_OFF
240     */
241    public int getState() {
242        return mState;
243    }
244
245    /**
246     * Get current roaming indicator of phone
247     * (note: not just decoding from TS 27.007 7.2)
248     *
249     * @return true if TS 27.007 7.2 roaming is true
250     *              and ONS is different from SPN
251     *
252     */
253    public boolean getRoaming() {
254        return mRoaming;
255    }
256
257    /**
258     * @hide
259     */
260    public boolean isEmergencyOnly() {
261        return mIsEmergencyOnly;
262    }
263
264    /**
265     * @hide
266     */
267    public int getCdmaRoamingIndicator(){
268        return this.mCdmaRoamingIndicator;
269    }
270
271    /**
272     * @hide
273     */
274    public int getCdmaDefaultRoamingIndicator(){
275        return this.mCdmaDefaultRoamingIndicator;
276    }
277
278    /**
279     * @hide
280     */
281    public int getCdmaEriIconIndex() {
282        return this.mCdmaEriIconIndex;
283    }
284
285    /**
286     * @hide
287     */
288    public int getCdmaEriIconMode() {
289        return this.mCdmaEriIconMode;
290    }
291
292    /**
293     * Get current registered operator name in long alphanumeric format
294     *
295     * In GSM/UMTS, long format can be upto 16 characters long
296     * In CDMA, returns the ERI text, if set, otherwise the ONS
297     *
298     * @return long name of operator, null if unregistered or unknown
299     */
300    public String getOperatorAlphaLong() {
301        return mOperatorAlphaLong;
302    }
303
304    /**
305     * Get current registered operator name in short lphanumeric format
306     *
307     * In GSM/UMST, short format can be upto 8 characters long
308     *
309     * @return short name of operator, null if unregistered or unknown
310     */
311    public String getOperatorAlphaShort() {
312        return mOperatorAlphaShort;
313    }
314
315    /**
316     * Get current registered operator numeric id
317     *
318     * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
319     * network code
320     *
321     * The country code can be decoded using MccTable.countryCodeForMcc()
322     *
323     * @return numeric format of operator, null if unregistered or unknown
324     */
325    public String getOperatorNumeric() {
326        return mOperatorNumeric;
327    }
328
329    /**
330     * Get current network selection mode
331     *
332     * @return true if manual mode, false if automatic mode
333     */
334    public boolean getIsManualSelection() {
335        return mIsManualNetworkSelection;
336    }
337
338    @Override
339    public int hashCode() {
340        return ((mState * 0x1234)
341                + (mRoaming ? 1 : 0)
342                + (mIsManualNetworkSelection ? 1 : 0)
343                + ((null == mOperatorAlphaLong) ? 0 : mOperatorAlphaLong.hashCode())
344                + ((null == mOperatorAlphaShort) ? 0 : mOperatorAlphaShort.hashCode())
345                + ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode())
346                + mCdmaRoamingIndicator
347                + mCdmaDefaultRoamingIndicator
348                + (mIsEmergencyOnly ? 1 : 0));
349    }
350
351    @Override
352    public boolean equals (Object o) {
353        ServiceState s;
354
355        try {
356            s = (ServiceState) o;
357        } catch (ClassCastException ex) {
358            return false;
359        }
360
361        if (o == null) {
362            return false;
363        }
364
365        return (mState == s.mState
366                && mRoaming == s.mRoaming
367                && mIsManualNetworkSelection == s.mIsManualNetworkSelection
368                && equalsHandlesNulls(mOperatorAlphaLong, s.mOperatorAlphaLong)
369                && equalsHandlesNulls(mOperatorAlphaShort, s.mOperatorAlphaShort)
370                && equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric)
371                && equalsHandlesNulls(mRadioTechnology, s.mRadioTechnology)
372                && equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
373                && equalsHandlesNulls(mNetworkId, s.mNetworkId)
374                && equalsHandlesNulls(mSystemId, s.mSystemId)
375                && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
376                && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
377                        s.mCdmaDefaultRoamingIndicator)
378                && mIsEmergencyOnly == s.mIsEmergencyOnly);
379    }
380
381    @Override
382    public String toString() {
383        String radioTechnology = new String("Error in radioTechnology");
384        switch(this.mRadioTechnology) {
385        case 0:
386            radioTechnology = "Unknown";
387            break;
388        case 1:
389            radioTechnology = "GPRS";
390            break;
391        case 2:
392            radioTechnology = "EDGE";
393            break;
394        case 3:
395            radioTechnology = "UMTS";
396            break;
397        case 4:
398            radioTechnology = "IS95A";
399            break;
400        case 5:
401            radioTechnology = "IS95B";
402            break;
403        case 6:
404            radioTechnology = "1xRTT";
405            break;
406        case 7:
407            radioTechnology = "EvDo rev. 0";
408            break;
409        case 8:
410            radioTechnology = "EvDo rev. A";
411            break;
412        case 9:
413            radioTechnology = "HSDPA";
414            break;
415        case 10:
416            radioTechnology = "HSUPA";
417            break;
418        case 11:
419            radioTechnology = "HSPA";
420            break;
421        case 12:
422            radioTechnology = "EvDo rev. B";
423            break;
424        default:
425            Log.w(LOG_TAG, "mRadioTechnology variable out of range.");
426        break;
427        }
428
429        return (mState + " " + (mRoaming ? "roaming" : "home")
430                + " " + mOperatorAlphaLong
431                + " " + mOperatorAlphaShort
432                + " " + mOperatorNumeric
433                + " " + (mIsManualNetworkSelection ? "(manual)" : "")
434                + " " + radioTechnology
435                + " " + (mCssIndicator ? "CSS supported" : "CSS not supported")
436                + " " + mNetworkId
437                + " " + mSystemId
438                + "RoamInd: " + mCdmaRoamingIndicator
439                + "DefRoamInd: " + mCdmaDefaultRoamingIndicator
440                + "EmergOnly: " + mIsEmergencyOnly);
441    }
442
443    public void setStateOutOfService() {
444        mState = STATE_OUT_OF_SERVICE;
445        mRoaming = false;
446        mOperatorAlphaLong = null;
447        mOperatorAlphaShort = null;
448        mOperatorNumeric = null;
449        mIsManualNetworkSelection = false;
450        mRadioTechnology = 0;
451        mCssIndicator = false;
452        mNetworkId = -1;
453        mSystemId = -1;
454        mCdmaRoamingIndicator = -1;
455        mCdmaDefaultRoamingIndicator = -1;
456        mCdmaEriIconIndex = -1;
457        mCdmaEriIconMode = -1;
458        mIsEmergencyOnly = false;
459    }
460
461    // TODO - can't this be combined with the above func..
462    public void setStateOff() {
463        mState = STATE_POWER_OFF;
464        mRoaming = false;
465        mOperatorAlphaLong = null;
466        mOperatorAlphaShort = null;
467        mOperatorNumeric = null;
468        mIsManualNetworkSelection = false;
469        mRadioTechnology = 0;
470        mCssIndicator = false;
471        mNetworkId = -1;
472        mSystemId = -1;
473        mCdmaRoamingIndicator = -1;
474        mCdmaDefaultRoamingIndicator = -1;
475        mCdmaEriIconIndex = -1;
476        mCdmaEriIconMode = -1;
477        mIsEmergencyOnly = false;
478    }
479
480    public void setState(int state) {
481        mState = state;
482    }
483
484    public void setRoaming(boolean roaming) {
485        mRoaming = roaming;
486    }
487
488
489    /**
490     * @hide
491     */
492    public void setEmergencyOnly(boolean emergencyOnly) {
493        mIsEmergencyOnly = emergencyOnly;
494    }
495
496    /**
497     * @hide
498     */
499    public void setCdmaRoamingIndicator(int roaming) {
500        this.mCdmaRoamingIndicator = roaming;
501    }
502
503    /**
504     * @hide
505     */
506    public void setCdmaDefaultRoamingIndicator (int roaming) {
507        this.mCdmaDefaultRoamingIndicator = roaming;
508    }
509
510    /**
511     * @hide
512     */
513    public void setCdmaEriIconIndex(int index) {
514        this.mCdmaEriIconIndex = index;
515    }
516
517    /**
518     * @hide
519     */
520    public void setCdmaEriIconMode(int mode) {
521        this.mCdmaEriIconMode = mode;
522    }
523
524    public void setOperatorName(String longName, String shortName, String numeric) {
525        mOperatorAlphaLong = longName;
526        mOperatorAlphaShort = shortName;
527        mOperatorNumeric = numeric;
528    }
529
530    /**
531     * In CDMA mOperatorAlphaLong can be set from the ERI
532     * text, this is done from the CDMAPhone and not from the CdmaServiceStateTracker
533     *
534     * @hide
535     */
536    public void setCdmaEriText(String longName) {
537        mOperatorAlphaLong = longName;
538    }
539
540    public void setIsManualSelection(boolean isManual) {
541        mIsManualNetworkSelection = isManual;
542    }
543
544    /**
545     * Test whether two objects hold the same data values or both are null
546     *
547     * @param a first obj
548     * @param b second obj
549     * @return true if two objects equal or both are null
550     */
551    private static boolean equalsHandlesNulls (Object a, Object b) {
552        return (a == null) ? (b == null) : a.equals (b);
553    }
554
555    /**
556     * Set ServiceState based on intent notifier map
557     *
558     * @param m intent notifier map
559     * @hide
560     */
561    private void setFromNotifierBundle(Bundle m) {
562        mState = m.getInt("state");
563        mRoaming = m.getBoolean("roaming");
564        mOperatorAlphaLong = m.getString("operator-alpha-long");
565        mOperatorAlphaShort = m.getString("operator-alpha-short");
566        mOperatorNumeric = m.getString("operator-numeric");
567        mIsManualNetworkSelection = m.getBoolean("manual");
568        mRadioTechnology = m.getInt("radioTechnology");
569        mCssIndicator = m.getBoolean("cssIndicator");
570        mNetworkId = m.getInt("networkId");
571        mSystemId = m.getInt("systemId");
572        mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
573        mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
574        mIsEmergencyOnly = m.getBoolean("emergencyOnly");
575    }
576
577    /**
578     * Set intent notifier Bundle based on service state
579     *
580     * @param m intent notifier Bundle
581     * @hide
582     */
583    public void fillInNotifierBundle(Bundle m) {
584        m.putInt("state", mState);
585        m.putBoolean("roaming", Boolean.valueOf(mRoaming));
586        m.putString("operator-alpha-long", mOperatorAlphaLong);
587        m.putString("operator-alpha-short", mOperatorAlphaShort);
588        m.putString("operator-numeric", mOperatorNumeric);
589        m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection));
590        m.putInt("radioTechnology", mRadioTechnology);
591        m.putBoolean("cssIndicator", mCssIndicator);
592        m.putInt("networkId", mNetworkId);
593        m.putInt("systemId", mSystemId);
594        m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
595        m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
596        m.putBoolean("emergencyOnly", Boolean.valueOf(mIsEmergencyOnly));
597    }
598
599    //***** CDMA
600    /** @hide */
601    public void setRadioTechnology(int state) {
602        this.mRadioTechnology = state;
603    }
604
605    /** @hide */
606    public void setCssIndicator(int css) {
607        this.mCssIndicator = (css != 0);
608    }
609
610    /** @hide */
611    public void setSystemAndNetworkId(int systemId, int networkId) {
612        this.mSystemId = systemId;
613        this.mNetworkId = networkId;
614    }
615
616    /** @hide */
617    public int getRadioTechnology() {
618        return this.mRadioTechnology;
619    }
620
621    /** @hide */
622    public int getCssIndicator() {
623        return this.mCssIndicator ? 1 : 0;
624    }
625
626    /** @hide */
627    public int getNetworkId() {
628        return this.mNetworkId;
629    }
630
631    /** @hide */
632    public int getSystemId() {
633        return this.mSystemId;
634    }
635}
636