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 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