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