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