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