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