2 * Copyright (C) 2006 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings;
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.graphics.Typeface;
26 import android.net.TrafficStats;
27 import android.net.Uri;
28 import android.os.AsyncResult;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.os.Message;
32 import android.telephony.CellInfo;
33 import android.telephony.CellInfoCdma;
34 import android.telephony.CellInfoGsm;
35 import android.telephony.CellInfoLte;
36 import android.telephony.CellInfoWcdma;
37 import android.telephony.CellIdentityCdma;
38 import android.telephony.CellIdentityGsm;
39 import android.telephony.CellIdentityLte;
40 import android.telephony.CellIdentityWcdma;
41 import android.telephony.CellLocation;
42 import android.telephony.CellSignalStrengthCdma;
43 import android.telephony.CellSignalStrengthGsm;
44 import android.telephony.CellSignalStrengthLte;
45 import android.telephony.CellSignalStrengthWcdma;
46 import android.telephony.DataConnectionRealTimeInfo;
47 import android.telephony.NeighboringCellInfo;
48 import android.telephony.PreciseCallState;
49 import android.telephony.PhoneStateListener;
50 import android.telephony.ServiceState;
51 import android.telephony.SignalStrength;
52 import android.telephony.SubscriptionManager;
53 import android.telephony.TelephonyManager;
54 import android.telephony.cdma.CdmaCellLocation;
55 import android.telephony.gsm.GsmCellLocation;
56 import android.util.Log;
57 import android.view.Menu;
58 import android.view.MenuItem;
59 import android.view.View;
60 import android.view.View.OnClickListener;
61 import android.widget.AdapterView;
62 import android.widget.ArrayAdapter;
63 import android.widget.Button;
64 import android.widget.CompoundButton;
65 import android.widget.CompoundButton.OnCheckedChangeListener;
66 import android.widget.EditText;
67 import android.widget.Spinner;
68 import android.widget.Switch;
69 import android.widget.TextView;
71 import com.android.ims.ImsConfig;
72 import com.android.ims.ImsException;
73 import com.android.ims.ImsManager;
74 import com.android.internal.telephony.Phone;
75 import com.android.internal.telephony.PhoneConstants;
76 import com.android.internal.telephony.PhoneFactory;
77 import com.android.internal.telephony.RILConstants;
78 import com.android.internal.telephony.TelephonyProperties;
80 import java.io.IOException;
81 import java.net.HttpURLConnection;
83 import java.net.UnknownHostException;
84 import java.util.ArrayList;
85 import java.util.List;
87 public class RadioInfo extends Activity {
88 private static final String TAG = "RadioInfo";
90 private static final String[] mPreferredNetworkLabels = {
99 "LTE/CDMA auto (PRL)",
100 "LTE/UMTS auto (PRL)",
101 "LTE/CDMA/UMTS auto (PRL)",
109 "LTE/TD-SCDMA/WCDMA",
111 "TD-SCDMA/CDMA/UMTS",
117 private static final int CELL_INFO_LIST_RATE_DISABLED = Integer.MAX_VALUE;
118 private static final int CELL_INFO_LIST_RATE_MAX = 0;
121 private static final int IMS_VOLTE_PROVISIONED_CONFIG_ID =
122 ImsConfig.ConfigConstants.VLT_SETTING_ENABLED;
124 private static final int IMS_VT_PROVISIONED_CONFIG_ID =
125 ImsConfig.ConfigConstants.LVC_SETTING_ENABLED;
127 private static final int IMS_WFC_PROVISIONED_CONFIG_ID =
128 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED;
130 //Values in must match mCellInfoRefreshRates
131 private static final String[] mCellInfoRefreshRateLabels = {
139 //Values in seconds, must match mCellInfoRefreshRateLabels
140 private static final int mCellInfoRefreshRates[] = {
141 CELL_INFO_LIST_RATE_DISABLED,
142 CELL_INFO_LIST_RATE_MAX,
148 private void log(String s) {
152 private static final int EVENT_CFI_CHANGED = 302;
154 private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
155 private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
156 private static final int EVENT_QUERY_SMSC_DONE = 1005;
157 private static final int EVENT_UPDATE_SMSC_DONE = 1006;
159 private static final int MENU_ITEM_SELECT_BAND = 0;
160 private static final int MENU_ITEM_VIEW_ADN = 1;
161 private static final int MENU_ITEM_VIEW_FDN = 2;
162 private static final int MENU_ITEM_VIEW_SDN = 3;
163 private static final int MENU_ITEM_GET_PDP_LIST = 4;
164 private static final int MENU_ITEM_TOGGLE_DATA = 5;
166 private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
167 private TextView number;
168 private TextView callState;
169 private TextView operatorName;
170 private TextView roamingState;
171 private TextView gsmState;
172 private TextView gprsState;
173 private TextView voiceNetwork;
174 private TextView dataNetwork;
175 private TextView dBm;
176 private TextView mMwi;
177 private TextView mCfi;
178 private TextView mLocation;
179 private TextView mNeighboringCids;
180 private TextView mCellInfo;
181 private TextView mDcRtInfoTv;
182 private TextView sent;
183 private TextView received;
184 private TextView mPingHostnameV4;
185 private TextView mPingHostnameV6;
186 private TextView mHttpClientTest;
187 private TextView dnsCheckState;
188 private EditText smsc;
189 private Switch radioPowerOnSwitch;
190 private Button cellInfoRefreshRateButton;
191 private Button dnsCheckToggleButton;
192 private Button pingTestButton;
193 private Button updateSmscButton;
194 private Button refreshSmscButton;
195 private Button oemInfoButton;
196 private Switch imsVolteProvisionedSwitch;
197 private Switch imsVtProvisionedSwitch;
198 private Switch imsWfcProvisionedSwitch;
199 private Spinner preferredNetworkType;
200 private Spinner cellInfoRefreshRateSpinner;
202 private TelephonyManager mTelephonyManager;
203 private ImsManager mImsManager = null;
204 private Phone phone = null;
206 private String mPingHostnameResultV4;
207 private String mPingHostnameResultV6;
208 private String mHttpClientTestResult;
209 private boolean mMwiValue = false;
210 private boolean mCfiValue = false;
212 private List<CellInfo> mCellInfoResult = null;
213 private CellLocation mCellLocationResult = null;
214 private List<NeighboringCellInfo> mNeighboringCellResult = null;
216 private int mPreferredNetworkTypeResult;
217 private int mCellInfoRefreshRateIndex;
219 private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
221 public void onDataConnectionStateChanged(int state) {
227 public void onDataActivity(int direction) {
232 public void onCallStateChanged(int state, String incomingNumber) {
234 updatePhoneState(state);
238 public void onPreciseCallStateChanged(PreciseCallState preciseState) {
243 public void onCellLocationChanged(CellLocation location) {
244 updateLocation(location);
248 public void onMessageWaitingIndicatorChanged(boolean mwi) {
250 updateMessageWaiting();
254 public void onCallForwardingIndicatorChanged(boolean cfi) {
256 updateCallRedirect();
260 public void onCellInfoChanged(List<CellInfo> arrayCi) {
261 log("onCellInfoChanged: arrayCi=" + arrayCi);
262 mCellInfoResult = arrayCi;
263 updateCellInfo(mCellInfoResult);
267 public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) {
268 log("onDataConnectionRealTimeInfoChanged: dcRtInfo=" + dcRtInfo);
269 updateDcRtInfoTv(dcRtInfo);
273 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
274 log("onSignalStrengthChanged: SignalStrength=" +signalStrength);
275 updateSignalStrength(signalStrength);
279 public void onServiceStateChanged(ServiceState serviceState) {
280 log("onServiceStateChanged: ServiceState=" + serviceState);
281 updateServiceState(serviceState);
282 updateRadioPowerState();
284 updateImsProvisionedState();
288 private void updatePreferredNetworkType(int type) {
289 if (type >= mPreferredNetworkLabels.length || type < 0) {
290 log("EVENT_QUERY_PREFERRED_TYPE_DONE: unknown " +
292 type = mPreferredNetworkLabels.length - 1; //set to Unknown
294 mPreferredNetworkTypeResult = type;
296 preferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
299 private Handler mHandler = new Handler() {
301 public void handleMessage(Message msg) {
304 case EVENT_QUERY_PREFERRED_TYPE_DONE:
305 ar= (AsyncResult) msg.obj;
306 if (ar.exception == null && ar.result != null) {
307 updatePreferredNetworkType(((int[])ar.result)[0]);
309 //In case of an exception, we will set this to unknown
310 updatePreferredNetworkType(mPreferredNetworkLabels.length-1);
313 case EVENT_SET_PREFERRED_TYPE_DONE:
314 ar= (AsyncResult) msg.obj;
315 if (ar.exception != null) {
316 log("Set preferred network type failed.");
319 case EVENT_QUERY_SMSC_DONE:
320 ar= (AsyncResult) msg.obj;
321 if (ar.exception != null) {
322 smsc.setText("refresh error");
324 smsc.setText((String)ar.result);
327 case EVENT_UPDATE_SMSC_DONE:
328 updateSmscButton.setEnabled(true);
329 ar= (AsyncResult) msg.obj;
330 if (ar.exception != null) {
331 smsc.setText("update error");
335 super.handleMessage(msg);
343 public void onCreate(Bundle icicle) {
344 super.onCreate(icicle);
345 if (!android.os.Process.myUserHandle().isSystem()) {
346 Log.e(TAG, "Not run from system user, don't do anything.");
351 setContentView(R.layout.radio_info);
353 log("Started onCreate");
355 mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
356 phone = PhoneFactory.getDefaultPhone();
358 //TODO: Need to update this if the default phoneId changes?
359 // Better to have an instance per phone?
360 mImsManager = ImsManager.getInstance(getApplicationContext(),
361 SubscriptionManager.getDefaultVoicePhoneId());
363 mDeviceId= (TextView) findViewById(R.id.imei);
364 number = (TextView) findViewById(R.id.number);
365 callState = (TextView) findViewById(R.id.call);
366 operatorName = (TextView) findViewById(R.id.operator);
367 roamingState = (TextView) findViewById(R.id.roaming);
368 gsmState = (TextView) findViewById(R.id.gsm);
369 gprsState = (TextView) findViewById(R.id.gprs);
370 voiceNetwork = (TextView) findViewById(R.id.voice_network);
371 dataNetwork = (TextView) findViewById(R.id.data_network);
372 dBm = (TextView) findViewById(R.id.dbm);
373 mMwi = (TextView) findViewById(R.id.mwi);
374 mCfi = (TextView) findViewById(R.id.cfi);
375 mLocation = (TextView) findViewById(R.id.location);
376 mNeighboringCids = (TextView) findViewById(R.id.neighboring);
377 mCellInfo = (TextView) findViewById(R.id.cellinfo);
378 mCellInfo.setTypeface(Typeface.MONOSPACE);
379 mDcRtInfoTv = (TextView) findViewById(R.id.dcrtinfo);
381 sent = (TextView) findViewById(R.id.sent);
382 received = (TextView) findViewById(R.id.received);
383 smsc = (EditText) findViewById(R.id.smsc);
384 dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
385 mPingHostnameV4 = (TextView) findViewById(R.id.pingHostnameV4);
386 mPingHostnameV6 = (TextView) findViewById(R.id.pingHostnameV6);
387 mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
389 preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
390 ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
391 android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
392 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
393 preferredNetworkType.setAdapter(adapter);
395 cellInfoRefreshRateSpinner = (Spinner) findViewById(R.id.cell_info_rate_select);
396 ArrayAdapter<String> cellInfoAdapter = new ArrayAdapter<String>(this,
397 android.R.layout.simple_spinner_item, mCellInfoRefreshRateLabels);
398 cellInfoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
399 cellInfoRefreshRateSpinner.setAdapter(cellInfoAdapter);
401 imsVolteProvisionedSwitch = (Switch) findViewById(R.id.volte_provisioned_switch);
402 imsVtProvisionedSwitch = (Switch) findViewById(R.id.vt_provisioned_switch);
403 imsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
405 radioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
407 pingTestButton = (Button) findViewById(R.id.ping_test);
408 pingTestButton.setOnClickListener(mPingButtonHandler);
409 updateSmscButton = (Button) findViewById(R.id.update_smsc);
410 updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
411 refreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
412 refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
413 dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
414 dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
416 oemInfoButton = (Button) findViewById(R.id.oem_info);
417 oemInfoButton.setOnClickListener(mOemInfoButtonHandler);
418 PackageManager pm = getPackageManager();
419 Intent oemInfoIntent = new Intent("com.android.settings.OEM_RADIO_INFO");
420 List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0);
421 if (oemInfoIntentList.size() == 0) {
422 oemInfoButton.setEnabled(false);
425 mCellInfoRefreshRateIndex = 0; //disabled
426 mPreferredNetworkTypeResult = mPreferredNetworkLabels.length - 1; //Unknown
428 //FIXME: Replace with TelephonyManager call
429 phone.getPreferredNetworkType(
430 mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
432 restoreFromBundle(icicle);
436 protected void onResume() {
439 log("Started onResume");
441 updateMessageWaiting();
442 updateCallRedirect();
445 updateRadioPowerState();
446 updateImsProvisionedState();
448 updateDnsCheckState();
451 updateNeighboringCids(mNeighboringCellResult);
452 updateLocation(mCellLocationResult);
453 updateCellInfo(mCellInfoResult);
455 mPingHostnameV4.setText(mPingHostnameResultV4);
456 mPingHostnameV6.setText(mPingHostnameResultV6);
457 mHttpClientTest.setText(mHttpClientTestResult);
459 cellInfoRefreshRateSpinner.setOnItemSelectedListener(mCellInfoRefreshRateHandler);
460 //set selection after registering listener to force update
461 cellInfoRefreshRateSpinner.setSelection(mCellInfoRefreshRateIndex);
463 //set selection before registering to prevent update
464 preferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
465 preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
467 radioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
468 imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
469 imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
470 imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
472 mTelephonyManager.listen(mPhoneStateListener,
473 PhoneStateListener.LISTEN_CALL_STATE
474 //b/27803938 - RadioInfo currently cannot read PRECISE_CALL_STATE
475 // | PhoneStateListener.LISTEN_PRECISE_CALL_STATE
476 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
477 | PhoneStateListener.LISTEN_DATA_ACTIVITY
478 | PhoneStateListener.LISTEN_CELL_LOCATION
479 | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
480 | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
481 | PhoneStateListener.LISTEN_CELL_INFO
482 | PhoneStateListener.LISTEN_SERVICE_STATE
483 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
484 | PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO);
490 protected void onPause() {
493 log("onPause: unregister phone & data intents");
495 mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
496 phone.setCellInfoListRate(CELL_INFO_LIST_RATE_DISABLED);
499 private void restoreFromBundle(Bundle b) {
504 mPingHostnameResultV4 = b.getString("mPingHostnameResultV4","");
505 mPingHostnameResultV6 = b.getString("mPingHostnameResultV6","");
506 mHttpClientTestResult = b.getString("mHttpClientTestResult","");
508 mPingHostnameV4.setText(mPingHostnameResultV4);
509 mPingHostnameV6.setText(mPingHostnameResultV6);
510 mHttpClientTest.setText(mHttpClientTestResult);
512 mPreferredNetworkTypeResult = b.getInt("mPreferredNetworkTypeResult",
513 mPreferredNetworkLabels.length - 1);
515 mCellInfoRefreshRateIndex = b.getInt("mCellInfoRefreshRateIndex", 0);
519 protected void onSaveInstanceState(Bundle outState) {
520 outState.putString("mPingHostnameResultV4", mPingHostnameResultV4);
521 outState.putString("mPingHostnameResultV6", mPingHostnameResultV6);
522 outState.putString("mHttpClientTestResult", mHttpClientTestResult);
524 outState.putInt("mPreferredNetworkTypeResult", mPreferredNetworkTypeResult);
525 outState.putInt("mCellInfoRefreshRateIndex", mCellInfoRefreshRateIndex);
530 public boolean onCreateOptionsMenu(Menu menu) {
531 menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label)
532 .setOnMenuItemClickListener(mSelectBandCallback)
533 .setAlphabeticShortcut('b');
534 menu.add(1, MENU_ITEM_VIEW_ADN, 0,
535 R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
536 menu.add(1, MENU_ITEM_VIEW_FDN, 0,
537 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
538 menu.add(1, MENU_ITEM_VIEW_SDN, 0,
539 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
540 menu.add(1, MENU_ITEM_GET_PDP_LIST,
541 0, R.string.radioInfo_menu_getPDP).setOnMenuItemClickListener(mGetPdpList);
542 menu.add(1, MENU_ITEM_TOGGLE_DATA,
543 0, R.string.radio_info_data_connection_disable).setOnMenuItemClickListener(mToggleData);
548 public boolean onPrepareOptionsMenu(Menu menu) {
549 // Get the TOGGLE DATA menu item in the right state.
550 MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
551 int state = mTelephonyManager.getDataState();
552 boolean visible = true;
555 case TelephonyManager.DATA_CONNECTED:
556 case TelephonyManager.DATA_SUSPENDED:
557 item.setTitle(R.string.radio_info_data_connection_disable);
559 case TelephonyManager.DATA_DISCONNECTED:
560 item.setTitle(R.string.radio_info_data_connection_enable);
566 item.setVisible(visible);
570 private void updateDnsCheckState() {
571 //FIXME: Replace with a TelephonyManager call
572 dnsCheckState.setText(phone.isDnsCheckDisabled() ?
573 "0.0.0.0 allowed" :"0.0.0.0 not allowed");
577 updateSignalStrength(SignalStrength signalStrength) {
578 Resources r = getResources();
580 int signalDbm = signalStrength.getDbm();
582 int signalAsu = signalStrength.getAsuLevel();
584 if (-1 == signalAsu) signalAsu = 0;
586 dBm.setText(String.valueOf(signalDbm) + " "
587 + r.getString(R.string.radioInfo_display_dbm) + " "
588 + String.valueOf(signalAsu) + " "
589 + r.getString(R.string.radioInfo_display_asu));
592 private final void updateLocation(CellLocation location) {
593 Resources r = getResources();
594 if (location instanceof GsmCellLocation) {
595 GsmCellLocation loc = (GsmCellLocation)location;
596 int lac = loc.getLac();
597 int cid = loc.getCid();
598 mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
599 + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
601 + r.getString(R.string.radioInfo_cid) + " = "
602 + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
603 } else if (location instanceof CdmaCellLocation) {
604 CdmaCellLocation loc = (CdmaCellLocation)location;
605 int bid = loc.getBaseStationId();
606 int sid = loc.getSystemId();
607 int nid = loc.getNetworkId();
608 int lat = loc.getBaseStationLatitude();
609 int lon = loc.getBaseStationLongitude();
610 mLocation.setText("BID = "
611 + ((bid == -1) ? "unknown" : Integer.toHexString(bid))
614 + ((sid == -1) ? "unknown" : Integer.toHexString(sid))
617 + ((nid == -1) ? "unknown" : Integer.toHexString(nid))
620 + ((lat == -1) ? "unknown" : Integer.toHexString(lat))
623 + ((lon == -1) ? "unknown" : Integer.toHexString(lon)));
625 mLocation.setText("unknown");
631 private final void updateNeighboringCids(List<NeighboringCellInfo> cids) {
632 StringBuilder sb = new StringBuilder();
635 if ( cids.isEmpty() ) {
636 sb.append("no neighboring cells");
638 for (NeighboringCellInfo cell : cids) {
639 sb.append(cell.toString()).append(" ");
643 sb.append("unknown");
645 mNeighboringCids.setText(sb.toString());
648 private final String getCellInfoDisplayString(int i) {
649 return (i != Integer.MAX_VALUE) ? Integer.toString(i) : "";
652 private final String getCellInfoDisplayString(long i) {
653 return (i != Long.MAX_VALUE) ? Long.toString(i) : "";
656 private final String buildCdmaInfoString(CellInfoCdma ci) {
657 CellIdentityCdma cidCdma = ci.getCellIdentity();
658 CellSignalStrengthCdma ssCdma = ci.getCellSignalStrength();
660 return String.format("%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s",
661 ci.isRegistered() ? "S " : " ",
662 getCellInfoDisplayString(cidCdma.getSystemId()),
663 getCellInfoDisplayString(cidCdma.getNetworkId()),
664 getCellInfoDisplayString(cidCdma.getBasestationId()),
665 getCellInfoDisplayString(ssCdma.getCdmaDbm()),
666 getCellInfoDisplayString(ssCdma.getCdmaEcio()),
667 getCellInfoDisplayString(ssCdma.getEvdoDbm()),
668 getCellInfoDisplayString(ssCdma.getEvdoEcio()),
669 getCellInfoDisplayString(ssCdma.getEvdoSnr()));
672 private final String buildGsmInfoString(CellInfoGsm ci) {
673 CellIdentityGsm cidGsm = ci.getCellIdentity();
674 CellSignalStrengthGsm ssGsm = ci.getCellSignalStrength();
676 return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
677 ci.isRegistered() ? "S " : " ",
678 getCellInfoDisplayString(cidGsm.getMcc()),
679 getCellInfoDisplayString(cidGsm.getMnc()),
680 getCellInfoDisplayString(cidGsm.getLac()),
681 getCellInfoDisplayString(cidGsm.getCid()),
682 getCellInfoDisplayString(cidGsm.getArfcn()),
683 getCellInfoDisplayString(cidGsm.getBsic()),
684 getCellInfoDisplayString(ssGsm.getDbm()));
687 private final String buildLteInfoString(CellInfoLte ci) {
688 CellIdentityLte cidLte = ci.getCellIdentity();
689 CellSignalStrengthLte ssLte = ci.getCellSignalStrength();
691 return String.format(
692 "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s %-2.2s\n",
693 ci.isRegistered() ? "S " : " ",
694 getCellInfoDisplayString(cidLte.getMcc()),
695 getCellInfoDisplayString(cidLte.getMnc()),
696 getCellInfoDisplayString(cidLte.getTac()),
697 getCellInfoDisplayString(cidLte.getCi()),
698 getCellInfoDisplayString(cidLte.getPci()),
699 getCellInfoDisplayString(cidLte.getEarfcn()),
700 getCellInfoDisplayString(ssLte.getDbm()),
701 getCellInfoDisplayString(ssLte.getRsrq()),
702 getCellInfoDisplayString(ssLte.getTimingAdvance()));
705 private final String buildWcdmaInfoString(CellInfoWcdma ci) {
706 CellIdentityWcdma cidWcdma = ci.getCellIdentity();
707 CellSignalStrengthWcdma ssWcdma = ci.getCellSignalStrength();
709 return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
710 ci.isRegistered() ? "S " : " ",
711 getCellInfoDisplayString(cidWcdma.getMcc()),
712 getCellInfoDisplayString(cidWcdma.getMnc()),
713 getCellInfoDisplayString(cidWcdma.getLac()),
714 getCellInfoDisplayString(cidWcdma.getCid()),
715 getCellInfoDisplayString(cidWcdma.getUarfcn()),
716 getCellInfoDisplayString(cidWcdma.getPsc()),
717 getCellInfoDisplayString(ssWcdma.getDbm()));
720 private final String buildCellInfoString(List<CellInfo> arrayCi) {
721 String value = new String();
722 StringBuilder cdmaCells = new StringBuilder(),
723 gsmCells = new StringBuilder(),
724 lteCells = new StringBuilder(),
725 wcdmaCells = new StringBuilder();
727 if (arrayCi != null) {
728 for (CellInfo ci : arrayCi) {
730 if (ci instanceof CellInfoLte) {
731 lteCells.append(buildLteInfoString((CellInfoLte) ci));
732 } else if (ci instanceof CellInfoWcdma) {
733 wcdmaCells.append(buildWcdmaInfoString((CellInfoWcdma) ci));
734 } else if (ci instanceof CellInfoGsm) {
735 gsmCells.append(buildGsmInfoString((CellInfoGsm) ci));
736 } else if (ci instanceof CellInfoCdma) {
737 cdmaCells.append(buildCdmaInfoString((CellInfoCdma) ci));
740 if (lteCells.length() != 0) {
741 value += String.format(
742 "LTE\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s %-2.2s\n",
743 "SRV", "MCC", "MNC", "TAC", "CID", "PCI", "EARFCN", "RSRP", "RSRQ", "TA");
744 value += lteCells.toString();
746 if (wcdmaCells.length() != 0) {
747 value += String.format("WCDMA\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
748 "SRV", "MCC", "MNC", "LAC", "CID", "UARFCN", "PSC", "RSCP");
749 value += wcdmaCells.toString();
751 if (gsmCells.length() != 0) {
752 value += String.format("GSM\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
753 "SRV", "MCC", "MNC", "LAC", "CID", "ARFCN", "BSIC", "RSSI");
754 value += gsmCells.toString();
756 if (cdmaCells.length() != 0) {
757 value += String.format(
758 "CDMA/EVDO\n%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s\n",
759 "SRV", "SID", "NID", "BSID", "C-RSSI", "C-ECIO", "E-RSSI", "E-ECIO", "E-SNR");
760 value += cdmaCells.toString();
766 return value.toString();
769 private final void updateCellInfo(List<CellInfo> arrayCi) {
770 mCellInfo.setText(buildCellInfoString(arrayCi));
773 private final void updateDcRtInfoTv(DataConnectionRealTimeInfo dcRtInfo) {
774 mDcRtInfoTv.setText(dcRtInfo.toString());
778 updateMessageWaiting() {
779 mMwi.setText(String.valueOf(mMwiValue));
783 updateCallRedirect() {
784 mCfi.setText(String.valueOf(mCfiValue));
789 updateServiceState(ServiceState serviceState) {
790 int state = serviceState.getState();
791 Resources r = getResources();
792 String display = r.getString(R.string.radioInfo_unknown);
795 case ServiceState.STATE_IN_SERVICE:
796 display = r.getString(R.string.radioInfo_service_in);
798 case ServiceState.STATE_OUT_OF_SERVICE:
799 case ServiceState.STATE_EMERGENCY_ONLY:
800 display = r.getString(R.string.radioInfo_service_emergency);
802 case ServiceState.STATE_POWER_OFF:
803 display = r.getString(R.string.radioInfo_service_off);
807 gsmState.setText(display);
809 if (serviceState.getRoaming()) {
810 roamingState.setText(R.string.radioInfo_roaming_in);
812 roamingState.setText(R.string.radioInfo_roaming_not);
815 operatorName.setText(serviceState.getOperatorAlphaLong());
819 updatePhoneState(int state) {
820 Resources r = getResources();
821 String display = r.getString(R.string.radioInfo_unknown);
824 case TelephonyManager.CALL_STATE_IDLE:
825 display = r.getString(R.string.radioInfo_phone_idle);
827 case TelephonyManager.CALL_STATE_RINGING:
828 display = r.getString(R.string.radioInfo_phone_ringing);
830 case TelephonyManager.CALL_STATE_OFFHOOK:
831 display = r.getString(R.string.radioInfo_phone_offhook);
835 callState.setText(display);
840 int state = mTelephonyManager.getDataState();
841 Resources r = getResources();
842 String display = r.getString(R.string.radioInfo_unknown);
845 case TelephonyManager.DATA_CONNECTED:
846 display = r.getString(R.string.radioInfo_data_connected);
848 case TelephonyManager.DATA_CONNECTING:
849 display = r.getString(R.string.radioInfo_data_connecting);
851 case TelephonyManager.DATA_DISCONNECTED:
852 display = r.getString(R.string.radioInfo_data_disconnected);
854 case TelephonyManager.DATA_SUSPENDED:
855 display = r.getString(R.string.radioInfo_data_suspended);
859 gprsState.setText(display);
862 private final void updateNetworkType() {
863 if( phone != null ) {
864 ServiceState ss = phone.getServiceState();
865 dataNetwork.setText(ServiceState.rilRadioTechnologyToString(
866 phone.getServiceState().getRilDataRadioTechnology()));
867 voiceNetwork.setText(ServiceState.rilRadioTechnologyToString(
868 phone.getServiceState().getRilVoiceRadioTechnology()));
875 Resources r = getResources();
877 s = phone.getDeviceId();
878 if (s == null) s = r.getString(R.string.radioInfo_unknown);
879 mDeviceId.setText(s);
881 //FIXME: Replace with a TelephonyManager call
882 s = phone.getLine1Number();
883 if (s == null) s = r.getString(R.string.radioInfo_unknown);
887 private final void updateDataStats2() {
888 Resources r = getResources();
890 long txPackets = TrafficStats.getMobileTxPackets();
891 long rxPackets = TrafficStats.getMobileRxPackets();
892 long txBytes = TrafficStats.getMobileTxBytes();
893 long rxBytes = TrafficStats.getMobileRxBytes();
895 String packets = r.getString(R.string.radioInfo_display_packets);
896 String bytes = r.getString(R.string.radioInfo_display_bytes);
898 sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
899 received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
905 private final void pingHostname() {
908 Process p4 = Runtime.getRuntime().exec("ping -c 1 www.google.com");
909 int status4 = p4.waitFor();
911 mPingHostnameResultV4 = "Pass";
913 mPingHostnameResultV4 = String.format("Fail(%d)", status4);
915 } catch (IOException e) {
916 mPingHostnameResultV4 = "Fail: IOException";
919 Process p6 = Runtime.getRuntime().exec("ping6 -c 1 www.google.com");
920 int status6 = p6.waitFor();
922 mPingHostnameResultV6 = "Pass";
924 mPingHostnameResultV6 = String.format("Fail(%d)", status6);
926 } catch (IOException e) {
927 mPingHostnameResultV6 = "Fail: IOException";
929 } catch (InterruptedException e) {
930 mPingHostnameResultV4 = mPingHostnameResultV6 = "Fail: InterruptedException";
935 * This function checks for basic functionality of HTTP Client.
937 private void httpClientTest() {
938 HttpURLConnection urlConnection = null;
940 // TODO: Hardcoded for now, make it UI configurable
941 URL url = new URL("https://www.google.com");
942 urlConnection = (HttpURLConnection) url.openConnection();
943 if (urlConnection.getResponseCode() == 200) {
944 mHttpClientTestResult = "Pass";
946 mHttpClientTestResult = "Fail: Code: " + urlConnection.getResponseMessage();
948 } catch (IOException e) {
949 mHttpClientTestResult = "Fail: IOException";
951 if (urlConnection != null) {
952 urlConnection.disconnect();
957 private void refreshSmsc() {
958 //FIXME: Replace with a TelephonyManager call
959 phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
962 private final void updateAllCellInfo() {
964 mCellInfo.setText("");
965 mNeighboringCids.setText("");
966 mLocation.setText("");
968 final Runnable updateAllCellInfoResults = new Runnable() {
970 updateNeighboringCids(mNeighboringCellResult);
971 updateLocation(mCellLocationResult);
972 updateCellInfo(mCellInfoResult);
976 Thread locThread = new Thread() {
979 mCellInfoResult = mTelephonyManager.getAllCellInfo();
980 mCellLocationResult = mTelephonyManager.getCellLocation();
981 mNeighboringCellResult = mTelephonyManager.getNeighboringCellInfo();
983 mHandler.post(updateAllCellInfoResults);
989 private final void updatePingState() {
990 // Set all to unknown since the threads will take a few secs to update.
991 mPingHostnameResultV4 = getResources().getString(R.string.radioInfo_unknown);
992 mPingHostnameResultV6 = getResources().getString(R.string.radioInfo_unknown);
993 mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
995 mPingHostnameV4.setText(mPingHostnameResultV4);
996 mPingHostnameV6.setText(mPingHostnameResultV6);
997 mHttpClientTest.setText(mHttpClientTestResult);
999 final Runnable updatePingResults = new Runnable() {
1001 mPingHostnameV4.setText(mPingHostnameResultV4);
1002 mPingHostnameV6.setText(mPingHostnameResultV6);
1003 mHttpClientTest.setText(mHttpClientTestResult);
1007 Thread hostname = new Thread() {
1011 mHandler.post(updatePingResults);
1016 Thread httpClient = new Thread() {
1020 mHandler.post(updatePingResults);
1026 private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() {
1027 public boolean onMenuItemClick(MenuItem item) {
1028 Intent intent = new Intent(Intent.ACTION_VIEW);
1029 // XXX We need to specify the component here because if we don't
1030 // the activity manager will try to resolve the type by calling
1031 // the content provider, which causes it to be loaded in a process
1032 // other than the Dialer process, which causes a lot of stuff to
1034 intent.setClassName("com.android.phone",
1035 "com.android.phone.SimContacts");
1036 startActivity(intent);
1041 private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() {
1042 public boolean onMenuItemClick(MenuItem item) {
1043 Intent intent = new Intent(Intent.ACTION_VIEW);
1044 // XXX We need to specify the component here because if we don't
1045 // the activity manager will try to resolve the type by calling
1046 // the content provider, which causes it to be loaded in a process
1047 // other than the Dialer process, which causes a lot of stuff to
1049 intent.setClassName("com.android.phone",
1050 "com.android.phone.settings.fdn.FdnList");
1051 startActivity(intent);
1056 private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() {
1057 public boolean onMenuItemClick(MenuItem item) {
1058 Intent intent = new Intent(
1059 Intent.ACTION_VIEW, Uri.parse("content://icc/sdn"));
1060 // XXX We need to specify the component here because if we don't
1061 // the activity manager will try to resolve the type by calling
1062 // the content provider, which causes it to be loaded in a process
1063 // other than the Dialer process, which causes a lot of stuff to
1065 intent.setClassName("com.android.phone",
1066 "com.android.phone.ADNList");
1067 startActivity(intent);
1072 private MenuItem.OnMenuItemClickListener mGetPdpList = new MenuItem.OnMenuItemClickListener() {
1073 public boolean onMenuItemClick(MenuItem item) {
1074 //FIXME: Replace with a TelephonyManager call
1075 phone.getDataCallList(null);
1080 private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() {
1081 public boolean onMenuItemClick(MenuItem item) {
1082 Intent intent = new Intent();
1083 intent.setClass(RadioInfo.this, BandMode.class);
1084 startActivity(intent);
1089 private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
1090 public boolean onMenuItemClick(MenuItem item) {
1091 int state = mTelephonyManager.getDataState();
1093 case TelephonyManager.DATA_CONNECTED:
1094 //FIXME: Replace with a TelephonyManager call
1095 phone.setDataEnabled(false);
1097 case TelephonyManager.DATA_DISCONNECTED:
1098 //FIXME: Replace with a TelephonyManager call
1099 phone.setDataEnabled(true);
1109 private boolean isRadioOn() {
1110 //FIXME: Replace with a TelephonyManager call
1111 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1114 private void updateRadioPowerState() {
1115 //delightful hack to prevent on-checked-changed calls from
1116 //actually forcing the radio preference to its transient/current value.
1117 radioPowerOnSwitch.setOnCheckedChangeListener(null);
1118 radioPowerOnSwitch.setChecked(isRadioOn());
1119 radioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
1122 void setImsVolteProvisionedState( boolean state ) {
1123 Log.d(TAG, "setImsVolteProvisioned state: " + ((state)? "on":"off"));
1124 setImsConfigProvisionedState( IMS_VOLTE_PROVISIONED_CONFIG_ID, state );
1127 void setImsVtProvisionedState( boolean state ) {
1128 Log.d(TAG, "setImsVtProvisioned() state: " + ((state)? "on":"off"));
1129 setImsConfigProvisionedState( IMS_VT_PROVISIONED_CONFIG_ID, state );
1132 void setImsWfcProvisionedState( boolean state ) {
1133 Log.d(TAG, "setImsWfcProvisioned() state: " + ((state)? "on":"off"));
1134 setImsConfigProvisionedState( IMS_WFC_PROVISIONED_CONFIG_ID, state );
1137 void setImsConfigProvisionedState( int configItem, boolean state ) {
1138 if (phone != null && mImsManager != null) {
1139 QueuedWork.singleThreadExecutor().submit(new Runnable() {
1142 mImsManager.getConfigInterface().setProvisionedValue(
1145 } catch (ImsException e) {
1146 Log.e(TAG, "setImsConfigProvisioned() exception:", e);
1153 OnCheckedChangeListener mRadioPowerOnChangeListener = new OnCheckedChangeListener() {
1155 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1156 log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
1157 phone.setRadioPower(isChecked);
1161 private boolean isImsVolteProvisioned() {
1162 if (phone != null && mImsManager != null) {
1163 return mImsManager.isVolteEnabledByPlatform(phone.getContext())
1164 && mImsManager.isVolteProvisionedOnDevice(phone.getContext());
1169 OnCheckedChangeListener mImsVolteCheckedChangeListener = new OnCheckedChangeListener() {
1171 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1172 setImsVolteProvisionedState(isChecked);
1176 private boolean isImsVtProvisioned() {
1177 if (phone != null && mImsManager != null) {
1178 return mImsManager.isVtEnabledByPlatform(phone.getContext())
1179 && mImsManager.isVtProvisionedOnDevice(phone.getContext());
1184 OnCheckedChangeListener mImsVtCheckedChangeListener = new OnCheckedChangeListener() {
1186 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1187 setImsVtProvisionedState(isChecked);
1191 private boolean isImsWfcProvisioned() {
1192 if (phone != null && mImsManager != null) {
1193 return mImsManager.isWfcEnabledByPlatform(phone.getContext())
1194 && mImsManager.isWfcProvisionedOnDevice(phone.getContext());
1199 OnCheckedChangeListener mImsWfcCheckedChangeListener = new OnCheckedChangeListener() {
1201 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1202 setImsWfcProvisionedState(isChecked);
1206 private void updateImsProvisionedState() {
1207 log("updateImsProvisionedState isImsVolteProvisioned()=" + isImsVolteProvisioned());
1208 //delightful hack to prevent on-checked-changed calls from
1209 //actually forcing the ims provisioning to its transient/current value.
1210 imsVolteProvisionedSwitch.setOnCheckedChangeListener(null);
1211 imsVolteProvisionedSwitch.setChecked(isImsVolteProvisioned());
1212 imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
1214 imsVtProvisionedSwitch.setOnCheckedChangeListener(null);
1215 imsVtProvisionedSwitch.setChecked(isImsVtProvisioned());
1216 imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
1218 imsWfcProvisionedSwitch.setOnCheckedChangeListener(null);
1219 imsWfcProvisionedSwitch.setChecked(isImsWfcProvisioned());
1220 imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
1223 OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
1224 public void onClick(View v) {
1225 //FIXME: Replace with a TelephonyManager call
1226 phone.disableDnsCheck(!phone.isDnsCheckDisabled());
1227 updateDnsCheckState();
1231 OnClickListener mOemInfoButtonHandler = new OnClickListener() {
1232 public void onClick(View v) {
1233 Intent intent = new Intent("com.android.settings.OEM_RADIO_INFO");
1235 startActivity(intent);
1236 } catch (android.content.ActivityNotFoundException ex) {
1237 log("OEM-specific Info/Settings Activity Not Found : " + ex);
1238 // If the activity does not exist, there are no OEM
1239 // settings, and so we can just do nothing...
1244 OnClickListener mPingButtonHandler = new OnClickListener() {
1245 public void onClick(View v) {
1250 OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
1251 public void onClick(View v) {
1252 updateSmscButton.setEnabled(false);
1253 phone.setSmscAddress(smsc.getText().toString(),
1254 mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
1258 OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
1259 public void onClick(View v) {
1264 AdapterView.OnItemSelectedListener mPreferredNetworkHandler =
1265 new AdapterView.OnItemSelectedListener() {
1267 public void onItemSelected(AdapterView parent, View v, int pos, long id) {
1268 if (mPreferredNetworkTypeResult != pos && pos >= 0
1269 && pos <= mPreferredNetworkLabels.length - 2) {
1270 mPreferredNetworkTypeResult = pos;
1271 Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
1272 phone.setPreferredNetworkType(mPreferredNetworkTypeResult, msg);
1276 public void onNothingSelected(AdapterView parent) {
1280 AdapterView.OnItemSelectedListener mCellInfoRefreshRateHandler =
1281 new AdapterView.OnItemSelectedListener() {
1283 public void onItemSelected(AdapterView parent, View v, int pos, long id) {
1284 mCellInfoRefreshRateIndex = pos;
1285 phone.setCellInfoListRate(mCellInfoRefreshRates[pos]);
1286 updateAllCellInfo();
1289 public void onNothingSelected(AdapterView parent) {