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