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.AlertDialog;
21 import android.app.Dialog;
22 import android.app.QueuedWork;
23 import android.content.Intent;
24 import android.content.pm.PackageManager;
25 import android.content.pm.ResolveInfo;
26 import android.content.res.Resources;
27 import android.graphics.Typeface;
28 import android.net.TrafficStats;
29 import android.net.Uri;
30 import android.os.AsyncResult;
31 import android.os.Bundle;
32 import android.os.Handler;
33 import android.os.Message;
34 import android.telephony.CellInfo;
35 import android.telephony.CellInfoCdma;
36 import android.telephony.CellInfoGsm;
37 import android.telephony.CellInfoLte;
38 import android.telephony.CellInfoWcdma;
39 import android.telephony.CellIdentityCdma;
40 import android.telephony.CellIdentityGsm;
41 import android.telephony.CellIdentityLte;
42 import android.telephony.CellIdentityWcdma;
43 import android.telephony.CellLocation;
44 import android.telephony.CellSignalStrengthCdma;
45 import android.telephony.CellSignalStrengthGsm;
46 import android.telephony.CellSignalStrengthLte;
47 import android.telephony.CellSignalStrengthWcdma;
48 import android.telephony.DataConnectionRealTimeInfo;
49 import android.telephony.NeighboringCellInfo;
50 import android.telephony.PreciseCallState;
51 import android.telephony.PhoneStateListener;
52 import android.telephony.ServiceState;
53 import android.telephony.SignalStrength;
54 import android.telephony.SubscriptionManager;
55 import android.telephony.TelephonyManager;
56 import android.telephony.cdma.CdmaCellLocation;
57 import android.telephony.gsm.GsmCellLocation;
58 import android.util.Log;
59 import android.view.Menu;
60 import android.view.MenuItem;
61 import android.view.View;
62 import android.view.View.OnClickListener;
63 import android.widget.AdapterView;
64 import android.widget.ArrayAdapter;
65 import android.widget.Button;
66 import android.widget.CompoundButton;
67 import android.widget.CompoundButton.OnCheckedChangeListener;
68 import android.widget.EditText;
69 import android.widget.Spinner;
70 import android.widget.Switch;
71 import android.widget.TextView;
73 import com.android.ims.ImsConfig;
74 import com.android.ims.ImsException;
75 import com.android.ims.ImsManager;
76 import com.android.internal.telephony.Phone;
77 import com.android.internal.telephony.PhoneConstants;
78 import com.android.internal.telephony.PhoneFactory;
79 import com.android.internal.telephony.RILConstants;
80 import com.android.internal.telephony.TelephonyProperties;
82 import java.io.IOException;
83 import java.net.HttpURLConnection;
85 import java.net.UnknownHostException;
86 import java.util.ArrayList;
87 import java.util.List;
89 public class RadioInfo extends Activity {
90 private static final String TAG = "RadioInfo";
92 private static final String[] mPreferredNetworkLabels = {
101 "LTE/CDMA auto (PRL)",
102 "LTE/UMTS auto (PRL)",
103 "LTE/CDMA/UMTS auto (PRL)",
111 "LTE/TD-SCDMA/WCDMA",
113 "TD-SCDMA/CDMA/UMTS",
119 private static final int CELL_INFO_LIST_RATE_DISABLED = Integer.MAX_VALUE;
120 private static final int CELL_INFO_LIST_RATE_MAX = 0;
123 private static final int IMS_VOLTE_PROVISIONED_CONFIG_ID =
124 ImsConfig.ConfigConstants.VLT_SETTING_ENABLED;
126 private static final int IMS_VT_PROVISIONED_CONFIG_ID =
127 ImsConfig.ConfigConstants.LVC_SETTING_ENABLED;
129 private static final int IMS_WFC_PROVISIONED_CONFIG_ID =
130 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED;
132 //Values in must match mCellInfoRefreshRates
133 private static final String[] mCellInfoRefreshRateLabels = {
141 //Values in seconds, must match mCellInfoRefreshRateLabels
142 private static final int mCellInfoRefreshRates[] = {
143 CELL_INFO_LIST_RATE_DISABLED,
144 CELL_INFO_LIST_RATE_MAX,
150 private void log(String s) {
154 private static final int EVENT_CFI_CHANGED = 302;
156 private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
157 private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
158 private static final int EVENT_QUERY_SMSC_DONE = 1005;
159 private static final int EVENT_UPDATE_SMSC_DONE = 1006;
161 private static final int MENU_ITEM_SELECT_BAND = 0;
162 private static final int MENU_ITEM_VIEW_ADN = 1;
163 private static final int MENU_ITEM_VIEW_FDN = 2;
164 private static final int MENU_ITEM_VIEW_SDN = 3;
165 private static final int MENU_ITEM_GET_IMS_STATUS = 4;
166 private static final int MENU_ITEM_TOGGLE_DATA = 5;
168 private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
169 private TextView number;
170 private TextView callState;
171 private TextView operatorName;
172 private TextView roamingState;
173 private TextView gsmState;
174 private TextView gprsState;
175 private TextView voiceNetwork;
176 private TextView dataNetwork;
177 private TextView dBm;
178 private TextView mMwi;
179 private TextView mCfi;
180 private TextView mLocation;
181 private TextView mNeighboringCids;
182 private TextView mCellInfo;
183 private TextView mDcRtInfoTv;
184 private TextView sent;
185 private TextView received;
186 private TextView mPingHostnameV4;
187 private TextView mPingHostnameV6;
188 private TextView mHttpClientTest;
189 private TextView dnsCheckState;
190 private EditText smsc;
191 private Switch radioPowerOnSwitch;
192 private Button cellInfoRefreshRateButton;
193 private Button dnsCheckToggleButton;
194 private Button pingTestButton;
195 private Button updateSmscButton;
196 private Button refreshSmscButton;
197 private Button oemInfoButton;
198 private Switch imsVolteProvisionedSwitch;
199 private Switch imsVtProvisionedSwitch;
200 private Switch imsWfcProvisionedSwitch;
201 private Spinner preferredNetworkType;
202 private Spinner cellInfoRefreshRateSpinner;
204 private TelephonyManager mTelephonyManager;
205 private ImsManager mImsManager = null;
206 private Phone phone = null;
208 private String mPingHostnameResultV4;
209 private String mPingHostnameResultV6;
210 private String mHttpClientTestResult;
211 private boolean mMwiValue = false;
212 private boolean mCfiValue = false;
214 private List<CellInfo> mCellInfoResult = null;
215 private CellLocation mCellLocationResult = null;
216 private List<NeighboringCellInfo> mNeighboringCellResult = null;
218 private int mPreferredNetworkTypeResult;
219 private int mCellInfoRefreshRateIndex;
221 private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
223 public void onDataConnectionStateChanged(int state) {
229 public void onDataActivity(int direction) {
234 public void onCallStateChanged(int state, String incomingNumber) {
236 updatePhoneState(state);
240 public void onPreciseCallStateChanged(PreciseCallState preciseState) {
245 public void onCellLocationChanged(CellLocation location) {
246 updateLocation(location);
250 public void onMessageWaitingIndicatorChanged(boolean mwi) {
252 updateMessageWaiting();
256 public void onCallForwardingIndicatorChanged(boolean cfi) {
258 updateCallRedirect();
262 public void onCellInfoChanged(List<CellInfo> arrayCi) {
263 log("onCellInfoChanged: arrayCi=" + arrayCi);
264 mCellInfoResult = arrayCi;
265 updateCellInfo(mCellInfoResult);
269 public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) {
270 log("onDataConnectionRealTimeInfoChanged: dcRtInfo=" + dcRtInfo);
271 updateDcRtInfoTv(dcRtInfo);
275 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
276 log("onSignalStrengthChanged: SignalStrength=" +signalStrength);
277 updateSignalStrength(signalStrength);
281 public void onServiceStateChanged(ServiceState serviceState) {
282 log("onServiceStateChanged: ServiceState=" + serviceState);
283 updateServiceState(serviceState);
284 updateRadioPowerState();
286 updateImsProvisionedState();
290 private void updatePreferredNetworkType(int type) {
291 if (type >= mPreferredNetworkLabels.length || type < 0) {
292 log("EVENT_QUERY_PREFERRED_TYPE_DONE: unknown " +
294 type = mPreferredNetworkLabels.length - 1; //set to Unknown
296 mPreferredNetworkTypeResult = type;
298 preferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
301 private Handler mHandler = new Handler() {
303 public void handleMessage(Message msg) {
306 case EVENT_QUERY_PREFERRED_TYPE_DONE:
307 ar= (AsyncResult) msg.obj;
308 if (ar.exception == null && ar.result != null) {
309 updatePreferredNetworkType(((int[])ar.result)[0]);
311 //In case of an exception, we will set this to unknown
312 updatePreferredNetworkType(mPreferredNetworkLabels.length-1);
315 case EVENT_SET_PREFERRED_TYPE_DONE:
316 ar= (AsyncResult) msg.obj;
317 if (ar.exception != null) {
318 log("Set preferred network type failed.");
321 case EVENT_QUERY_SMSC_DONE:
322 ar= (AsyncResult) msg.obj;
323 if (ar.exception != null) {
324 smsc.setText("refresh error");
326 smsc.setText((String)ar.result);
329 case EVENT_UPDATE_SMSC_DONE:
330 updateSmscButton.setEnabled(true);
331 ar= (AsyncResult) msg.obj;
332 if (ar.exception != null) {
333 smsc.setText("update error");
337 super.handleMessage(msg);
345 public void onCreate(Bundle icicle) {
346 super.onCreate(icicle);
347 if (!android.os.Process.myUserHandle().isSystem()) {
348 Log.e(TAG, "Not run from system user, don't do anything.");
353 setContentView(R.layout.radio_info);
355 log("Started onCreate");
357 mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
358 phone = PhoneFactory.getDefaultPhone();
360 //TODO: Need to update this if the default phoneId changes?
361 // Better to have an instance per phone?
362 mImsManager = ImsManager.getInstance(getApplicationContext(),
363 SubscriptionManager.getDefaultVoicePhoneId());
365 mDeviceId= (TextView) findViewById(R.id.imei);
366 number = (TextView) findViewById(R.id.number);
367 callState = (TextView) findViewById(R.id.call);
368 operatorName = (TextView) findViewById(R.id.operator);
369 roamingState = (TextView) findViewById(R.id.roaming);
370 gsmState = (TextView) findViewById(R.id.gsm);
371 gprsState = (TextView) findViewById(R.id.gprs);
372 voiceNetwork = (TextView) findViewById(R.id.voice_network);
373 dataNetwork = (TextView) findViewById(R.id.data_network);
374 dBm = (TextView) findViewById(R.id.dbm);
375 mMwi = (TextView) findViewById(R.id.mwi);
376 mCfi = (TextView) findViewById(R.id.cfi);
377 mLocation = (TextView) findViewById(R.id.location);
378 mNeighboringCids = (TextView) findViewById(R.id.neighboring);
379 mCellInfo = (TextView) findViewById(R.id.cellinfo);
380 mCellInfo.setTypeface(Typeface.MONOSPACE);
381 mDcRtInfoTv = (TextView) findViewById(R.id.dcrtinfo);
383 sent = (TextView) findViewById(R.id.sent);
384 received = (TextView) findViewById(R.id.received);
385 smsc = (EditText) findViewById(R.id.smsc);
386 dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
387 mPingHostnameV4 = (TextView) findViewById(R.id.pingHostnameV4);
388 mPingHostnameV6 = (TextView) findViewById(R.id.pingHostnameV6);
389 mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
391 preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
392 ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
393 android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
394 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
395 preferredNetworkType.setAdapter(adapter);
397 cellInfoRefreshRateSpinner = (Spinner) findViewById(R.id.cell_info_rate_select);
398 ArrayAdapter<String> cellInfoAdapter = new ArrayAdapter<String>(this,
399 android.R.layout.simple_spinner_item, mCellInfoRefreshRateLabels);
400 cellInfoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
401 cellInfoRefreshRateSpinner.setAdapter(cellInfoAdapter);
403 imsVolteProvisionedSwitch = (Switch) findViewById(R.id.volte_provisioned_switch);
404 imsVtProvisionedSwitch = (Switch) findViewById(R.id.vt_provisioned_switch);
405 imsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
407 radioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
409 pingTestButton = (Button) findViewById(R.id.ping_test);
410 pingTestButton.setOnClickListener(mPingButtonHandler);
411 updateSmscButton = (Button) findViewById(R.id.update_smsc);
412 updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
413 refreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
414 refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
415 dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
416 dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
418 oemInfoButton = (Button) findViewById(R.id.oem_info);
419 oemInfoButton.setOnClickListener(mOemInfoButtonHandler);
420 PackageManager pm = getPackageManager();
421 Intent oemInfoIntent = new Intent("com.android.settings.OEM_RADIO_INFO");
422 List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0);
423 if (oemInfoIntentList.size() == 0) {
424 oemInfoButton.setEnabled(false);
427 mCellInfoRefreshRateIndex = 0; //disabled
428 mPreferredNetworkTypeResult = mPreferredNetworkLabels.length - 1; //Unknown
430 //FIXME: Replace with TelephonyManager call
431 phone.getPreferredNetworkType(
432 mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
434 restoreFromBundle(icicle);
438 protected void onResume() {
441 log("Started onResume");
443 updateMessageWaiting();
444 updateCallRedirect();
447 updateRadioPowerState();
448 updateImsProvisionedState();
450 updateDnsCheckState();
453 updateNeighboringCids(mNeighboringCellResult);
454 updateLocation(mCellLocationResult);
455 updateCellInfo(mCellInfoResult);
457 mPingHostnameV4.setText(mPingHostnameResultV4);
458 mPingHostnameV6.setText(mPingHostnameResultV6);
459 mHttpClientTest.setText(mHttpClientTestResult);
461 cellInfoRefreshRateSpinner.setOnItemSelectedListener(mCellInfoRefreshRateHandler);
462 //set selection after registering listener to force update
463 cellInfoRefreshRateSpinner.setSelection(mCellInfoRefreshRateIndex);
465 //set selection before registering to prevent update
466 preferredNetworkType.setSelection(mPreferredNetworkTypeResult, true);
467 preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
469 radioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
470 imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
471 imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
472 imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
474 mTelephonyManager.listen(mPhoneStateListener,
475 PhoneStateListener.LISTEN_CALL_STATE
476 //b/27803938 - RadioInfo currently cannot read PRECISE_CALL_STATE
477 // | PhoneStateListener.LISTEN_PRECISE_CALL_STATE
478 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
479 | PhoneStateListener.LISTEN_DATA_ACTIVITY
480 | PhoneStateListener.LISTEN_CELL_LOCATION
481 | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
482 | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
483 | PhoneStateListener.LISTEN_CELL_INFO
484 | PhoneStateListener.LISTEN_SERVICE_STATE
485 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
486 | PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO);
492 protected void onPause() {
495 log("onPause: unregister phone & data intents");
497 mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
498 mTelephonyManager.setCellInfoListRate(CELL_INFO_LIST_RATE_DISABLED);
501 private void restoreFromBundle(Bundle b) {
506 mPingHostnameResultV4 = b.getString("mPingHostnameResultV4","");
507 mPingHostnameResultV6 = b.getString("mPingHostnameResultV6","");
508 mHttpClientTestResult = b.getString("mHttpClientTestResult","");
510 mPingHostnameV4.setText(mPingHostnameResultV4);
511 mPingHostnameV6.setText(mPingHostnameResultV6);
512 mHttpClientTest.setText(mHttpClientTestResult);
514 mPreferredNetworkTypeResult = b.getInt("mPreferredNetworkTypeResult",
515 mPreferredNetworkLabels.length - 1);
517 mCellInfoRefreshRateIndex = b.getInt("mCellInfoRefreshRateIndex", 0);
521 protected void onSaveInstanceState(Bundle outState) {
522 outState.putString("mPingHostnameResultV4", mPingHostnameResultV4);
523 outState.putString("mPingHostnameResultV6", mPingHostnameResultV6);
524 outState.putString("mHttpClientTestResult", mHttpClientTestResult);
526 outState.putInt("mPreferredNetworkTypeResult", mPreferredNetworkTypeResult);
527 outState.putInt("mCellInfoRefreshRateIndex", mCellInfoRefreshRateIndex);
532 public boolean onCreateOptionsMenu(Menu menu) {
533 menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label)
534 .setOnMenuItemClickListener(mSelectBandCallback)
535 .setAlphabeticShortcut('b');
536 menu.add(1, MENU_ITEM_VIEW_ADN, 0,
537 R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
538 menu.add(1, MENU_ITEM_VIEW_FDN, 0,
539 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
540 menu.add(1, MENU_ITEM_VIEW_SDN, 0,
541 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
542 menu.add(1, MENU_ITEM_GET_IMS_STATUS,
543 0, R.string.radioInfo_menu_getIMS).setOnMenuItemClickListener(mGetImsStatus);
544 menu.add(1, MENU_ITEM_TOGGLE_DATA,
545 0, R.string.radio_info_data_connection_disable).setOnMenuItemClickListener(mToggleData);
550 public boolean onPrepareOptionsMenu(Menu menu) {
551 // Get the TOGGLE DATA menu item in the right state.
552 MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
553 int state = mTelephonyManager.getDataState();
554 boolean visible = true;
557 case TelephonyManager.DATA_CONNECTED:
558 case TelephonyManager.DATA_SUSPENDED:
559 item.setTitle(R.string.radio_info_data_connection_disable);
561 case TelephonyManager.DATA_DISCONNECTED:
562 item.setTitle(R.string.radio_info_data_connection_enable);
568 item.setVisible(visible);
572 private void updateDnsCheckState() {
573 //FIXME: Replace with a TelephonyManager call
574 dnsCheckState.setText(phone.isDnsCheckDisabled() ?
575 "0.0.0.0 allowed" :"0.0.0.0 not allowed");
579 updateSignalStrength(SignalStrength signalStrength) {
580 Resources r = getResources();
582 int signalDbm = signalStrength.getDbm();
584 int signalAsu = signalStrength.getAsuLevel();
586 if (-1 == signalAsu) signalAsu = 0;
588 dBm.setText(String.valueOf(signalDbm) + " "
589 + r.getString(R.string.radioInfo_display_dbm) + " "
590 + String.valueOf(signalAsu) + " "
591 + r.getString(R.string.radioInfo_display_asu));
594 private final void updateLocation(CellLocation location) {
595 Resources r = getResources();
596 if (location instanceof GsmCellLocation) {
597 GsmCellLocation loc = (GsmCellLocation)location;
598 int lac = loc.getLac();
599 int cid = loc.getCid();
600 mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
601 + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
603 + r.getString(R.string.radioInfo_cid) + " = "
604 + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
605 } else if (location instanceof CdmaCellLocation) {
606 CdmaCellLocation loc = (CdmaCellLocation)location;
607 int bid = loc.getBaseStationId();
608 int sid = loc.getSystemId();
609 int nid = loc.getNetworkId();
610 int lat = loc.getBaseStationLatitude();
611 int lon = loc.getBaseStationLongitude();
612 mLocation.setText("BID = "
613 + ((bid == -1) ? "unknown" : Integer.toHexString(bid))
616 + ((sid == -1) ? "unknown" : Integer.toHexString(sid))
619 + ((nid == -1) ? "unknown" : Integer.toHexString(nid))
622 + ((lat == -1) ? "unknown" : Integer.toHexString(lat))
625 + ((lon == -1) ? "unknown" : Integer.toHexString(lon)));
627 mLocation.setText("unknown");
633 private final void updateNeighboringCids(List<NeighboringCellInfo> cids) {
634 StringBuilder sb = new StringBuilder();
637 if (cids.isEmpty()) {
638 sb.append("no neighboring cells");
640 for (NeighboringCellInfo cell : cids) {
641 sb.append(cell.toString()).append(" ");
645 sb.append("unknown");
647 mNeighboringCids.setText(sb.toString());
650 private final String getCellInfoDisplayString(int i) {
651 return (i != Integer.MAX_VALUE) ? Integer.toString(i) : "";
654 private final String getCellInfoDisplayString(long i) {
655 return (i != Long.MAX_VALUE) ? Long.toString(i) : "";
658 private final String buildCdmaInfoString(CellInfoCdma ci) {
659 CellIdentityCdma cidCdma = ci.getCellIdentity();
660 CellSignalStrengthCdma ssCdma = ci.getCellSignalStrength();
662 return String.format("%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s",
663 ci.isRegistered() ? "S " : " ",
664 getCellInfoDisplayString(cidCdma.getSystemId()),
665 getCellInfoDisplayString(cidCdma.getNetworkId()),
666 getCellInfoDisplayString(cidCdma.getBasestationId()),
667 getCellInfoDisplayString(ssCdma.getCdmaDbm()),
668 getCellInfoDisplayString(ssCdma.getCdmaEcio()),
669 getCellInfoDisplayString(ssCdma.getEvdoDbm()),
670 getCellInfoDisplayString(ssCdma.getEvdoEcio()),
671 getCellInfoDisplayString(ssCdma.getEvdoSnr()));
674 private final String buildGsmInfoString(CellInfoGsm ci) {
675 CellIdentityGsm cidGsm = ci.getCellIdentity();
676 CellSignalStrengthGsm ssGsm = ci.getCellSignalStrength();
678 return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
679 ci.isRegistered() ? "S " : " ",
680 getCellInfoDisplayString(cidGsm.getMcc()),
681 getCellInfoDisplayString(cidGsm.getMnc()),
682 getCellInfoDisplayString(cidGsm.getLac()),
683 getCellInfoDisplayString(cidGsm.getCid()),
684 getCellInfoDisplayString(cidGsm.getArfcn()),
685 getCellInfoDisplayString(cidGsm.getBsic()),
686 getCellInfoDisplayString(ssGsm.getDbm()));
689 private final String buildLteInfoString(CellInfoLte ci) {
690 CellIdentityLte cidLte = ci.getCellIdentity();
691 CellSignalStrengthLte ssLte = ci.getCellSignalStrength();
693 return String.format(
694 "%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s %-2.2s\n",
695 ci.isRegistered() ? "S " : " ",
696 getCellInfoDisplayString(cidLte.getMcc()),
697 getCellInfoDisplayString(cidLte.getMnc()),
698 getCellInfoDisplayString(cidLte.getTac()),
699 getCellInfoDisplayString(cidLte.getCi()),
700 getCellInfoDisplayString(cidLte.getPci()),
701 getCellInfoDisplayString(cidLte.getEarfcn()),
702 getCellInfoDisplayString(ssLte.getDbm()),
703 getCellInfoDisplayString(ssLte.getRsrq()),
704 getCellInfoDisplayString(ssLte.getTimingAdvance()));
707 private final String buildWcdmaInfoString(CellInfoWcdma ci) {
708 CellIdentityWcdma cidWcdma = ci.getCellIdentity();
709 CellSignalStrengthWcdma ssWcdma = ci.getCellSignalStrength();
711 return String.format("%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
712 ci.isRegistered() ? "S " : " ",
713 getCellInfoDisplayString(cidWcdma.getMcc()),
714 getCellInfoDisplayString(cidWcdma.getMnc()),
715 getCellInfoDisplayString(cidWcdma.getLac()),
716 getCellInfoDisplayString(cidWcdma.getCid()),
717 getCellInfoDisplayString(cidWcdma.getUarfcn()),
718 getCellInfoDisplayString(cidWcdma.getPsc()),
719 getCellInfoDisplayString(ssWcdma.getDbm()));
722 private final String buildCellInfoString(List<CellInfo> arrayCi) {
723 String value = new String();
724 StringBuilder cdmaCells = new StringBuilder(),
725 gsmCells = new StringBuilder(),
726 lteCells = new StringBuilder(),
727 wcdmaCells = new StringBuilder();
729 if (arrayCi != null) {
730 for (CellInfo ci : arrayCi) {
732 if (ci instanceof CellInfoLte) {
733 lteCells.append(buildLteInfoString((CellInfoLte) ci));
734 } else if (ci instanceof CellInfoWcdma) {
735 wcdmaCells.append(buildWcdmaInfoString((CellInfoWcdma) ci));
736 } else if (ci instanceof CellInfoGsm) {
737 gsmCells.append(buildGsmInfoString((CellInfoGsm) ci));
738 } else if (ci instanceof CellInfoCdma) {
739 cdmaCells.append(buildCdmaInfoString((CellInfoCdma) ci));
742 if (lteCells.length() != 0) {
743 value += String.format(
744 "LTE\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-3.3s %-6.6s %-4.4s %-4.4s %-2.2s\n",
745 "SRV", "MCC", "MNC", "TAC", "CID", "PCI", "EARFCN", "RSRP", "RSRQ", "TA");
746 value += lteCells.toString();
748 if (wcdmaCells.length() != 0) {
749 value += String.format("WCDMA\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-3.3s %-4.4s\n",
750 "SRV", "MCC", "MNC", "LAC", "CID", "UARFCN", "PSC", "RSCP");
751 value += wcdmaCells.toString();
753 if (gsmCells.length() != 0) {
754 value += String.format("GSM\n%-3.3s %-3.3s %-3.3s %-5.5s %-5.5s %-6.6s %-4.4s %-4.4s\n",
755 "SRV", "MCC", "MNC", "LAC", "CID", "ARFCN", "BSIC", "RSSI");
756 value += gsmCells.toString();
758 if (cdmaCells.length() != 0) {
759 value += String.format(
760 "CDMA/EVDO\n%-3.3s %-5.5s %-5.5s %-5.5s %-6.6s %-6.6s %-6.6s %-6.6s %-5.5s\n",
761 "SRV", "SID", "NID", "BSID", "C-RSSI", "C-ECIO", "E-RSSI", "E-ECIO", "E-SNR");
762 value += cdmaCells.toString();
768 return value.toString();
771 private final void updateCellInfo(List<CellInfo> arrayCi) {
772 mCellInfo.setText(buildCellInfoString(arrayCi));
775 private final void updateDcRtInfoTv(DataConnectionRealTimeInfo dcRtInfo) {
776 mDcRtInfoTv.setText(dcRtInfo.toString());
780 updateMessageWaiting() {
781 mMwi.setText(String.valueOf(mMwiValue));
785 updateCallRedirect() {
786 mCfi.setText(String.valueOf(mCfiValue));
791 updateServiceState(ServiceState serviceState) {
792 int state = serviceState.getState();
793 Resources r = getResources();
794 String display = r.getString(R.string.radioInfo_unknown);
797 case ServiceState.STATE_IN_SERVICE:
798 display = r.getString(R.string.radioInfo_service_in);
800 case ServiceState.STATE_OUT_OF_SERVICE:
801 case ServiceState.STATE_EMERGENCY_ONLY:
802 display = r.getString(R.string.radioInfo_service_emergency);
804 case ServiceState.STATE_POWER_OFF:
805 display = r.getString(R.string.radioInfo_service_off);
809 gsmState.setText(display);
811 if (serviceState.getRoaming()) {
812 roamingState.setText(R.string.radioInfo_roaming_in);
814 roamingState.setText(R.string.radioInfo_roaming_not);
817 operatorName.setText(serviceState.getOperatorAlphaLong());
821 updatePhoneState(int state) {
822 Resources r = getResources();
823 String display = r.getString(R.string.radioInfo_unknown);
826 case TelephonyManager.CALL_STATE_IDLE:
827 display = r.getString(R.string.radioInfo_phone_idle);
829 case TelephonyManager.CALL_STATE_RINGING:
830 display = r.getString(R.string.radioInfo_phone_ringing);
832 case TelephonyManager.CALL_STATE_OFFHOOK:
833 display = r.getString(R.string.radioInfo_phone_offhook);
837 callState.setText(display);
842 int state = mTelephonyManager.getDataState();
843 Resources r = getResources();
844 String display = r.getString(R.string.radioInfo_unknown);
847 case TelephonyManager.DATA_CONNECTED:
848 display = r.getString(R.string.radioInfo_data_connected);
850 case TelephonyManager.DATA_CONNECTING:
851 display = r.getString(R.string.radioInfo_data_connecting);
853 case TelephonyManager.DATA_DISCONNECTED:
854 display = r.getString(R.string.radioInfo_data_disconnected);
856 case TelephonyManager.DATA_SUSPENDED:
857 display = r.getString(R.string.radioInfo_data_suspended);
861 gprsState.setText(display);
864 private final void updateNetworkType() {
866 ServiceState ss = phone.getServiceState();
867 dataNetwork.setText(ServiceState.rilRadioTechnologyToString(
868 phone.getServiceState().getRilDataRadioTechnology()));
869 voiceNetwork.setText(ServiceState.rilRadioTechnologyToString(
870 phone.getServiceState().getRilVoiceRadioTechnology()));
877 Resources r = getResources();
879 s = phone.getDeviceId();
880 if (s == null) s = r.getString(R.string.radioInfo_unknown);
881 mDeviceId.setText(s);
883 //FIXME: Replace with a TelephonyManager call
884 s = phone.getLine1Number();
885 if (s == null) s = r.getString(R.string.radioInfo_unknown);
889 private final void updateDataStats2() {
890 Resources r = getResources();
892 long txPackets = TrafficStats.getMobileTxPackets();
893 long rxPackets = TrafficStats.getMobileRxPackets();
894 long txBytes = TrafficStats.getMobileTxBytes();
895 long rxBytes = TrafficStats.getMobileRxBytes();
897 String packets = r.getString(R.string.radioInfo_display_packets);
898 String bytes = r.getString(R.string.radioInfo_display_bytes);
900 sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
901 received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
907 private final void pingHostname() {
910 Process p4 = Runtime.getRuntime().exec("ping -c 1 www.google.com");
911 int status4 = p4.waitFor();
913 mPingHostnameResultV4 = "Pass";
915 mPingHostnameResultV4 = String.format("Fail(%d)", status4);
917 } catch (IOException e) {
918 mPingHostnameResultV4 = "Fail: IOException";
921 Process p6 = Runtime.getRuntime().exec("ping6 -c 1 www.google.com");
922 int status6 = p6.waitFor();
924 mPingHostnameResultV6 = "Pass";
926 mPingHostnameResultV6 = String.format("Fail(%d)", status6);
928 } catch (IOException e) {
929 mPingHostnameResultV6 = "Fail: IOException";
931 } catch (InterruptedException e) {
932 mPingHostnameResultV4 = mPingHostnameResultV6 = "Fail: InterruptedException";
937 * This function checks for basic functionality of HTTP Client.
939 private void httpClientTest() {
940 HttpURLConnection urlConnection = null;
942 // TODO: Hardcoded for now, make it UI configurable
943 URL url = new URL("https://www.google.com");
944 urlConnection = (HttpURLConnection) url.openConnection();
945 if (urlConnection.getResponseCode() == 200) {
946 mHttpClientTestResult = "Pass";
948 mHttpClientTestResult = "Fail: Code: " + urlConnection.getResponseMessage();
950 } catch (IOException e) {
951 mHttpClientTestResult = "Fail: IOException";
953 if (urlConnection != null) {
954 urlConnection.disconnect();
959 private void refreshSmsc() {
960 //FIXME: Replace with a TelephonyManager call
961 phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
964 private final void updateAllCellInfo() {
966 mCellInfo.setText("");
967 mNeighboringCids.setText("");
968 mLocation.setText("");
970 final Runnable updateAllCellInfoResults = new Runnable() {
972 updateNeighboringCids(mNeighboringCellResult);
973 updateLocation(mCellLocationResult);
974 updateCellInfo(mCellInfoResult);
978 Thread locThread = new Thread() {
981 mCellInfoResult = mTelephonyManager.getAllCellInfo();
982 mCellLocationResult = mTelephonyManager.getCellLocation();
983 mNeighboringCellResult = mTelephonyManager.getNeighboringCellInfo();
985 mHandler.post(updateAllCellInfoResults);
991 private final void updatePingState() {
992 // Set all to unknown since the threads will take a few secs to update.
993 mPingHostnameResultV4 = getResources().getString(R.string.radioInfo_unknown);
994 mPingHostnameResultV6 = getResources().getString(R.string.radioInfo_unknown);
995 mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
997 mPingHostnameV4.setText(mPingHostnameResultV4);
998 mPingHostnameV6.setText(mPingHostnameResultV6);
999 mHttpClientTest.setText(mHttpClientTestResult);
1001 final Runnable updatePingResults = new Runnable() {
1003 mPingHostnameV4.setText(mPingHostnameResultV4);
1004 mPingHostnameV6.setText(mPingHostnameResultV6);
1005 mHttpClientTest.setText(mHttpClientTestResult);
1009 Thread hostname = new Thread() {
1013 mHandler.post(updatePingResults);
1018 Thread httpClient = new Thread() {
1022 mHandler.post(updatePingResults);
1028 private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() {
1029 public boolean onMenuItemClick(MenuItem item) {
1030 Intent intent = new Intent(Intent.ACTION_VIEW);
1031 // XXX We need to specify the component here because if we don't
1032 // the activity manager will try to resolve the type by calling
1033 // the content provider, which causes it to be loaded in a process
1034 // other than the Dialer process, which causes a lot of stuff to
1036 intent.setClassName("com.android.phone",
1037 "com.android.phone.SimContacts");
1038 startActivity(intent);
1043 private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() {
1044 public boolean onMenuItemClick(MenuItem item) {
1045 Intent intent = new Intent(Intent.ACTION_VIEW);
1046 // XXX We need to specify the component here because if we don't
1047 // the activity manager will try to resolve the type by calling
1048 // the content provider, which causes it to be loaded in a process
1049 // other than the Dialer process, which causes a lot of stuff to
1051 intent.setClassName("com.android.phone",
1052 "com.android.phone.settings.fdn.FdnList");
1053 startActivity(intent);
1058 private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() {
1059 public boolean onMenuItemClick(MenuItem item) {
1060 Intent intent = new Intent(
1061 Intent.ACTION_VIEW, Uri.parse("content://icc/sdn"));
1062 // XXX We need to specify the component here because if we don't
1063 // the activity manager will try to resolve the type by calling
1064 // the content provider, which causes it to be loaded in a process
1065 // other than the Dialer process, which causes a lot of stuff to
1067 intent.setClassName("com.android.phone",
1068 "com.android.phone.ADNList");
1069 startActivity(intent);
1074 private MenuItem.OnMenuItemClickListener mGetImsStatus = new MenuItem.OnMenuItemClickListener() {
1075 public boolean onMenuItemClick(MenuItem item) {
1076 boolean isImsRegistered = phone.isImsRegistered();
1077 boolean availableVolte = phone.isVolteEnabled();
1078 boolean availableWfc = phone.isWifiCallingEnabled();
1079 boolean availableVt = phone.isVideoEnabled();
1080 boolean availableUt = phone.isUtEnabled();
1082 final String imsRegString = isImsRegistered ?
1083 getString(R.string.radio_info_ims_reg_status_registered) :
1084 getString(R.string.radio_info_ims_reg_status_not_registered);
1086 final String available = getString(R.string.radio_info_ims_feature_status_available);
1087 final String unavailable = getString(
1088 R.string.radio_info_ims_feature_status_unavailable);
1090 String imsStatus = getString(R.string.radio_info_ims_reg_status,
1092 availableVolte ? available : unavailable,
1093 availableWfc ? available : unavailable,
1094 availableVt ? available : unavailable,
1095 availableUt ? available : unavailable);
1097 AlertDialog imsDialog = new AlertDialog.Builder(RadioInfo.this)
1098 .setMessage(imsStatus)
1099 .setTitle(getString(R.string.radio_info_ims_reg_status_title))
1108 private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() {
1109 public boolean onMenuItemClick(MenuItem item) {
1110 Intent intent = new Intent();
1111 intent.setClass(RadioInfo.this, BandMode.class);
1112 startActivity(intent);
1117 private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
1118 public boolean onMenuItemClick(MenuItem item) {
1119 int state = mTelephonyManager.getDataState();
1121 case TelephonyManager.DATA_CONNECTED:
1122 //FIXME: Replace with a TelephonyManager call
1123 phone.setDataEnabled(false);
1125 case TelephonyManager.DATA_DISCONNECTED:
1126 //FIXME: Replace with a TelephonyManager call
1127 phone.setDataEnabled(true);
1137 private boolean isRadioOn() {
1138 //FIXME: Replace with a TelephonyManager call
1139 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1142 private void updateRadioPowerState() {
1143 //delightful hack to prevent on-checked-changed calls from
1144 //actually forcing the radio preference to its transient/current value.
1145 radioPowerOnSwitch.setOnCheckedChangeListener(null);
1146 radioPowerOnSwitch.setChecked(isRadioOn());
1147 radioPowerOnSwitch.setOnCheckedChangeListener(mRadioPowerOnChangeListener);
1150 void setImsVolteProvisionedState(boolean state) {
1151 Log.d(TAG, "setImsVolteProvisioned state: " + ((state)? "on":"off"));
1152 setImsConfigProvisionedState(IMS_VOLTE_PROVISIONED_CONFIG_ID, state);
1155 void setImsVtProvisionedState(boolean state) {
1156 Log.d(TAG, "setImsVtProvisioned() state: " + ((state)? "on":"off"));
1157 setImsConfigProvisionedState(IMS_VT_PROVISIONED_CONFIG_ID, state);
1160 void setImsWfcProvisionedState(boolean state) {
1161 Log.d(TAG, "setImsWfcProvisioned() state: " + ((state)? "on":"off"));
1162 setImsConfigProvisionedState(IMS_WFC_PROVISIONED_CONFIG_ID, state);
1165 void setImsConfigProvisionedState(int configItem, boolean state) {
1166 if (phone != null && mImsManager != null) {
1167 QueuedWork.queue(new Runnable() {
1170 mImsManager.getConfigInterface().setProvisionedValue(
1173 } catch (ImsException e) {
1174 Log.e(TAG, "setImsConfigProvisioned() exception:", e);
1181 OnCheckedChangeListener mRadioPowerOnChangeListener = new OnCheckedChangeListener() {
1183 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1184 log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
1185 phone.setRadioPower(isChecked);
1189 private boolean isImsVolteProvisioned() {
1190 if (phone != null && mImsManager != null) {
1191 return mImsManager.isVolteEnabledByPlatform(phone.getContext())
1192 && mImsManager.isVolteProvisionedOnDevice(phone.getContext());
1197 OnCheckedChangeListener mImsVolteCheckedChangeListener = new OnCheckedChangeListener() {
1199 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1200 setImsVolteProvisionedState(isChecked);
1204 private boolean isImsVtProvisioned() {
1205 if (phone != null && mImsManager != null) {
1206 return mImsManager.isVtEnabledByPlatform(phone.getContext())
1207 && mImsManager.isVtProvisionedOnDevice(phone.getContext());
1212 OnCheckedChangeListener mImsVtCheckedChangeListener = new OnCheckedChangeListener() {
1214 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1215 setImsVtProvisionedState(isChecked);
1219 private boolean isImsWfcProvisioned() {
1220 if (phone != null && mImsManager != null) {
1221 return mImsManager.isWfcEnabledByPlatform(phone.getContext())
1222 && mImsManager.isWfcProvisionedOnDevice(phone.getContext());
1227 OnCheckedChangeListener mImsWfcCheckedChangeListener = new OnCheckedChangeListener() {
1229 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1230 setImsWfcProvisionedState(isChecked);
1234 private void updateImsProvisionedState() {
1235 log("updateImsProvisionedState isImsVolteProvisioned()=" + isImsVolteProvisioned());
1236 //delightful hack to prevent on-checked-changed calls from
1237 //actually forcing the ims provisioning to its transient/current value.
1238 imsVolteProvisionedSwitch.setOnCheckedChangeListener(null);
1239 imsVolteProvisionedSwitch.setChecked(isImsVolteProvisioned());
1240 imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
1241 imsVolteProvisionedSwitch.setEnabled(
1242 mImsManager.isVolteEnabledByPlatform(phone.getContext()));
1244 imsVtProvisionedSwitch.setOnCheckedChangeListener(null);
1245 imsVtProvisionedSwitch.setChecked(isImsVtProvisioned());
1246 imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
1247 imsVtProvisionedSwitch.setEnabled(
1248 mImsManager.isVtEnabledByPlatform(phone.getContext()));
1250 imsWfcProvisionedSwitch.setOnCheckedChangeListener(null);
1251 imsWfcProvisionedSwitch.setChecked(isImsWfcProvisioned());
1252 imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
1253 imsWfcProvisionedSwitch.setEnabled(
1254 mImsManager.isWfcEnabledByPlatform(phone.getContext()));
1257 OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
1258 public void onClick(View v) {
1259 //FIXME: Replace with a TelephonyManager call
1260 phone.disableDnsCheck(!phone.isDnsCheckDisabled());
1261 updateDnsCheckState();
1265 OnClickListener mOemInfoButtonHandler = new OnClickListener() {
1266 public void onClick(View v) {
1267 Intent intent = new Intent("com.android.settings.OEM_RADIO_INFO");
1269 startActivity(intent);
1270 } catch (android.content.ActivityNotFoundException ex) {
1271 log("OEM-specific Info/Settings Activity Not Found : " + ex);
1272 // If the activity does not exist, there are no OEM
1273 // settings, and so we can just do nothing...
1278 OnClickListener mPingButtonHandler = new OnClickListener() {
1279 public void onClick(View v) {
1284 OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
1285 public void onClick(View v) {
1286 updateSmscButton.setEnabled(false);
1287 phone.setSmscAddress(smsc.getText().toString(),
1288 mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
1292 OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
1293 public void onClick(View v) {
1298 AdapterView.OnItemSelectedListener mPreferredNetworkHandler =
1299 new AdapterView.OnItemSelectedListener() {
1301 public void onItemSelected(AdapterView parent, View v, int pos, long id) {
1302 if (mPreferredNetworkTypeResult != pos && pos >= 0
1303 && pos <= mPreferredNetworkLabels.length - 2) {
1304 mPreferredNetworkTypeResult = pos;
1305 Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
1306 phone.setPreferredNetworkType(mPreferredNetworkTypeResult, msg);
1310 public void onNothingSelected(AdapterView parent) {
1314 AdapterView.OnItemSelectedListener mCellInfoRefreshRateHandler =
1315 new AdapterView.OnItemSelectedListener() {
1317 public void onItemSelected(AdapterView parent, View v, int pos, long id) {
1318 mCellInfoRefreshRateIndex = pos;
1319 mTelephonyManager.setCellInfoListRate(mCellInfoRefreshRates[pos]);
1320 updateAllCellInfo();
1323 public void onNothingSelected(AdapterView parent) {