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