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