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