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 com.android.settings; 18 19 import android.app.Activity; 20 import android.app.QueuedWork; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.content.res.Resources; 26 import android.net.TrafficStats; 27 import android.net.Uri; 28 import android.os.AsyncResult; 29 import android.os.Bundle; 30 import android.os.Handler; 31 import android.os.Message; 32 import android.os.SystemProperties; 33 import android.telephony.CellInfo; 34 import android.telephony.CellLocation; 35 import android.telephony.DataConnectionRealTimeInfo; 36 import android.telephony.PhoneStateListener; 37 import android.telephony.ServiceState; 38 import android.telephony.TelephonyManager; 39 import android.telephony.NeighboringCellInfo; 40 import android.telephony.cdma.CdmaCellLocation; 41 import android.telephony.gsm.GsmCellLocation; 42 import android.util.Log; 43 import android.view.Menu; 44 import android.view.MenuItem; 45 import android.view.View; 46 import android.view.View.OnClickListener; 47 import android.widget.AdapterView; 48 import android.widget.ArrayAdapter; 49 import android.widget.Button; 50 import android.widget.Spinner; 51 import android.widget.TextView; 52 import android.widget.EditText; 53 54 import com.android.internal.telephony.Phone; 55 import com.android.internal.telephony.PhoneConstants; 56 import com.android.internal.telephony.PhoneFactory; 57 import com.android.internal.telephony.PhoneStateIntentReceiver; 58 import com.android.internal.telephony.TelephonyProperties; 59 import com.android.ims.ImsConfig; 60 import com.android.ims.ImsException; 61 import com.android.ims.ImsManager; 62 import org.apache.http.HttpResponse; 63 import org.apache.http.client.HttpClient; 64 import org.apache.http.client.methods.HttpGet; 65 import org.apache.http.impl.client.DefaultHttpClient; 66 67 import java.io.IOException; 68 import java.net.UnknownHostException; 69 import java.util.ArrayList; 70 import java.util.List; 71 72 public class RadioInfo extends Activity { 73 private final String TAG = "phone"; 74 75 private static final int EVENT_PHONE_STATE_CHANGED = 100; 76 private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200; 77 private static final int EVENT_SERVICE_STATE_CHANGED = 300; 78 private static final int EVENT_CFI_CHANGED = 302; 79 80 private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000; 81 private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001; 82 private static final int EVENT_QUERY_NEIGHBORING_CIDS_DONE = 1002; 83 private static final int EVENT_QUERY_SMSC_DONE = 1005; 84 private static final int EVENT_UPDATE_SMSC_DONE = 1006; 85 86 private static final int MENU_ITEM_SELECT_BAND = 0; 87 private static final int MENU_ITEM_VIEW_ADN = 1; 88 private static final int MENU_ITEM_VIEW_FDN = 2; 89 private static final int MENU_ITEM_VIEW_SDN = 3; 90 private static final int MENU_ITEM_GET_PDP_LIST = 4; 91 private static final int MENU_ITEM_TOGGLE_DATA = 5; 92 93 static final String ENABLE_DATA_STR = "Enable data connection"; 94 static final String DISABLE_DATA_STR = "Disable data connection"; 95 96 private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA 97 private TextView number; 98 private TextView callState; 99 private TextView operatorName; 100 private TextView roamingState; 101 private TextView gsmState; 102 private TextView gprsState; 103 private TextView network; 104 private TextView dBm; 105 private TextView mMwi; 106 private TextView mCfi; 107 private TextView mLocation; 108 private TextView mNeighboringCids; 109 private TextView mCellInfo; 110 private TextView mDcRtInfoTv; 111 private TextView resets; 112 private TextView attempts; 113 private TextView successes; 114 private TextView disconnects; 115 private TextView sentSinceReceived; 116 private TextView sent; 117 private TextView received; 118 private TextView mPingIpAddr; 119 private TextView mPingHostname; 120 private TextView mHttpClientTest; 121 private TextView dnsCheckState; 122 private EditText smsc; 123 private Button radioPowerButton; 124 private Button cellInfoListRateButton; 125 private Button dnsCheckToggleButton; 126 private Button pingTestButton; 127 private Button updateSmscButton; 128 private Button refreshSmscButton; 129 private Button oemInfoButton; 130 private Spinner preferredNetworkType; 131 132 private TelephonyManager mTelephonyManager; 133 private Phone phone = null; 134 private PhoneStateIntentReceiver mPhoneStateReceiver; 135 136 private String mPingIpAddrResult; 137 private String mPingHostnameResult; 138 private String mHttpClientTestResult; 139 private boolean mMwiValue = false; 140 private boolean mCfiValue = false; 141 private List<CellInfo> mCellInfoValue; 142 143 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 144 @Override 145 public void onDataConnectionStateChanged(int state) { 146 updateDataState(); 147 updateDataStats(); 148 updatePdpList(); 149 updateNetworkType(); 150 } 151 152 @Override 153 public void onDataActivity(int direction) { 154 updateDataStats2(); 155 } 156 157 @Override 158 public void onCellLocationChanged(CellLocation location) { 159 updateLocation(location); 160 } 161 162 @Override 163 public void onMessageWaitingIndicatorChanged(boolean mwi) { 164 mMwiValue = mwi; 165 updateMessageWaiting(); 166 } 167 168 @Override 169 public void onCallForwardingIndicatorChanged(boolean cfi) { 170 mCfiValue = cfi; 171 updateCallRedirect(); 172 } 173 174 @Override 175 public void onCellInfoChanged(List<CellInfo> arrayCi) { 176 log("onCellInfoChanged: arrayCi=" + arrayCi); 177 updateCellInfoTv(arrayCi); 178 } 179 180 @Override 181 public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) { 182 log("onDataConnectionRealTimeInfoChanged: dcRtInfo=" + dcRtInfo); 183 updateDcRtInfoTv(dcRtInfo); 184 } 185 }; 186 187 private Handler mHandler = new Handler() { 188 public void handleMessage(Message msg) { 189 AsyncResult ar; 190 switch (msg.what) { 191 case EVENT_PHONE_STATE_CHANGED: 192 updatePhoneState(); 193 break; 194 195 case EVENT_SIGNAL_STRENGTH_CHANGED: 196 updateSignalStrength(); 197 break; 198 199 case EVENT_SERVICE_STATE_CHANGED: 200 updateServiceState(); 201 updatePowerState(); 202 updateImsVoLteProvisionedState(); 203 break; 204 205 case EVENT_QUERY_PREFERRED_TYPE_DONE: 206 ar= (AsyncResult) msg.obj; 207 if (ar.exception == null) { 208 int type = ((int[])ar.result)[0]; 209 if (type >= mPreferredNetworkLabels.length) { 210 log("EVENT_QUERY_PREFERRED_TYPE_DONE: unknown " + 211 "type=" + type); 212 type = mPreferredNetworkLabels.length - 1; 213 } 214 preferredNetworkType.setSelection(type, true); 215 } else { 216 preferredNetworkType.setSelection(mPreferredNetworkLabels.length - 1, true); 217 } 218 break; 219 case EVENT_SET_PREFERRED_TYPE_DONE: 220 ar= (AsyncResult) msg.obj; 221 if (ar.exception != null) { 222 phone.getPreferredNetworkType( 223 obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE)); 224 } 225 break; 226 case EVENT_QUERY_NEIGHBORING_CIDS_DONE: 227 ar= (AsyncResult) msg.obj; 228 if (ar.exception == null) { 229 updateNeighboringCids((ArrayList<NeighboringCellInfo>)ar.result); 230 } else { 231 mNeighboringCids.setText("unknown"); 232 } 233 break; 234 case EVENT_QUERY_SMSC_DONE: 235 ar= (AsyncResult) msg.obj; 236 if (ar.exception != null) { 237 smsc.setText("refresh error"); 238 } else { 239 smsc.setText((String)ar.result); 240 } 241 break; 242 case EVENT_UPDATE_SMSC_DONE: 243 updateSmscButton.setEnabled(true); 244 ar= (AsyncResult) msg.obj; 245 if (ar.exception != null) { 246 smsc.setText("update error"); 247 } 248 break; 249 default: 250 break; 251 252 } 253 } 254 }; 255 256 @Override 257 public void onCreate(Bundle icicle) { 258 super.onCreate(icicle); 259 260 setContentView(R.layout.radio_info); 261 262 mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); 263 phone = PhoneFactory.getDefaultPhone(); 264 265 mDeviceId= (TextView) findViewById(R.id.imei); 266 number = (TextView) findViewById(R.id.number); 267 callState = (TextView) findViewById(R.id.call); 268 operatorName = (TextView) findViewById(R.id.operator); 269 roamingState = (TextView) findViewById(R.id.roaming); 270 gsmState = (TextView) findViewById(R.id.gsm); 271 gprsState = (TextView) findViewById(R.id.gprs); 272 network = (TextView) findViewById(R.id.network); 273 dBm = (TextView) findViewById(R.id.dbm); 274 mMwi = (TextView) findViewById(R.id.mwi); 275 mCfi = (TextView) findViewById(R.id.cfi); 276 mLocation = (TextView) findViewById(R.id.location); 277 mNeighboringCids = (TextView) findViewById(R.id.neighboring); 278 mCellInfo = (TextView) findViewById(R.id.cellinfo); 279 mDcRtInfoTv = (TextView) findViewById(R.id.dcrtinfo); 280 281 resets = (TextView) findViewById(R.id.resets); 282 attempts = (TextView) findViewById(R.id.attempts); 283 successes = (TextView) findViewById(R.id.successes); 284 disconnects = (TextView) findViewById(R.id.disconnects); 285 sentSinceReceived = (TextView) findViewById(R.id.sentSinceReceived); 286 sent = (TextView) findViewById(R.id.sent); 287 received = (TextView) findViewById(R.id.received); 288 smsc = (EditText) findViewById(R.id.smsc); 289 dnsCheckState = (TextView) findViewById(R.id.dnsCheckState); 290 291 mPingIpAddr = (TextView) findViewById(R.id.pingIpAddr); 292 mPingHostname = (TextView) findViewById(R.id.pingHostname); 293 mHttpClientTest = (TextView) findViewById(R.id.httpClientTest); 294 295 preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType); 296 ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, 297 android.R.layout.simple_spinner_item, mPreferredNetworkLabels); 298 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 299 preferredNetworkType.setAdapter(adapter); 300 preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler); 301 302 radioPowerButton = (Button) findViewById(R.id.radio_power); 303 radioPowerButton.setOnClickListener(mPowerButtonHandler); 304 305 cellInfoListRateButton = (Button) findViewById(R.id.cell_info_list_rate); 306 cellInfoListRateButton.setOnClickListener(mCellInfoListRateHandler); 307 308 imsRegRequiredButton = (Button) findViewById(R.id.ims_reg_required); 309 imsRegRequiredButton.setOnClickListener(mImsRegRequiredHandler); 310 311 imsVoLteProvisionedButton = (Button) findViewById(R.id.volte_provisioned_flag); 312 imsVoLteProvisionedButton.setOnClickListener(mImsVoLteProvisionedHandler); 313 314 smsOverImsButton = (Button) findViewById(R.id.sms_over_ims); 315 smsOverImsButton.setOnClickListener(mSmsOverImsHandler); 316 317 lteRamDumpButton = (Button) findViewById(R.id.lte_ram_dump); 318 lteRamDumpButton.setOnClickListener(mLteRamDumpHandler); 319 320 pingTestButton = (Button) findViewById(R.id.ping_test); 321 pingTestButton.setOnClickListener(mPingButtonHandler); 322 updateSmscButton = (Button) findViewById(R.id.update_smsc); 323 updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler); 324 refreshSmscButton = (Button) findViewById(R.id.refresh_smsc); 325 refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler); 326 dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle); 327 dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler); 328 329 oemInfoButton = (Button) findViewById(R.id.oem_info); 330 oemInfoButton.setOnClickListener(mOemInfoButtonHandler); 331 PackageManager pm = getPackageManager(); 332 Intent oemInfoIntent = new Intent("com.android.settings.OEM_RADIO_INFO"); 333 List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0); 334 if (oemInfoIntentList.size() == 0) { 335 oemInfoButton.setEnabled(false); 336 } 337 338 mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler); 339 mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED); 340 mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED); 341 mPhoneStateReceiver.notifyPhoneCallState(EVENT_PHONE_STATE_CHANGED); 342 343 phone.getPreferredNetworkType( 344 mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE)); 345 phone.getNeighboringCids( 346 mHandler.obtainMessage(EVENT_QUERY_NEIGHBORING_CIDS_DONE)); 347 348 CellLocation.requestLocationUpdate(); 349 350 // Get current cell info 351 mCellInfoValue = mTelephonyManager.getAllCellInfo(); 352 log("onCreate: mCellInfoValue=" + mCellInfoValue); 353 } 354 355 @Override 356 protected void onResume() { 357 super.onResume(); 358 359 updatePhoneState(); 360 updateSignalStrength(); 361 updateMessageWaiting(); 362 updateCallRedirect(); 363 updateServiceState(); 364 updateLocation(mTelephonyManager.getCellLocation()); 365 updateDataState(); 366 updateDataStats(); 367 updateDataStats2(); 368 updatePowerState(); 369 updateCellInfoListRate(); 370 updateImsRegRequiredState(); 371 updateImsVoLteProvisionedState(); 372 updateSmsOverImsState(); 373 updateLteRamDumpState(); 374 updateProperties(); 375 updateDnsCheckState(); 376 377 log("onResume: register phone & data intents"); 378 379 mPhoneStateReceiver.registerIntent(); 380 mTelephonyManager.listen(mPhoneStateListener, 381 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE 382 | PhoneStateListener.LISTEN_DATA_ACTIVITY 383 | PhoneStateListener.LISTEN_CELL_LOCATION 384 | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR 385 | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR 386 | PhoneStateListener.LISTEN_CELL_INFO 387 | PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO); 388 } 389 390 @Override 391 public void onPause() { 392 super.onPause(); 393 394 log("onPause: unregister phone & data intents"); 395 396 mPhoneStateReceiver.unregisterIntent(); 397 mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); 398 } 399 400 @Override 401 public boolean onCreateOptionsMenu(Menu menu) { 402 menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label) 403 .setOnMenuItemClickListener(mSelectBandCallback) 404 .setAlphabeticShortcut('b'); 405 menu.add(1, MENU_ITEM_VIEW_ADN, 0, 406 R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback); 407 menu.add(1, MENU_ITEM_VIEW_FDN, 0, 408 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback); 409 menu.add(1, MENU_ITEM_VIEW_SDN, 0, 410 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback); 411 menu.add(1, MENU_ITEM_GET_PDP_LIST, 412 0, R.string.radioInfo_menu_getPDP).setOnMenuItemClickListener(mGetPdpList); 413 menu.add(1, MENU_ITEM_TOGGLE_DATA, 414 0, DISABLE_DATA_STR).setOnMenuItemClickListener(mToggleData); 415 return true; 416 } 417 418 @Override 419 public boolean onPrepareOptionsMenu(Menu menu) { 420 // Get the TOGGLE DATA menu item in the right state. 421 MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA); 422 int state = mTelephonyManager.getDataState(); 423 boolean visible = true; 424 425 switch (state) { 426 case TelephonyManager.DATA_CONNECTED: 427 case TelephonyManager.DATA_SUSPENDED: 428 item.setTitle(DISABLE_DATA_STR); 429 break; 430 case TelephonyManager.DATA_DISCONNECTED: 431 item.setTitle(ENABLE_DATA_STR); 432 break; 433 default: 434 visible = false; 435 break; 436 } 437 item.setVisible(visible); 438 return true; 439 } 440 441 private boolean isRadioOn() { 442 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF; 443 } 444 445 private void updatePowerState() { 446 String buttonText = isRadioOn() ? 447 getString(R.string.turn_off_radio) : 448 getString(R.string.turn_on_radio); 449 radioPowerButton.setText(buttonText); 450 } 451 452 private void updateCellInfoListRate() { 453 cellInfoListRateButton.setText("CellInfoListRate " + mCellInfoListRateHandler.getRate()); 454 updateCellInfoTv(mTelephonyManager.getAllCellInfo()); 455 } 456 457 private void updateDnsCheckState() { 458 dnsCheckState.setText(phone.isDnsCheckDisabled() ? 459 "0.0.0.0 allowed" :"0.0.0.0 not allowed"); 460 } 461 462 private final void 463 updateSignalStrength() { 464 // TODO PhoneStateIntentReceiver is deprecated and PhoneStateListener 465 // should probably used instead. 466 int state = mPhoneStateReceiver.getServiceState().getState(); 467 Resources r = getResources(); 468 469 if ((ServiceState.STATE_OUT_OF_SERVICE == state) || 470 (ServiceState.STATE_POWER_OFF == state)) { 471 dBm.setText("0"); 472 } 473 474 int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm(); 475 476 if (-1 == signalDbm) signalDbm = 0; 477 478 int signalAsu = mPhoneStateReceiver.getSignalStrengthLevelAsu(); 479 480 if (-1 == signalAsu) signalAsu = 0; 481 482 dBm.setText(String.valueOf(signalDbm) + " " 483 + r.getString(R.string.radioInfo_display_dbm) + " " 484 + String.valueOf(signalAsu) + " " 485 + r.getString(R.string.radioInfo_display_asu)); 486 } 487 488 private final void updateLocation(CellLocation location) { 489 Resources r = getResources(); 490 if (location instanceof GsmCellLocation) { 491 GsmCellLocation loc = (GsmCellLocation)location; 492 int lac = loc.getLac(); 493 int cid = loc.getCid(); 494 mLocation.setText(r.getString(R.string.radioInfo_lac) + " = " 495 + ((lac == -1) ? "unknown" : Integer.toHexString(lac)) 496 + " " 497 + r.getString(R.string.radioInfo_cid) + " = " 498 + ((cid == -1) ? "unknown" : Integer.toHexString(cid))); 499 } else if (location instanceof CdmaCellLocation) { 500 CdmaCellLocation loc = (CdmaCellLocation)location; 501 int bid = loc.getBaseStationId(); 502 int sid = loc.getSystemId(); 503 int nid = loc.getNetworkId(); 504 int lat = loc.getBaseStationLatitude(); 505 int lon = loc.getBaseStationLongitude(); 506 mLocation.setText("BID = " 507 + ((bid == -1) ? "unknown" : Integer.toHexString(bid)) 508 + " " 509 + "SID = " 510 + ((sid == -1) ? "unknown" : Integer.toHexString(sid)) 511 + " " 512 + "NID = " 513 + ((nid == -1) ? "unknown" : Integer.toHexString(nid)) 514 + "\n" 515 + "LAT = " 516 + ((lat == -1) ? "unknown" : Integer.toHexString(lat)) 517 + " " 518 + "LONG = " 519 + ((lon == -1) ? "unknown" : Integer.toHexString(lon))); 520 } else { 521 mLocation.setText("unknown"); 522 } 523 524 525 } 526 527 private final void updateNeighboringCids(ArrayList<NeighboringCellInfo> cids) { 528 StringBuilder sb = new StringBuilder(); 529 530 if (cids != null) { 531 if ( cids.isEmpty() ) { 532 sb.append("no neighboring cells"); 533 } else { 534 for (NeighboringCellInfo cell : cids) { 535 sb.append(cell.toString()).append(" "); 536 } 537 } 538 } else { 539 sb.append("unknown"); 540 } 541 mNeighboringCids.setText(sb.toString()); 542 } 543 544 private final void updateCellInfoTv(List<CellInfo> arrayCi) { 545 mCellInfoValue = arrayCi; 546 StringBuilder value = new StringBuilder(); 547 if (mCellInfoValue != null) { 548 int index = 0; 549 for (CellInfo ci : mCellInfoValue) { 550 value.append('['); 551 value.append(index); 552 value.append("]="); 553 value.append(ci.toString()); 554 if (++index < mCellInfoValue.size()) { 555 value.append("\n"); 556 } 557 } 558 } 559 mCellInfo.setText(value.toString()); 560 } 561 562 private final void updateDcRtInfoTv(DataConnectionRealTimeInfo dcRtInfo) { 563 mDcRtInfoTv.setText(dcRtInfo.toString()); 564 } 565 566 private final void 567 updateMessageWaiting() { 568 mMwi.setText(String.valueOf(mMwiValue)); 569 } 570 571 private final void 572 updateCallRedirect() { 573 mCfi.setText(String.valueOf(mCfiValue)); 574 } 575 576 577 private final void 578 updateServiceState() { 579 ServiceState serviceState = mPhoneStateReceiver.getServiceState(); 580 int state = serviceState.getState(); 581 Resources r = getResources(); 582 String display = r.getString(R.string.radioInfo_unknown); 583 584 switch (state) { 585 case ServiceState.STATE_IN_SERVICE: 586 display = r.getString(R.string.radioInfo_service_in); 587 break; 588 case ServiceState.STATE_OUT_OF_SERVICE: 589 case ServiceState.STATE_EMERGENCY_ONLY: 590 display = r.getString(R.string.radioInfo_service_emergency); 591 break; 592 case ServiceState.STATE_POWER_OFF: 593 display = r.getString(R.string.radioInfo_service_off); 594 break; 595 } 596 597 gsmState.setText(display); 598 599 if (serviceState.getRoaming()) { 600 roamingState.setText(R.string.radioInfo_roaming_in); 601 } else { 602 roamingState.setText(R.string.radioInfo_roaming_not); 603 } 604 605 operatorName.setText(serviceState.getOperatorAlphaLong()); 606 } 607 608 private final void 609 updatePhoneState() { 610 PhoneConstants.State state = mPhoneStateReceiver.getPhoneState(); 611 Resources r = getResources(); 612 String display = r.getString(R.string.radioInfo_unknown); 613 614 switch (state) { 615 case IDLE: 616 display = r.getString(R.string.radioInfo_phone_idle); 617 break; 618 case RINGING: 619 display = r.getString(R.string.radioInfo_phone_ringing); 620 break; 621 case OFFHOOK: 622 display = r.getString(R.string.radioInfo_phone_offhook); 623 break; 624 } 625 626 callState.setText(display); 627 } 628 629 private final void 630 updateDataState() { 631 int state = mTelephonyManager.getDataState(); 632 Resources r = getResources(); 633 String display = r.getString(R.string.radioInfo_unknown); 634 635 switch (state) { 636 case TelephonyManager.DATA_CONNECTED: 637 display = r.getString(R.string.radioInfo_data_connected); 638 break; 639 case TelephonyManager.DATA_CONNECTING: 640 display = r.getString(R.string.radioInfo_data_connecting); 641 break; 642 case TelephonyManager.DATA_DISCONNECTED: 643 display = r.getString(R.string.radioInfo_data_disconnected); 644 break; 645 case TelephonyManager.DATA_SUSPENDED: 646 display = r.getString(R.string.radioInfo_data_suspended); 647 break; 648 } 649 650 gprsState.setText(display); 651 } 652 653 private final void updateNetworkType() { 654 Resources r = getResources(); 655 String display = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, 656 r.getString(R.string.radioInfo_unknown)); 657 658 network.setText(display); 659 } 660 661 private final void 662 updateProperties() { 663 String s; 664 Resources r = getResources(); 665 666 s = phone.getDeviceId(); 667 if (s == null) s = r.getString(R.string.radioInfo_unknown); 668 mDeviceId.setText(s); 669 670 671 s = phone.getLine1Number(); 672 if (s == null) s = r.getString(R.string.radioInfo_unknown); 673 number.setText(s); 674 } 675 676 private final void updateDataStats() { 677 String s; 678 679 s = SystemProperties.get("net.gsm.radio-reset", "0"); 680 resets.setText(s); 681 682 s = SystemProperties.get("net.gsm.attempt-gprs", "0"); 683 attempts.setText(s); 684 685 s = SystemProperties.get("net.gsm.succeed-gprs", "0"); 686 successes.setText(s); 687 688 //s = SystemProperties.get("net.gsm.disconnect", "0"); 689 //disconnects.setText(s); 690 691 s = SystemProperties.get("net.ppp.reset-by-timeout", "0"); 692 sentSinceReceived.setText(s); 693 } 694 695 private final void updateDataStats2() { 696 Resources r = getResources(); 697 698 long txPackets = TrafficStats.getMobileTxPackets(); 699 long rxPackets = TrafficStats.getMobileRxPackets(); 700 long txBytes = TrafficStats.getMobileTxBytes(); 701 long rxBytes = TrafficStats.getMobileRxBytes(); 702 703 String packets = r.getString(R.string.radioInfo_display_packets); 704 String bytes = r.getString(R.string.radioInfo_display_bytes); 705 706 sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes); 707 received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes); 708 } 709 710 /** 711 * Ping a IP address. 712 */ 713 private final void pingIpAddr() { 714 try { 715 // This is hardcoded IP addr. This is for testing purposes. 716 // We would need to get rid of this before release. 717 String ipAddress = "74.125.47.104"; 718 Process p = Runtime.getRuntime().exec("ping -c 1 " + ipAddress); 719 int status = p.waitFor(); 720 if (status == 0) { 721 mPingIpAddrResult = "Pass"; 722 } else { 723 mPingIpAddrResult = "Fail: IP addr not reachable"; 724 } 725 } catch (IOException e) { 726 mPingIpAddrResult = "Fail: IOException"; 727 } catch (InterruptedException e) { 728 mPingIpAddrResult = "Fail: InterruptedException"; 729 } 730 } 731 732 /** 733 * Ping a host name 734 */ 735 private final void pingHostname() { 736 try { 737 Process p = Runtime.getRuntime().exec("ping -c 1 www.google.com"); 738 int status = p.waitFor(); 739 if (status == 0) { 740 mPingHostnameResult = "Pass"; 741 } else { 742 mPingHostnameResult = "Fail: Host unreachable"; 743 } 744 } catch (UnknownHostException e) { 745 mPingHostnameResult = "Fail: Unknown Host"; 746 } catch (IOException e) { 747 mPingHostnameResult= "Fail: IOException"; 748 } catch (InterruptedException e) { 749 mPingHostnameResult = "Fail: InterruptedException"; 750 } 751 } 752 753 /** 754 * This function checks for basic functionality of HTTP Client. 755 */ 756 private void httpClientTest() { 757 HttpClient client = new DefaultHttpClient(); 758 try { 759 HttpGet request = new HttpGet("http://www.google.com"); 760 HttpResponse response = client.execute(request); 761 if (response.getStatusLine().getStatusCode() == 200) { 762 mHttpClientTestResult = "Pass"; 763 } else { 764 mHttpClientTestResult = "Fail: Code: " + String.valueOf(response); 765 } 766 request.abort(); 767 } catch (IOException e) { 768 mHttpClientTestResult = "Fail: IOException"; 769 } 770 } 771 772 private void refreshSmsc() { 773 phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE)); 774 } 775 776 private final void updatePingState() { 777 final Handler handler = new Handler(); 778 // Set all to unknown since the threads will take a few secs to update. 779 mPingIpAddrResult = getResources().getString(R.string.radioInfo_unknown); 780 mPingHostnameResult = getResources().getString(R.string.radioInfo_unknown); 781 mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown); 782 783 mPingIpAddr.setText(mPingIpAddrResult); 784 mPingHostname.setText(mPingHostnameResult); 785 mHttpClientTest.setText(mHttpClientTestResult); 786 787 final Runnable updatePingResults = new Runnable() { 788 public void run() { 789 mPingIpAddr.setText(mPingIpAddrResult); 790 mPingHostname.setText(mPingHostnameResult); 791 mHttpClientTest.setText(mHttpClientTestResult); 792 } 793 }; 794 Thread ipAddr = new Thread() { 795 @Override 796 public void run() { 797 pingIpAddr(); 798 handler.post(updatePingResults); 799 } 800 }; 801 ipAddr.start(); 802 803 Thread hostname = new Thread() { 804 @Override 805 public void run() { 806 pingHostname(); 807 handler.post(updatePingResults); 808 } 809 }; 810 hostname.start(); 811 812 Thread httpClient = new Thread() { 813 @Override 814 public void run() { 815 httpClientTest(); 816 handler.post(updatePingResults); 817 } 818 }; 819 httpClient.start(); 820 } 821 822 private final void updatePdpList() { 823 StringBuilder sb = new StringBuilder("========DATA=======\n"); 824 825 // List<DataConnection> dcs = phone.getCurrentDataConnectionList(); 826 // 827 // for (DataConnection dc : dcs) { 828 // sb.append(" State=").append(dc.getStateAsString()).append("\n"); 829 // if (dc.isActive()) { 830 // long timeElapsed = 831 // (System.currentTimeMillis() - dc.getConnectionTime())/1000; 832 // sb.append(" connected at ") 833 // .append(DateUtils.timeString(dc.getConnectionTime())) 834 // .append(" and elapsed ") 835 // .append(DateUtils.formatElapsedTime(timeElapsed)); 836 // 837 // if (dc instanceof GsmDataConnection) { 838 // GsmDataConnection pdp = (GsmDataConnection)dc; 839 // sb.append("\n to ") 840 // .append(pdp.getApn().toString()); 841 // } 842 // sb.append("\nLinkProperties: "); 843 // sb.append(phone.getLinkProperties(phone.getActiveApnTypes()[0]).toString()); 844 // } else if (dc.isInactive()) { 845 // sb.append(" disconnected with last try at ") 846 // .append(DateUtils.timeString(dc.getLastFailTime())) 847 // .append("\n fail because ") 848 // .append(dc.getLastFailCause().toString()); 849 // } else { 850 // if (dc instanceof GsmDataConnection) { 851 // GsmDataConnection pdp = (GsmDataConnection)dc; 852 // sb.append(" is connecting to ") 853 // .append(pdp.getApn().toString()); 854 // } else { 855 // sb.append(" is connecting"); 856 // } 857 // } 858 // sb.append("\n==================="); 859 // } 860 861 disconnects.setText(sb.toString()); 862 } 863 864 private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() { 865 public boolean onMenuItemClick(MenuItem item) { 866 Intent intent = new Intent(Intent.ACTION_VIEW); 867 // XXX We need to specify the component here because if we don't 868 // the activity manager will try to resolve the type by calling 869 // the content provider, which causes it to be loaded in a process 870 // other than the Dialer process, which causes a lot of stuff to 871 // break. 872 intent.setClassName("com.android.phone", 873 "com.android.phone.SimContacts"); 874 startActivity(intent); 875 return true; 876 } 877 }; 878 879 private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() { 880 public boolean onMenuItemClick(MenuItem item) { 881 Intent intent = new Intent(Intent.ACTION_VIEW); 882 // XXX We need to specify the component here because if we don't 883 // the activity manager will try to resolve the type by calling 884 // the content provider, which causes it to be loaded in a process 885 // other than the Dialer process, which causes a lot of stuff to 886 // break. 887 intent.setClassName("com.android.phone", 888 "com.android.phone.settings.fdn.FdnList"); 889 startActivity(intent); 890 return true; 891 } 892 }; 893 894 private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() { 895 public boolean onMenuItemClick(MenuItem item) { 896 Intent intent = new Intent( 897 Intent.ACTION_VIEW, Uri.parse("content://icc/sdn")); 898 // XXX We need to specify the component here because if we don't 899 // the activity manager will try to resolve the type by calling 900 // the content provider, which causes it to be loaded in a process 901 // other than the Dialer process, which causes a lot of stuff to 902 // break. 903 intent.setClassName("com.android.phone", 904 "com.android.phone.ADNList"); 905 startActivity(intent); 906 return true; 907 } 908 }; 909 910 private MenuItem.OnMenuItemClickListener mGetPdpList = new MenuItem.OnMenuItemClickListener() { 911 public boolean onMenuItemClick(MenuItem item) { 912 phone.getDataCallList(null); 913 return true; 914 } 915 }; 916 917 private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() { 918 public boolean onMenuItemClick(MenuItem item) { 919 Intent intent = new Intent(); 920 intent.setClass(RadioInfo.this, BandMode.class); 921 startActivity(intent); 922 return true; 923 } 924 }; 925 926 private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() { 927 public boolean onMenuItemClick(MenuItem item) { 928 int state = mTelephonyManager.getDataState(); 929 switch (state) { 930 case TelephonyManager.DATA_CONNECTED: 931 phone.setDataEnabled(false); 932 break; 933 case TelephonyManager.DATA_DISCONNECTED: 934 phone.setDataEnabled(true); 935 break; 936 default: 937 // do nothing 938 break; 939 } 940 return true; 941 } 942 }; 943 944 OnClickListener mPowerButtonHandler = new OnClickListener() { 945 public void onClick(View v) { 946 //log("toggle radio power: currently " + (isRadioOn()?"on":"off")); 947 phone.setRadioPower(!isRadioOn()); 948 } 949 }; 950 951 class CellInfoListRateHandler implements OnClickListener { 952 int rates[] = {Integer.MAX_VALUE, 0, 1000}; 953 int index = 0; 954 955 public int getRate() { 956 return rates[index]; 957 } 958 959 @Override 960 public void onClick(View v) { 961 index += 1; 962 if (index >= rates.length) { 963 index = 0; 964 } 965 phone.setCellInfoListRate(rates[index]); 966 updateCellInfoListRate(); 967 } 968 } 969 CellInfoListRateHandler mCellInfoListRateHandler = new CellInfoListRateHandler(); 970 971 private Button imsRegRequiredButton; 972 static final String PROPERTY_IMS_REG_REQUIRED = "persist.radio.imsregrequired"; 973 OnClickListener mImsRegRequiredHandler = new OnClickListener() { 974 @Override 975 public void onClick(View v) { 976 log(String.format("toggle %s: currently %s", 977 PROPERTY_IMS_REG_REQUIRED, (isImsRegRequired() ? "on":"off"))); 978 boolean newValue = !isImsRegRequired(); 979 SystemProperties.set(PROPERTY_IMS_REG_REQUIRED, 980 newValue ? "1":"0"); 981 updateImsRegRequiredState(); 982 } 983 }; 984 985 private boolean isImsRegRequired() { 986 return SystemProperties.getBoolean(PROPERTY_IMS_REG_REQUIRED, false); 987 } 988 989 private void updateImsRegRequiredState() { 990 log("updateImsRegRequiredState isImsRegRequired()=" + isImsRegRequired()); 991 String buttonText = isImsRegRequired() ? 992 getString(R.string.ims_reg_required_off) : 993 getString(R.string.ims_reg_required_on); 994 imsRegRequiredButton.setText(buttonText); 995 } 996 997 private Button smsOverImsButton; 998 static final String PROPERTY_SMS_OVER_IMS = "persist.radio.imsallowmtsms"; 999 OnClickListener mSmsOverImsHandler = new OnClickListener() { 1000 @Override 1001 public void onClick(View v) { 1002 log(String.format("toggle %s: currently %s", 1003 PROPERTY_SMS_OVER_IMS, (isSmsOverImsEnabled() ? "on":"off"))); 1004 boolean newValue = !isSmsOverImsEnabled(); 1005 SystemProperties.set(PROPERTY_SMS_OVER_IMS, newValue ? "1":"0"); 1006 updateSmsOverImsState(); 1007 } 1008 }; 1009 1010 private boolean isSmsOverImsEnabled() { 1011 return SystemProperties.getBoolean(PROPERTY_SMS_OVER_IMS, false); 1012 } 1013 1014 private Button imsVoLteProvisionedButton; 1015 OnClickListener mImsVoLteProvisionedHandler = new OnClickListener() { 1016 @Override 1017 public void onClick(View v) { 1018 log(String.format("toggle VoLTE provisioned: currently %s", 1019 (isImsVoLteProvisioned() ? "on":"off"))); 1020 final boolean newValue = !isImsVoLteProvisioned(); 1021 if (phone != null) { 1022 final ImsManager imsManager = ImsManager.getInstance(phone.getContext(), phone.getSubId()); 1023 if (imsManager != null) { 1024 QueuedWork.singleThreadExecutor().submit(new Runnable() { 1025 public void run() { 1026 try { 1027 imsManager.getConfigInterface().setProvisionedValue( 1028 ImsConfig.ConfigConstants.VLT_SETTING_ENABLED, 1029 newValue? 1 : 0); 1030 } catch (ImsException e) { 1031 Log.e(TAG, "setImsVoLteProvisioned() exception:", e); 1032 } 1033 } 1034 }); 1035 } 1036 } 1037 updateImsVoLteProvisionedState(); 1038 } 1039 }; 1040 1041 private boolean isImsVoLteProvisioned() { 1042 if (phone != null) { 1043 ImsManager imsManager = ImsManager.getInstance(phone.getContext(), phone.getSubId()); 1044 return imsManager.isVolteProvisionedOnDevice(phone.getContext()); 1045 } 1046 return false; 1047 } 1048 1049 private void updateImsVoLteProvisionedState() { 1050 log("updateImsVoLteProvisionedState isImsVoLteProvisioned()=" + isImsVoLteProvisioned()); 1051 String buttonText = isImsVoLteProvisioned() ? 1052 getString(R.string.volte_provisioned_flag_off) : 1053 getString(R.string.volte_provisioned_flag_on); 1054 imsVoLteProvisionedButton.setText(buttonText); 1055 } 1056 1057 private void updateSmsOverImsState() { 1058 log("updateSmsOverImsState isSmsOverImsEnabled()=" + isSmsOverImsEnabled()); 1059 String buttonText = isSmsOverImsEnabled() ? 1060 getString(R.string.sms_over_ims_off) : 1061 getString(R.string.sms_over_ims_on); 1062 smsOverImsButton.setText(buttonText); 1063 } 1064 1065 private Button lteRamDumpButton; 1066 static final String PROPERTY_LTE_RAM_DUMP = "persist.radio.ramdump"; 1067 OnClickListener mLteRamDumpHandler = new OnClickListener() { 1068 @Override 1069 public void onClick(View v) { 1070 log(String.format("toggle %s: currently %s", 1071 PROPERTY_LTE_RAM_DUMP, (isSmsOverImsEnabled() ? "on":"off"))); 1072 boolean newValue = !isLteRamDumpEnabled(); 1073 SystemProperties.set(PROPERTY_LTE_RAM_DUMP, newValue ? "1":"0"); 1074 updateLteRamDumpState(); 1075 } 1076 }; 1077 1078 private boolean isLteRamDumpEnabled() { 1079 return SystemProperties.getBoolean(PROPERTY_LTE_RAM_DUMP, false); 1080 } 1081 1082 private void updateLteRamDumpState() { 1083 log("updateLteRamDumpState isLteRamDumpEnabled()=" + isLteRamDumpEnabled()); 1084 String buttonText = isLteRamDumpEnabled() ? 1085 getString(R.string.lte_ram_dump_off) : 1086 getString(R.string.lte_ram_dump_on); 1087 lteRamDumpButton.setText(buttonText); 1088 } 1089 1090 OnClickListener mDnsCheckButtonHandler = new OnClickListener() { 1091 public void onClick(View v) { 1092 phone.disableDnsCheck(!phone.isDnsCheckDisabled()); 1093 updateDnsCheckState(); 1094 } 1095 }; 1096 1097 OnClickListener mOemInfoButtonHandler = new OnClickListener() { 1098 public void onClick(View v) { 1099 Intent intent = new Intent("com.android.settings.OEM_RADIO_INFO"); 1100 try { 1101 startActivity(intent); 1102 } catch (android.content.ActivityNotFoundException ex) { 1103 log("OEM-specific Info/Settings Activity Not Found : " + ex); 1104 // If the activity does not exist, there are no OEM 1105 // settings, and so we can just do nothing... 1106 } 1107 } 1108 }; 1109 1110 OnClickListener mPingButtonHandler = new OnClickListener() { 1111 public void onClick(View v) { 1112 updatePingState(); 1113 } 1114 }; 1115 1116 OnClickListener mUpdateSmscButtonHandler = new OnClickListener() { 1117 public void onClick(View v) { 1118 updateSmscButton.setEnabled(false); 1119 phone.setSmscAddress(smsc.getText().toString(), 1120 mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE)); 1121 } 1122 }; 1123 1124 OnClickListener mRefreshSmscButtonHandler = new OnClickListener() { 1125 public void onClick(View v) { 1126 refreshSmsc(); 1127 } 1128 }; 1129 1130 AdapterView.OnItemSelectedListener 1131 mPreferredNetworkHandler = new AdapterView.OnItemSelectedListener() { 1132 public void onItemSelected(AdapterView parent, View v, int pos, long id) { 1133 Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE); 1134 if (pos>=0 && pos<=(mPreferredNetworkLabels.length - 2)) { 1135 phone.setPreferredNetworkType(pos, msg); 1136 } 1137 } 1138 1139 public void onNothingSelected(AdapterView parent) { 1140 } 1141 }; 1142 1143 private String[] mPreferredNetworkLabels = { 1144 "WCDMA preferred", 1145 "GSM only", 1146 "WCDMA only", 1147 "GSM auto (PRL)", 1148 "CDMA auto (PRL)", 1149 "CDMA only", 1150 "EvDo only", 1151 "GSM/CDMA auto (PRL)", 1152 "LTE/CDMA auto (PRL)", 1153 "LTE/GSM auto (PRL)", 1154 "LTE/GSM/CDMA auto (PRL)", 1155 "LTE only", 1156 "Unknown"}; 1157 1158 private void log(String s) { 1159 Log.d(TAG, "[RadioInfo] " + s); 1160 } 1161 } 1162