ServiceState.java revision ea0d71390ab528ffea7161674333b0bbab8356df
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.telephony.Rlog;
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    static final boolean DBG = false;
40    static final boolean VDBG = false;  // STOPSHIP if true
41
42    /**
43     * Normal operation condition, the phone is registered
44     * with an operator either in home network or in roaming.
45     */
46    public static final int STATE_IN_SERVICE = 0;
47
48    /**
49     * Phone is not registered with any operator, the phone
50     * can be currently searching a new operator to register to, or not
51     * searching to registration at all, or registration is denied, or radio
52     * signal is not available.
53     */
54    public static final int STATE_OUT_OF_SERVICE = 1;
55
56    /**
57     * The phone is registered and locked.  Only emergency numbers are allowed. {@more}
58     */
59    public static final int STATE_EMERGENCY_ONLY = 2;
60
61    /**
62     * Radio of telephony is explicitly powered off.
63     */
64    public static final int STATE_POWER_OFF = 3;
65
66    /**
67     * RIL level registration state values from ril.h
68     * ((const char **)response)[0] is registration state 0-6,
69     *              0 - Not registered, MT is not currently searching
70     *                  a new operator to register
71     *              1 - Registered, home network
72     *              2 - Not registered, but MT is currently searching
73     *                  a new operator to register
74     *              3 - Registration denied
75     *              4 - Unknown
76     *              5 - Registered, roaming
77     *             10 - Same as 0, but indicates that emergency calls
78     *                  are enabled.
79     *             12 - Same as 2, but indicates that emergency calls
80     *                  are enabled.
81     *             13 - Same as 3, but indicates that emergency calls
82     *                  are enabled.
83     *             14 - Same as 4, but indicates that emergency calls
84     *                  are enabled.
85     * @hide
86     */
87    public static final int RIL_REG_STATE_NOT_REG = 0;
88    /** @hide */
89    public static final int RIL_REG_STATE_HOME = 1;
90    /** @hide */
91    public static final int RIL_REG_STATE_SEARCHING = 2;
92    /** @hide */
93    public static final int RIL_REG_STATE_DENIED = 3;
94    /** @hide */
95    public static final int RIL_REG_STATE_UNKNOWN = 4;
96    /** @hide */
97    public static final int RIL_REG_STATE_ROAMING = 5;
98    /** @hide */
99    public static final int RIL_REG_STATE_NOT_REG_EMERGENCY_CALL_ENABLED = 10;
100    /** @hide */
101    public static final int RIL_REG_STATE_SEARCHING_EMERGENCY_CALL_ENABLED = 12;
102    /** @hide */
103    public static final int RIL_REG_STATE_DENIED_EMERGENCY_CALL_ENABLED = 13;
104    /** @hide */
105    public static final int RIL_REG_STATE_UNKNOWN_EMERGENCY_CALL_ENABLED = 14;
106
107    /**
108     * Available radio technologies for GSM, UMTS and CDMA.
109     * Duplicates the constants from hardware/radio/include/ril.h
110     * This should only be used by agents working with the ril.  Others
111     * should use the equivalent TelephonyManager.NETWORK_TYPE_*
112     */
113    /** @hide */
114    public static final int RIL_RADIO_TECHNOLOGY_UNKNOWN = 0;
115    /** @hide */
116    public static final int RIL_RADIO_TECHNOLOGY_GPRS = 1;
117    /** @hide */
118    public static final int RIL_RADIO_TECHNOLOGY_EDGE = 2;
119    /** @hide */
120    public static final int RIL_RADIO_TECHNOLOGY_UMTS = 3;
121    /** @hide */
122    public static final int RIL_RADIO_TECHNOLOGY_IS95A = 4;
123    /** @hide */
124    public static final int RIL_RADIO_TECHNOLOGY_IS95B = 5;
125    /** @hide */
126    public static final int RIL_RADIO_TECHNOLOGY_1xRTT = 6;
127    /** @hide */
128    public static final int RIL_RADIO_TECHNOLOGY_EVDO_0 = 7;
129    /** @hide */
130    public static final int RIL_RADIO_TECHNOLOGY_EVDO_A = 8;
131    /** @hide */
132    public static final int RIL_RADIO_TECHNOLOGY_HSDPA = 9;
133    /** @hide */
134    public static final int RIL_RADIO_TECHNOLOGY_HSUPA = 10;
135    /** @hide */
136    public static final int RIL_RADIO_TECHNOLOGY_HSPA = 11;
137    /** @hide */
138    public static final int RIL_RADIO_TECHNOLOGY_EVDO_B = 12;
139    /** @hide */
140    public static final int RIL_RADIO_TECHNOLOGY_EHRPD = 13;
141    /** @hide */
142    public static final int RIL_RADIO_TECHNOLOGY_LTE = 14;
143    /** @hide */
144    public static final int RIL_RADIO_TECHNOLOGY_HSPAP = 15;
145    /**
146     * GSM radio technology only supports voice. It does not support data.
147     * @hide
148     */
149    public static final int RIL_RADIO_TECHNOLOGY_GSM = 16;
150    /** @hide */
151    public static final int RIL_RADIO_TECHNOLOGY_TD_SCDMA = 17;
152    /**
153     * IWLAN
154     * @hide
155     */
156    public static final int RIL_RADIO_TECHNOLOGY_IWLAN = 18;
157
158    /**
159     * LTE_CA
160     * @hide
161     */
162    public static final int RIL_RADIO_TECHNOLOGY_LTE_CA = 19;
163
164    /** @hide */
165    public static final int RIL_RADIO_CDMA_TECHNOLOGY_BITMASK =
166            (1 << (RIL_RADIO_TECHNOLOGY_IS95A - 1))
167                    | (1 << (RIL_RADIO_TECHNOLOGY_IS95B - 1))
168                    | (1 << (RIL_RADIO_TECHNOLOGY_1xRTT - 1))
169                    | (1 << (RIL_RADIO_TECHNOLOGY_EVDO_0 - 1))
170                    | (1 << (RIL_RADIO_TECHNOLOGY_EVDO_A - 1))
171                    | (1 << (RIL_RADIO_TECHNOLOGY_EVDO_B - 1))
172                    | (1 << (RIL_RADIO_TECHNOLOGY_EHRPD - 1));
173
174    /**
175     * Available registration states for GSM, UMTS and CDMA.
176     */
177    /** @hide */
178    public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_NOT_SEARCHING = 0;
179    /** @hide */
180    public static final int REGISTRATION_STATE_HOME_NETWORK = 1;
181    /** @hide */
182    public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_SEARCHING = 2;
183    /** @hide */
184    public static final int REGISTRATION_STATE_REGISTRATION_DENIED = 3;
185    /** @hide */
186    public static final int REGISTRATION_STATE_UNKNOWN = 4;
187    /** @hide */
188    public static final int REGISTRATION_STATE_ROAMING = 5;
189
190    private int mVoiceRegState = STATE_OUT_OF_SERVICE;
191    private int mDataRegState = STATE_OUT_OF_SERVICE;
192
193    /**
194     * Roaming type
195     * HOME : in home network
196     * @hide
197     */
198    public static final int ROAMING_TYPE_NOT_ROAMING = 0;
199    /**
200     * Roaming type
201     * UNKNOWN : in a roaming network, but we can not tell if it's domestic or international
202     * @hide
203     */
204    public static final int ROAMING_TYPE_UNKNOWN = 1;
205    /**
206     * Roaming type
207     * DOMESTIC : in domestic roaming network
208     * @hide
209     */
210    public static final int ROAMING_TYPE_DOMESTIC = 2;
211    /**
212     * Roaming type
213     * INTERNATIONAL : in international roaming network
214     * @hide
215     */
216    public static final int ROAMING_TYPE_INTERNATIONAL = 3;
217
218    private int mVoiceRoamingType;
219    private int mDataRoamingType;
220    private String mVoiceOperatorAlphaLong;
221    private String mVoiceOperatorAlphaShort;
222    private String mVoiceOperatorNumeric;
223    private String mDataOperatorAlphaLong;
224    private String mDataOperatorAlphaShort;
225    private String mDataOperatorNumeric;
226    private boolean mIsManualNetworkSelection;
227
228    private boolean mIsEmergencyOnly;
229
230    private int mRilVoiceRadioTechnology;
231    private int mRilDataRadioTechnology;
232
233    private boolean mCssIndicator;
234    private int mNetworkId;
235    private int mSystemId;
236    private int mCdmaRoamingIndicator;
237    private int mCdmaDefaultRoamingIndicator;
238    private int mCdmaEriIconIndex;
239    private int mCdmaEriIconMode;
240
241    private boolean mIsDataRoamingFromRegistration;
242
243    private boolean mIsUsingCarrierAggregation;
244
245    /**
246     * get String description of roaming type
247     * @hide
248     */
249    public static final String getRoamingLogString(int roamingType) {
250        switch (roamingType) {
251            case ROAMING_TYPE_NOT_ROAMING:
252                return "home";
253
254            case ROAMING_TYPE_UNKNOWN:
255                return "roaming";
256
257            case ROAMING_TYPE_DOMESTIC:
258                return "Domestic Roaming";
259
260            case ROAMING_TYPE_INTERNATIONAL:
261                return "International Roaming";
262
263            default:
264                return "UNKNOWN";
265        }
266    }
267
268    /**
269     * Create a new ServiceState from a intent notifier Bundle
270     *
271     * This method is used by PhoneStateIntentReceiver and maybe by
272     * external applications.
273     *
274     * @param m Bundle from intent notifier
275     * @return newly created ServiceState
276     * @hide
277     */
278    public static ServiceState newFromBundle(Bundle m) {
279        ServiceState ret;
280        ret = new ServiceState();
281        ret.setFromNotifierBundle(m);
282        return ret;
283    }
284
285    /**
286     * Empty constructor
287     */
288    public ServiceState() {
289    }
290
291    /**
292     * Copy constructors
293     *
294     * @param s Source service state
295     */
296    public ServiceState(ServiceState s) {
297        copyFrom(s);
298    }
299
300    protected void copyFrom(ServiceState s) {
301        mVoiceRegState = s.mVoiceRegState;
302        mDataRegState = s.mDataRegState;
303        mVoiceRoamingType = s.mVoiceRoamingType;
304        mDataRoamingType = s.mDataRoamingType;
305        mVoiceOperatorAlphaLong = s.mVoiceOperatorAlphaLong;
306        mVoiceOperatorAlphaShort = s.mVoiceOperatorAlphaShort;
307        mVoiceOperatorNumeric = s.mVoiceOperatorNumeric;
308        mDataOperatorAlphaLong = s.mDataOperatorAlphaLong;
309        mDataOperatorAlphaShort = s.mDataOperatorAlphaShort;
310        mDataOperatorNumeric = s.mDataOperatorNumeric;
311        mIsManualNetworkSelection = s.mIsManualNetworkSelection;
312        mRilVoiceRadioTechnology = s.mRilVoiceRadioTechnology;
313        mRilDataRadioTechnology = s.mRilDataRadioTechnology;
314        mCssIndicator = s.mCssIndicator;
315        mNetworkId = s.mNetworkId;
316        mSystemId = s.mSystemId;
317        mCdmaRoamingIndicator = s.mCdmaRoamingIndicator;
318        mCdmaDefaultRoamingIndicator = s.mCdmaDefaultRoamingIndicator;
319        mCdmaEriIconIndex = s.mCdmaEriIconIndex;
320        mCdmaEriIconMode = s.mCdmaEriIconMode;
321        mIsEmergencyOnly = s.mIsEmergencyOnly;
322        mIsDataRoamingFromRegistration = s.mIsDataRoamingFromRegistration;
323        mIsUsingCarrierAggregation = s.mIsUsingCarrierAggregation;
324    }
325
326    /**
327     * Construct a ServiceState object from the given parcel.
328     */
329    public ServiceState(Parcel in) {
330        mVoiceRegState = in.readInt();
331        mDataRegState = in.readInt();
332        mVoiceRoamingType = in.readInt();
333        mDataRoamingType = in.readInt();
334        mVoiceOperatorAlphaLong = in.readString();
335        mVoiceOperatorAlphaShort = in.readString();
336        mVoiceOperatorNumeric = in.readString();
337        mDataOperatorAlphaLong = in.readString();
338        mDataOperatorAlphaShort = in.readString();
339        mDataOperatorNumeric = in.readString();
340        mIsManualNetworkSelection = in.readInt() != 0;
341        mRilVoiceRadioTechnology = in.readInt();
342        mRilDataRadioTechnology = in.readInt();
343        mCssIndicator = (in.readInt() != 0);
344        mNetworkId = in.readInt();
345        mSystemId = in.readInt();
346        mCdmaRoamingIndicator = in.readInt();
347        mCdmaDefaultRoamingIndicator = in.readInt();
348        mCdmaEriIconIndex = in.readInt();
349        mCdmaEriIconMode = in.readInt();
350        mIsEmergencyOnly = in.readInt() != 0;
351        mIsDataRoamingFromRegistration = in.readInt() != 0;
352        mIsUsingCarrierAggregation = in.readInt() != 0;
353    }
354
355    public void writeToParcel(Parcel out, int flags) {
356        out.writeInt(mVoiceRegState);
357        out.writeInt(mDataRegState);
358        out.writeInt(mVoiceRoamingType);
359        out.writeInt(mDataRoamingType);
360        out.writeString(mVoiceOperatorAlphaLong);
361        out.writeString(mVoiceOperatorAlphaShort);
362        out.writeString(mVoiceOperatorNumeric);
363        out.writeString(mDataOperatorAlphaLong);
364        out.writeString(mDataOperatorAlphaShort);
365        out.writeString(mDataOperatorNumeric);
366        out.writeInt(mIsManualNetworkSelection ? 1 : 0);
367        out.writeInt(mRilVoiceRadioTechnology);
368        out.writeInt(mRilDataRadioTechnology);
369        out.writeInt(mCssIndicator ? 1 : 0);
370        out.writeInt(mNetworkId);
371        out.writeInt(mSystemId);
372        out.writeInt(mCdmaRoamingIndicator);
373        out.writeInt(mCdmaDefaultRoamingIndicator);
374        out.writeInt(mCdmaEriIconIndex);
375        out.writeInt(mCdmaEriIconMode);
376        out.writeInt(mIsEmergencyOnly ? 1 : 0);
377        out.writeInt(mIsDataRoamingFromRegistration ? 1 : 0);
378        out.writeInt(mIsUsingCarrierAggregation ? 1 : 0);
379    }
380
381    public int describeContents() {
382        return 0;
383    }
384
385    public static final Parcelable.Creator<ServiceState> CREATOR =
386            new Parcelable.Creator<ServiceState>() {
387        public ServiceState createFromParcel(Parcel in) {
388            return new ServiceState(in);
389        }
390
391        public ServiceState[] newArray(int size) {
392            return new ServiceState[size];
393        }
394    };
395
396    /**
397     * Get current voice service state
398     */
399    public int getState() {
400        return getVoiceRegState();
401    }
402
403    /**
404     * Get current voice service state
405     *
406     * @see #STATE_IN_SERVICE
407     * @see #STATE_OUT_OF_SERVICE
408     * @see #STATE_EMERGENCY_ONLY
409     * @see #STATE_POWER_OFF
410     *
411     * @hide
412     */
413    public int getVoiceRegState() {
414        return mVoiceRegState;
415    }
416
417    /**
418     * Get current data service state
419     *
420     * @see #STATE_IN_SERVICE
421     * @see #STATE_OUT_OF_SERVICE
422     * @see #STATE_EMERGENCY_ONLY
423     * @see #STATE_POWER_OFF
424     *
425     * @hide
426     */
427    public int getDataRegState() {
428        return mDataRegState;
429    }
430
431    /**
432     * Get current roaming indicator of phone
433     * (note: not just decoding from TS 27.007 7.2)
434     *
435     * @return true if TS 27.007 7.2 roaming is true
436     *              and ONS is different from SPN
437     */
438    public boolean getRoaming() {
439        return getVoiceRoaming() || getDataRoaming();
440    }
441
442    /**
443     * Get current voice network roaming status
444     * @return roaming status
445     * @hide
446     */
447    public boolean getVoiceRoaming() {
448        return mVoiceRoamingType != ROAMING_TYPE_NOT_ROAMING;
449    }
450
451    /**
452     * Get current voice network roaming type
453     * @return roaming type
454     * @hide
455     */
456    public int getVoiceRoamingType() {
457        return mVoiceRoamingType;
458    }
459
460    /**
461     * Get current data network roaming type
462     * @return roaming type
463     * @hide
464     */
465    public boolean getDataRoaming() {
466        return mDataRoamingType != ROAMING_TYPE_NOT_ROAMING;
467    }
468
469    /**
470     * Set whether data network registration state is roaming
471     *
472     * This should only be set to the roaming value received
473     * once the data registration phase has completed.
474     * @hide
475     */
476    public void setDataRoamingFromRegistration(boolean dataRoaming) {
477        mIsDataRoamingFromRegistration = dataRoaming;
478    }
479
480    /**
481     * Get whether data network registration state is roaming
482     * @return true if registration indicates roaming, false otherwise
483     * @hide
484     */
485    public boolean getDataRoamingFromRegistration() {
486        return mIsDataRoamingFromRegistration;
487    }
488
489    /**
490     * Get current data network roaming type
491     * @return roaming type
492     * @hide
493     */
494    public int getDataRoamingType() {
495        return mDataRoamingType;
496    }
497
498    /**
499     * @hide
500     */
501    public boolean isEmergencyOnly() {
502        return mIsEmergencyOnly;
503    }
504
505    /**
506     * @hide
507     */
508    public int getCdmaRoamingIndicator(){
509        return this.mCdmaRoamingIndicator;
510    }
511
512    /**
513     * @hide
514     */
515    public int getCdmaDefaultRoamingIndicator(){
516        return this.mCdmaDefaultRoamingIndicator;
517    }
518
519    /**
520     * @hide
521     */
522    public int getCdmaEriIconIndex() {
523        return this.mCdmaEriIconIndex;
524    }
525
526    /**
527     * @hide
528     */
529    public int getCdmaEriIconMode() {
530        return this.mCdmaEriIconMode;
531    }
532
533    /**
534     * Get current registered operator name in long alphanumeric format.
535     *
536     * In GSM/UMTS, long format can be up to 16 characters long.
537     * In CDMA, returns the ERI text, if set. Otherwise, returns the ONS.
538     *
539     * @return long name of operator, null if unregistered or unknown
540     */
541    public String getOperatorAlphaLong() {
542        return mVoiceOperatorAlphaLong;
543    }
544
545    /**
546     * Get current registered voice network operator name in long alphanumeric format.
547     * @return long name of operator
548     * @hide
549     */
550    public String getVoiceOperatorAlphaLong() {
551        return mVoiceOperatorAlphaLong;
552    }
553
554    /**
555     * Get current registered data network operator name in long alphanumeric format.
556     * @return long name of voice operator
557     * @hide
558     */
559    public String getDataOperatorAlphaLong() {
560        return mDataOperatorAlphaLong;
561    }
562
563    /**
564     * Get current registered operator name in short alphanumeric format.
565     *
566     * In GSM/UMTS, short format can be up to 8 characters long.
567     *
568     * @return short name of operator, null if unregistered or unknown
569     */
570    public String getOperatorAlphaShort() {
571        return mVoiceOperatorAlphaShort;
572    }
573
574    /**
575     * Get current registered voice network operator name in short alphanumeric format.
576     * @return short name of operator, null if unregistered or unknown
577     * @hide
578     */
579    public String getVoiceOperatorAlphaShort() {
580        return mVoiceOperatorAlphaShort;
581    }
582
583    /**
584     * Get current registered data network operator name in short alphanumeric format.
585     * @return short name of operator, null if unregistered or unknown
586     * @hide
587     */
588    public String getDataOperatorAlphaShort() {
589        return mDataOperatorAlphaShort;
590    }
591
592    /**
593     * Get current registered operator numeric id.
594     *
595     * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
596     * network code.
597     *
598     * @return numeric format of operator, null if unregistered or unknown
599     */
600    /*
601     * The country code can be decoded using
602     * {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}.
603     */
604    public String getOperatorNumeric() {
605        return mVoiceOperatorNumeric;
606    }
607
608    /**
609     * Get current registered voice network operator numeric id.
610     * @return numeric format of operator, null if unregistered or unknown
611     * @hide
612     */
613    public String getVoiceOperatorNumeric() {
614        return mVoiceOperatorNumeric;
615    }
616
617    /**
618     * Get current registered data network operator numeric id.
619     * @return numeric format of operator, null if unregistered or unknown
620     * @hide
621     */
622    public String getDataOperatorNumeric() {
623        return mDataOperatorNumeric;
624    }
625
626    /**
627     * Get current network selection mode.
628     *
629     * @return true if manual mode, false if automatic mode
630     */
631    public boolean getIsManualSelection() {
632        return mIsManualNetworkSelection;
633    }
634
635    @Override
636    public int hashCode() {
637        return ((mVoiceRegState * 31)
638                + (mDataRegState * 37)
639                + mVoiceRoamingType
640                + mDataRoamingType
641                + (mIsManualNetworkSelection ? 1 : 0)
642                + ((null == mVoiceOperatorAlphaLong) ? 0 : mVoiceOperatorAlphaLong.hashCode())
643                + ((null == mVoiceOperatorAlphaShort) ? 0 : mVoiceOperatorAlphaShort.hashCode())
644                + ((null == mVoiceOperatorNumeric) ? 0 : mVoiceOperatorNumeric.hashCode())
645                + ((null == mDataOperatorAlphaLong) ? 0 : mDataOperatorAlphaLong.hashCode())
646                + ((null == mDataOperatorAlphaShort) ? 0 : mDataOperatorAlphaShort.hashCode())
647                + ((null == mDataOperatorNumeric) ? 0 : mDataOperatorNumeric.hashCode())
648                + mCdmaRoamingIndicator
649                + mCdmaDefaultRoamingIndicator
650                + (mIsEmergencyOnly ? 1 : 0)
651                + (mIsDataRoamingFromRegistration ? 1 : 0));
652    }
653
654    @Override
655    public boolean equals (Object o) {
656        ServiceState s;
657
658        try {
659            s = (ServiceState) o;
660        } catch (ClassCastException ex) {
661            return false;
662        }
663
664        if (o == null) {
665            return false;
666        }
667
668        return (mVoiceRegState == s.mVoiceRegState
669                && mDataRegState == s.mDataRegState
670                && mIsManualNetworkSelection == s.mIsManualNetworkSelection
671                && mVoiceRoamingType == s.mVoiceRoamingType
672                && mDataRoamingType == s.mDataRoamingType
673                && equalsHandlesNulls(mVoiceOperatorAlphaLong, s.mVoiceOperatorAlphaLong)
674                && equalsHandlesNulls(mVoiceOperatorAlphaShort, s.mVoiceOperatorAlphaShort)
675                && equalsHandlesNulls(mVoiceOperatorNumeric, s.mVoiceOperatorNumeric)
676                && equalsHandlesNulls(mDataOperatorAlphaLong, s.mDataOperatorAlphaLong)
677                && equalsHandlesNulls(mDataOperatorAlphaShort, s.mDataOperatorAlphaShort)
678                && equalsHandlesNulls(mDataOperatorNumeric, s.mDataOperatorNumeric)
679                && equalsHandlesNulls(mRilVoiceRadioTechnology, s.mRilVoiceRadioTechnology)
680                && equalsHandlesNulls(mRilDataRadioTechnology, s.mRilDataRadioTechnology)
681                && equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
682                && equalsHandlesNulls(mNetworkId, s.mNetworkId)
683                && equalsHandlesNulls(mSystemId, s.mSystemId)
684                && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
685                && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
686                        s.mCdmaDefaultRoamingIndicator)
687                && mIsEmergencyOnly == s.mIsEmergencyOnly
688                && mIsDataRoamingFromRegistration == s.mIsDataRoamingFromRegistration
689                && mIsUsingCarrierAggregation == s.mIsUsingCarrierAggregation);
690    }
691
692    /**
693     * Convert radio technology to String
694     *
695     * @param radioTechnology
696     * @return String representation of the RAT
697     *
698     * @hide
699     */
700    public static String rilRadioTechnologyToString(int rt) {
701        String rtString;
702
703        switch(rt) {
704            case RIL_RADIO_TECHNOLOGY_UNKNOWN:
705                rtString = "Unknown";
706                break;
707            case RIL_RADIO_TECHNOLOGY_GPRS:
708                rtString = "GPRS";
709                break;
710            case RIL_RADIO_TECHNOLOGY_EDGE:
711                rtString = "EDGE";
712                break;
713            case RIL_RADIO_TECHNOLOGY_UMTS:
714                rtString = "UMTS";
715                break;
716            case RIL_RADIO_TECHNOLOGY_IS95A:
717                rtString = "CDMA-IS95A";
718                break;
719            case RIL_RADIO_TECHNOLOGY_IS95B:
720                rtString = "CDMA-IS95B";
721                break;
722            case RIL_RADIO_TECHNOLOGY_1xRTT:
723                rtString = "1xRTT";
724                break;
725            case RIL_RADIO_TECHNOLOGY_EVDO_0:
726                rtString = "EvDo-rev.0";
727                break;
728            case RIL_RADIO_TECHNOLOGY_EVDO_A:
729                rtString = "EvDo-rev.A";
730                break;
731            case RIL_RADIO_TECHNOLOGY_HSDPA:
732                rtString = "HSDPA";
733                break;
734            case RIL_RADIO_TECHNOLOGY_HSUPA:
735                rtString = "HSUPA";
736                break;
737            case RIL_RADIO_TECHNOLOGY_HSPA:
738                rtString = "HSPA";
739                break;
740            case RIL_RADIO_TECHNOLOGY_EVDO_B:
741                rtString = "EvDo-rev.B";
742                break;
743            case RIL_RADIO_TECHNOLOGY_EHRPD:
744                rtString = "eHRPD";
745                break;
746            case RIL_RADIO_TECHNOLOGY_LTE:
747                rtString = "LTE";
748                break;
749            case RIL_RADIO_TECHNOLOGY_HSPAP:
750                rtString = "HSPAP";
751                break;
752            case RIL_RADIO_TECHNOLOGY_GSM:
753                rtString = "GSM";
754                break;
755            case RIL_RADIO_TECHNOLOGY_IWLAN:
756                rtString = "IWLAN";
757                break;
758            case RIL_RADIO_TECHNOLOGY_TD_SCDMA:
759                rtString = "TD-SCDMA";
760                break;
761            case RIL_RADIO_TECHNOLOGY_LTE_CA:
762                rtString = "LTE_CA";
763                break;
764            default:
765                rtString = "Unexpected";
766                Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
767                break;
768        }
769        return rtString;
770    }
771
772    @Override
773    public String toString() {
774        String radioTechnology = rilRadioTechnologyToString(mRilVoiceRadioTechnology);
775        String dataRadioTechnology = rilRadioTechnologyToString(mRilDataRadioTechnology);
776
777        return (mVoiceRegState + " " + mDataRegState
778                + " "
779                + "voice " + getRoamingLogString(mVoiceRoamingType)
780                + " "
781                + "data " + getRoamingLogString(mDataRoamingType)
782                + " " + mVoiceOperatorAlphaLong
783                + " " + mVoiceOperatorAlphaShort
784                + " " + mVoiceOperatorNumeric
785                + " " + mDataOperatorAlphaLong
786                + " " + mDataOperatorAlphaShort
787                + " " + mDataOperatorNumeric
788                + " " + (mIsManualNetworkSelection ? "(manual)" : "")
789                + " " + radioTechnology
790                + " " + dataRadioTechnology
791                + " " + (mCssIndicator ? "CSS supported" : "CSS not supported")
792                + " " + mNetworkId
793                + " " + mSystemId
794                + " RoamInd=" + mCdmaRoamingIndicator
795                + " DefRoamInd=" + mCdmaDefaultRoamingIndicator
796                + " EmergOnly=" + mIsEmergencyOnly
797                + " IsDataRoamingFromRegistration=" + mIsDataRoamingFromRegistration
798                + " IsUsingCarrierAggregation=" + mIsUsingCarrierAggregation);
799    }
800
801    private void setNullState(int state) {
802        if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setNullState=" + state);
803        mVoiceRegState = state;
804        mDataRegState = state;
805        mVoiceRoamingType = ROAMING_TYPE_NOT_ROAMING;
806        mDataRoamingType = ROAMING_TYPE_NOT_ROAMING;
807        mVoiceOperatorAlphaLong = null;
808        mVoiceOperatorAlphaShort = null;
809        mVoiceOperatorNumeric = null;
810        mDataOperatorAlphaLong = null;
811        mDataOperatorAlphaShort = null;
812        mDataOperatorNumeric = null;
813        mIsManualNetworkSelection = false;
814        mRilVoiceRadioTechnology = 0;
815        mRilDataRadioTechnology = 0;
816        mCssIndicator = false;
817        mNetworkId = -1;
818        mSystemId = -1;
819        mCdmaRoamingIndicator = -1;
820        mCdmaDefaultRoamingIndicator = -1;
821        mCdmaEriIconIndex = -1;
822        mCdmaEriIconMode = -1;
823        mIsEmergencyOnly = false;
824        mIsDataRoamingFromRegistration = false;
825        mIsUsingCarrierAggregation = false;
826    }
827
828    public void setStateOutOfService() {
829        setNullState(STATE_OUT_OF_SERVICE);
830    }
831
832    public void setStateOff() {
833        setNullState(STATE_POWER_OFF);
834    }
835
836    public void setState(int state) {
837        setVoiceRegState(state);
838        if (DBG) Rlog.e(LOG_TAG, "[ServiceState] setState deprecated use setVoiceRegState()");
839    }
840
841    /** @hide */
842    public void setVoiceRegState(int state) {
843        mVoiceRegState = state;
844        if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setVoiceRegState=" + mVoiceRegState);
845    }
846
847    /** @hide */
848    public void setDataRegState(int state) {
849        mDataRegState = state;
850        if (VDBG) Rlog.d(LOG_TAG, "[ServiceState] setDataRegState=" + mDataRegState);
851    }
852
853    public void setRoaming(boolean roaming) {
854        mVoiceRoamingType = (roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
855        mDataRoamingType = mVoiceRoamingType;
856    }
857
858    /** @hide */
859    public void setVoiceRoaming(boolean roaming) {
860        mVoiceRoamingType = (roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
861    }
862
863    /** @hide */
864    public void setVoiceRoamingType(int type) {
865        mVoiceRoamingType = type;
866    }
867
868    /** @hide */
869    public void setDataRoaming(boolean dataRoaming) {
870        mDataRoamingType = (dataRoaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
871    }
872
873    /** @hide */
874    public void setDataRoamingType(int type) {
875        mDataRoamingType = type;
876    }
877
878    /**
879     * @hide
880     */
881    public void setEmergencyOnly(boolean emergencyOnly) {
882        mIsEmergencyOnly = emergencyOnly;
883    }
884
885    /**
886     * @hide
887     */
888    public void setCdmaRoamingIndicator(int roaming) {
889        this.mCdmaRoamingIndicator = roaming;
890    }
891
892    /**
893     * @hide
894     */
895    public void setCdmaDefaultRoamingIndicator (int roaming) {
896        this.mCdmaDefaultRoamingIndicator = roaming;
897    }
898
899    /**
900     * @hide
901     */
902    public void setCdmaEriIconIndex(int index) {
903        this.mCdmaEriIconIndex = index;
904    }
905
906    /**
907     * @hide
908     */
909    public void setCdmaEriIconMode(int mode) {
910        this.mCdmaEriIconMode = mode;
911    }
912
913    public void setOperatorName(String longName, String shortName, String numeric) {
914        mVoiceOperatorAlphaLong = longName;
915        mVoiceOperatorAlphaShort = shortName;
916        mVoiceOperatorNumeric = numeric;
917        mDataOperatorAlphaLong = longName;
918        mDataOperatorAlphaShort = shortName;
919        mDataOperatorNumeric = numeric;
920    }
921
922    /** @hide */
923    public void setVoiceOperatorName(String longName, String shortName, String numeric) {
924        mVoiceOperatorAlphaLong = longName;
925        mVoiceOperatorAlphaShort = shortName;
926        mVoiceOperatorNumeric = numeric;
927    }
928
929    /** @hide */
930    public void setDataOperatorName(String longName, String shortName, String numeric) {
931        mDataOperatorAlphaLong = longName;
932        mDataOperatorAlphaShort = shortName;
933        mDataOperatorNumeric = numeric;
934    }
935
936    /**
937     * In CDMA, mOperatorAlphaLong can be set from the ERI text.
938     * This is done from the GsmCdmaPhone and not from the ServiceStateTracker.
939     *
940     * @hide
941     */
942    public void setOperatorAlphaLong(String longName) {
943        mVoiceOperatorAlphaLong = longName;
944        mDataOperatorAlphaLong = longName;
945    }
946
947    /** @hide */
948    public void setVoiceOperatorAlphaLong(String longName) {
949        mVoiceOperatorAlphaLong = longName;
950    }
951
952    /** @hide */
953    public void setDataOperatorAlphaLong(String longName) {
954        mDataOperatorAlphaLong = longName;
955    }
956
957    public void setIsManualSelection(boolean isManual) {
958        mIsManualNetworkSelection = isManual;
959    }
960
961    /**
962     * Test whether two objects hold the same data values or both are null.
963     *
964     * @param a first obj
965     * @param b second obj
966     * @return true if two objects equal or both are null
967     */
968    private static boolean equalsHandlesNulls (Object a, Object b) {
969        return (a == null) ? (b == null) : a.equals (b);
970    }
971
972    /**
973     * Set ServiceState based on intent notifier map.
974     *
975     * @param m intent notifier map
976     * @hide
977     */
978    private void setFromNotifierBundle(Bundle m) {
979        mVoiceRegState = m.getInt("voiceRegState");
980        mDataRegState = m.getInt("dataRegState");
981        mVoiceRoamingType = m.getInt("voiceRoamingType");
982        mDataRoamingType = m.getInt("dataRoamingType");
983        mVoiceOperatorAlphaLong = m.getString("operator-alpha-long");
984        mVoiceOperatorAlphaShort = m.getString("operator-alpha-short");
985        mVoiceOperatorNumeric = m.getString("operator-numeric");
986        mDataOperatorAlphaLong = m.getString("data-operator-alpha-long");
987        mDataOperatorAlphaShort = m.getString("data-operator-alpha-short");
988        mDataOperatorNumeric = m.getString("data-operator-numeric");
989        mIsManualNetworkSelection = m.getBoolean("manual");
990        mRilVoiceRadioTechnology = m.getInt("radioTechnology");
991        mRilDataRadioTechnology = m.getInt("dataRadioTechnology");
992        mCssIndicator = m.getBoolean("cssIndicator");
993        mNetworkId = m.getInt("networkId");
994        mSystemId = m.getInt("systemId");
995        mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
996        mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
997        mIsEmergencyOnly = m.getBoolean("emergencyOnly");
998        mIsDataRoamingFromRegistration = m.getBoolean("isDataRoamingFromRegistration");
999        mIsUsingCarrierAggregation = m.getBoolean("isUsingCarrierAggregation");
1000    }
1001
1002    /**
1003     * Set intent notifier Bundle based on service state.
1004     *
1005     * @param m intent notifier Bundle
1006     * @hide
1007     */
1008    public void fillInNotifierBundle(Bundle m) {
1009        m.putInt("voiceRegState", mVoiceRegState);
1010        m.putInt("dataRegState", mDataRegState);
1011        m.putInt("voiceRoamingType", mVoiceRoamingType);
1012        m.putInt("dataRoamingType", mDataRoamingType);
1013        m.putString("operator-alpha-long", mVoiceOperatorAlphaLong);
1014        m.putString("operator-alpha-short", mVoiceOperatorAlphaShort);
1015        m.putString("operator-numeric", mVoiceOperatorNumeric);
1016        m.putString("data-operator-alpha-long", mDataOperatorAlphaLong);
1017        m.putString("data-operator-alpha-short", mDataOperatorAlphaShort);
1018        m.putString("data-operator-numeric", mDataOperatorNumeric);
1019        m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection));
1020        m.putInt("radioTechnology", mRilVoiceRadioTechnology);
1021        m.putInt("dataRadioTechnology", mRilDataRadioTechnology);
1022        m.putBoolean("cssIndicator", mCssIndicator);
1023        m.putInt("networkId", mNetworkId);
1024        m.putInt("systemId", mSystemId);
1025        m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
1026        m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
1027        m.putBoolean("emergencyOnly", Boolean.valueOf(mIsEmergencyOnly));
1028        m.putBoolean("isDataRoamingFromRegistration", Boolean.valueOf(mIsDataRoamingFromRegistration));
1029        m.putBoolean("isUsingCarrierAggregation", Boolean.valueOf(mIsUsingCarrierAggregation));
1030    }
1031
1032    /** @hide */
1033    public void setRilVoiceRadioTechnology(int rt) {
1034        if (rt == RIL_RADIO_TECHNOLOGY_LTE_CA) {
1035            rt = RIL_RADIO_TECHNOLOGY_LTE;
1036        }
1037
1038        this.mRilVoiceRadioTechnology = rt;
1039    }
1040
1041    /** @hide */
1042    public void setRilDataRadioTechnology(int rt) {
1043        if (rt == RIL_RADIO_TECHNOLOGY_LTE_CA) {
1044            rt = RIL_RADIO_TECHNOLOGY_LTE;
1045            this.mIsUsingCarrierAggregation = true;
1046        } else {
1047            this.mIsUsingCarrierAggregation = false;
1048        }
1049        this.mRilDataRadioTechnology = rt;
1050        if (VDBG) Rlog.d(LOG_TAG, "[ServiceState] setRilDataRadioTechnology=" +
1051                mRilDataRadioTechnology);
1052    }
1053
1054    /** @hide */
1055    public boolean isUsingCarrierAggregation() {
1056        return mIsUsingCarrierAggregation;
1057    }
1058
1059    /** @hide */
1060    public void setIsUsingCarrierAggregation(boolean ca) {
1061        mIsUsingCarrierAggregation = ca;
1062    }
1063
1064    /** @hide */
1065    public void setCssIndicator(int css) {
1066        this.mCssIndicator = (css != 0);
1067    }
1068
1069    /** @hide */
1070    public void setSystemAndNetworkId(int systemId, int networkId) {
1071        this.mSystemId = systemId;
1072        this.mNetworkId = networkId;
1073    }
1074
1075    /** @hide */
1076    public int getRilVoiceRadioTechnology() {
1077        return this.mRilVoiceRadioTechnology;
1078    }
1079    /** @hide */
1080    public int getRilDataRadioTechnology() {
1081        return this.mRilDataRadioTechnology;
1082    }
1083    /**
1084     * @hide
1085     * @Deprecated to be removed Q3 2013 use {@link #getRilDataRadioTechnology} or
1086     * {@link #getRilVoiceRadioTechnology}
1087     */
1088    public int getRadioTechnology() {
1089        Rlog.e(LOG_TAG, "ServiceState.getRadioTechnology() DEPRECATED will be removed *******");
1090        return getRilDataRadioTechnology();
1091    }
1092
1093    private int rilRadioTechnologyToNetworkType(int rt) {
1094        switch(rt) {
1095        case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS:
1096            return TelephonyManager.NETWORK_TYPE_GPRS;
1097        case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE:
1098            return TelephonyManager.NETWORK_TYPE_EDGE;
1099        case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS:
1100            return TelephonyManager.NETWORK_TYPE_UMTS;
1101        case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA:
1102            return TelephonyManager.NETWORK_TYPE_HSDPA;
1103        case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA:
1104            return TelephonyManager.NETWORK_TYPE_HSUPA;
1105        case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA:
1106            return TelephonyManager.NETWORK_TYPE_HSPA;
1107        case ServiceState.RIL_RADIO_TECHNOLOGY_IS95A:
1108        case ServiceState.RIL_RADIO_TECHNOLOGY_IS95B:
1109            return TelephonyManager.NETWORK_TYPE_CDMA;
1110        case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT:
1111            return TelephonyManager.NETWORK_TYPE_1xRTT;
1112        case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0:
1113            return TelephonyManager.NETWORK_TYPE_EVDO_0;
1114        case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A:
1115            return TelephonyManager.NETWORK_TYPE_EVDO_A;
1116        case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B:
1117            return TelephonyManager.NETWORK_TYPE_EVDO_B;
1118        case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD:
1119            return TelephonyManager.NETWORK_TYPE_EHRPD;
1120        case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
1121            return TelephonyManager.NETWORK_TYPE_LTE;
1122        case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
1123            return TelephonyManager.NETWORK_TYPE_HSPAP;
1124        case ServiceState.RIL_RADIO_TECHNOLOGY_GSM:
1125            return TelephonyManager.NETWORK_TYPE_GSM;
1126        case ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA:
1127            return TelephonyManager.NETWORK_TYPE_TD_SCDMA;
1128        case ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN:
1129            return TelephonyManager.NETWORK_TYPE_IWLAN;
1130        case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA:
1131            return TelephonyManager.NETWORK_TYPE_LTE_CA;
1132        default:
1133            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
1134        }
1135    }
1136
1137    /**
1138     * @Deprecated to be removed Q3 2013 use {@link #getVoiceNetworkType}
1139     * @hide
1140     */
1141    public int getNetworkType() {
1142        Rlog.e(LOG_TAG, "ServiceState.getNetworkType() DEPRECATED will be removed *******");
1143        return rilRadioTechnologyToNetworkType(mRilVoiceRadioTechnology);
1144    }
1145
1146    /** @hide */
1147    public int getDataNetworkType() {
1148        return rilRadioTechnologyToNetworkType(mRilDataRadioTechnology);
1149    }
1150
1151    /** @hide */
1152    public int getVoiceNetworkType() {
1153        return rilRadioTechnologyToNetworkType(mRilVoiceRadioTechnology);
1154    }
1155
1156    /** @hide */
1157    public int getCssIndicator() {
1158        return this.mCssIndicator ? 1 : 0;
1159    }
1160
1161    /** @hide */
1162    public int getNetworkId() {
1163        return this.mNetworkId;
1164    }
1165
1166    /** @hide */
1167    public int getSystemId() {
1168        return this.mSystemId;
1169    }
1170
1171    /** @hide */
1172    public static boolean isGsm(int radioTechnology) {
1173        return radioTechnology == RIL_RADIO_TECHNOLOGY_GPRS
1174                || radioTechnology == RIL_RADIO_TECHNOLOGY_EDGE
1175                || radioTechnology == RIL_RADIO_TECHNOLOGY_UMTS
1176                || radioTechnology == RIL_RADIO_TECHNOLOGY_HSDPA
1177                || radioTechnology == RIL_RADIO_TECHNOLOGY_HSUPA
1178                || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPA
1179                || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE
1180                || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPAP
1181                || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM
1182                || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
1183                || radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
1184                || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
1185
1186    }
1187
1188    /** @hide */
1189    public static boolean isCdma(int radioTechnology) {
1190        return radioTechnology == RIL_RADIO_TECHNOLOGY_IS95A
1191                || radioTechnology == RIL_RADIO_TECHNOLOGY_IS95B
1192                || radioTechnology == RIL_RADIO_TECHNOLOGY_1xRTT
1193                || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_0
1194                || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_A
1195                || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_B
1196                || radioTechnology == RIL_RADIO_TECHNOLOGY_EHRPD;
1197    }
1198
1199    /** @hide */
1200    public static boolean isLte(int radioTechnology) {
1201        return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE ||
1202                radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
1203    }
1204
1205    /** @hide */
1206    public static boolean bearerBitmapHasCdma(int radioTechnologyBitmap) {
1207        return (RIL_RADIO_CDMA_TECHNOLOGY_BITMASK & radioTechnologyBitmap) != 0;
1208    }
1209
1210    /** @hide */
1211    public static boolean bitmaskHasTech(int bearerBitmask, int radioTech) {
1212        if (bearerBitmask == 0) {
1213            return true;
1214        } else if (radioTech >= 1) {
1215            return ((bearerBitmask & (1 << (radioTech - 1))) != 0);
1216        }
1217        return false;
1218    }
1219
1220    /** @hide */
1221    public static int getBitmaskForTech(int radioTech) {
1222        if (radioTech >= 1) {
1223            return (1 << (radioTech - 1));
1224        }
1225        return 0;
1226    }
1227
1228    /** @hide */
1229    public static int getBitmaskFromString(String bearerList) {
1230        String[] bearers = bearerList.split("\\|");
1231        int bearerBitmask = 0;
1232        for (String bearer : bearers) {
1233            int bearerInt = 0;
1234            try {
1235                bearerInt = Integer.parseInt(bearer.trim());
1236            } catch (NumberFormatException nfe) {
1237                return 0;
1238            }
1239
1240            if (bearerInt == 0) {
1241                return 0;
1242            }
1243
1244            bearerBitmask |= getBitmaskForTech(bearerInt);
1245        }
1246        return bearerBitmask;
1247    }
1248
1249    /**
1250     * Returns a merged ServiceState consisting of the base SS with voice settings from the
1251     * voice SS. The voice SS is only used if it is IN_SERVICE (otherwise the base SS is returned).
1252     * @hide
1253     * */
1254    public static ServiceState mergeServiceStates(ServiceState baseSs, ServiceState voiceSs) {
1255        if (voiceSs.mVoiceRegState != STATE_IN_SERVICE) {
1256            return baseSs;
1257        }
1258
1259        ServiceState newSs = new ServiceState(baseSs);
1260
1261        // voice overrides
1262        newSs.mVoiceRegState = voiceSs.mVoiceRegState;
1263        newSs.mIsEmergencyOnly = false; // only get here if voice is IN_SERVICE
1264
1265        return newSs;
1266    }
1267}
1268