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