Files
app_Settings/src/com/android/settings/RadioInfo.java
Alex Klyubin b009023c76 Make Settings app not use cleartext network traffic.
This CL switches the only two places which use cleartext HTTP in this
app to HTTPS. It also declares in the AndroidManifest.xml that this
app does not use cleartext network traffic, thus asking the platform
and tools to block any such traffic from this app on best effort
basis.

NOTE: The only test that uses cleartext HTTP traffic is in VpnTests.
This test makes cleartext HTTP requests to a third-party service which
does not appear to support HTTPS. Thus, this CL temporarily relaxes
the cleartext traffic policy during this test to keep it working. The
correct longer-term fix for this test is to use a service that offers
HTTPS.

Bug: 19215516
Change-Id: Idf1ff8c66d43d77ef2114b2f1b676927844150e5
2015-04-02 11:30:15 -07:00

1163 lines
44 KiB
Java

/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.app.Activity;
import android.app.QueuedWork;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import android.telephony.CellInfo;
import android.telephony.CellLocation;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.NeighboringCellInfo;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.EditText;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.PhoneStateIntentReceiver;
import com.android.internal.telephony.TelephonyProperties;
import com.android.ims.ImsConfig;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
public class RadioInfo extends Activity {
private final String TAG = "phone";
private static final int EVENT_PHONE_STATE_CHANGED = 100;
private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
private static final int EVENT_SERVICE_STATE_CHANGED = 300;
private static final int EVENT_CFI_CHANGED = 302;
private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
private static final int EVENT_QUERY_NEIGHBORING_CIDS_DONE = 1002;
private static final int EVENT_QUERY_SMSC_DONE = 1005;
private static final int EVENT_UPDATE_SMSC_DONE = 1006;
private static final int MENU_ITEM_SELECT_BAND = 0;
private static final int MENU_ITEM_VIEW_ADN = 1;
private static final int MENU_ITEM_VIEW_FDN = 2;
private static final int MENU_ITEM_VIEW_SDN = 3;
private static final int MENU_ITEM_GET_PDP_LIST = 4;
private static final int MENU_ITEM_TOGGLE_DATA = 5;
static final String ENABLE_DATA_STR = "Enable data connection";
static final String DISABLE_DATA_STR = "Disable data connection";
private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
private TextView number;
private TextView callState;
private TextView operatorName;
private TextView roamingState;
private TextView gsmState;
private TextView gprsState;
private TextView network;
private TextView dBm;
private TextView mMwi;
private TextView mCfi;
private TextView mLocation;
private TextView mNeighboringCids;
private TextView mCellInfo;
private TextView mDcRtInfoTv;
private TextView resets;
private TextView attempts;
private TextView successes;
private TextView disconnects;
private TextView sentSinceReceived;
private TextView sent;
private TextView received;
private TextView mPingIpAddr;
private TextView mPingHostname;
private TextView mHttpClientTest;
private TextView dnsCheckState;
private EditText smsc;
private Button radioPowerButton;
private Button cellInfoListRateButton;
private Button dnsCheckToggleButton;
private Button pingTestButton;
private Button updateSmscButton;
private Button refreshSmscButton;
private Button oemInfoButton;
private Spinner preferredNetworkType;
private TelephonyManager mTelephonyManager;
private Phone phone = null;
private PhoneStateIntentReceiver mPhoneStateReceiver;
private String mPingIpAddrResult;
private String mPingHostnameResult;
private String mHttpClientTestResult;
private boolean mMwiValue = false;
private boolean mCfiValue = false;
private List<CellInfo> mCellInfoValue;
private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onDataConnectionStateChanged(int state) {
updateDataState();
updateDataStats();
updatePdpList();
updateNetworkType();
}
@Override
public void onDataActivity(int direction) {
updateDataStats2();
}
@Override
public void onCellLocationChanged(CellLocation location) {
updateLocation(location);
}
@Override
public void onMessageWaitingIndicatorChanged(boolean mwi) {
mMwiValue = mwi;
updateMessageWaiting();
}
@Override
public void onCallForwardingIndicatorChanged(boolean cfi) {
mCfiValue = cfi;
updateCallRedirect();
}
@Override
public void onCellInfoChanged(List<CellInfo> arrayCi) {
log("onCellInfoChanged: arrayCi=" + arrayCi);
updateCellInfoTv(arrayCi);
}
@Override
public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) {
log("onDataConnectionRealTimeInfoChanged: dcRtInfo=" + dcRtInfo);
updateDcRtInfoTv(dcRtInfo);
}
};
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
case EVENT_PHONE_STATE_CHANGED:
updatePhoneState();
break;
case EVENT_SIGNAL_STRENGTH_CHANGED:
updateSignalStrength();
break;
case EVENT_SERVICE_STATE_CHANGED:
updateServiceState();
updatePowerState();
updateImsVoLteProvisionedState();
break;
case EVENT_QUERY_PREFERRED_TYPE_DONE:
ar= (AsyncResult) msg.obj;
if (ar.exception == null) {
int type = ((int[])ar.result)[0];
if (type >= mPreferredNetworkLabels.length) {
log("EVENT_QUERY_PREFERRED_TYPE_DONE: unknown " +
"type=" + type);
type = mPreferredNetworkLabels.length - 1;
}
preferredNetworkType.setSelection(type, true);
} else {
preferredNetworkType.setSelection(mPreferredNetworkLabels.length - 1, true);
}
break;
case EVENT_SET_PREFERRED_TYPE_DONE:
ar= (AsyncResult) msg.obj;
if (ar.exception != null) {
phone.getPreferredNetworkType(
obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
}
break;
case EVENT_QUERY_NEIGHBORING_CIDS_DONE:
ar= (AsyncResult) msg.obj;
if (ar.exception == null) {
updateNeighboringCids((ArrayList<NeighboringCellInfo>)ar.result);
} else {
mNeighboringCids.setText("unknown");
}
break;
case EVENT_QUERY_SMSC_DONE:
ar= (AsyncResult) msg.obj;
if (ar.exception != null) {
smsc.setText("refresh error");
} else {
smsc.setText((String)ar.result);
}
break;
case EVENT_UPDATE_SMSC_DONE:
updateSmscButton.setEnabled(true);
ar= (AsyncResult) msg.obj;
if (ar.exception != null) {
smsc.setText("update error");
}
break;
default:
break;
}
}
};
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.radio_info);
mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
phone = PhoneFactory.getDefaultPhone();
mDeviceId= (TextView) findViewById(R.id.imei);
number = (TextView) findViewById(R.id.number);
callState = (TextView) findViewById(R.id.call);
operatorName = (TextView) findViewById(R.id.operator);
roamingState = (TextView) findViewById(R.id.roaming);
gsmState = (TextView) findViewById(R.id.gsm);
gprsState = (TextView) findViewById(R.id.gprs);
network = (TextView) findViewById(R.id.network);
dBm = (TextView) findViewById(R.id.dbm);
mMwi = (TextView) findViewById(R.id.mwi);
mCfi = (TextView) findViewById(R.id.cfi);
mLocation = (TextView) findViewById(R.id.location);
mNeighboringCids = (TextView) findViewById(R.id.neighboring);
mCellInfo = (TextView) findViewById(R.id.cellinfo);
mDcRtInfoTv = (TextView) findViewById(R.id.dcrtinfo);
resets = (TextView) findViewById(R.id.resets);
attempts = (TextView) findViewById(R.id.attempts);
successes = (TextView) findViewById(R.id.successes);
disconnects = (TextView) findViewById(R.id.disconnects);
sentSinceReceived = (TextView) findViewById(R.id.sentSinceReceived);
sent = (TextView) findViewById(R.id.sent);
received = (TextView) findViewById(R.id.received);
smsc = (EditText) findViewById(R.id.smsc);
dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
mPingIpAddr = (TextView) findViewById(R.id.pingIpAddr);
mPingHostname = (TextView) findViewById(R.id.pingHostname);
mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
preferredNetworkType.setAdapter(adapter);
preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
radioPowerButton = (Button) findViewById(R.id.radio_power);
radioPowerButton.setOnClickListener(mPowerButtonHandler);
cellInfoListRateButton = (Button) findViewById(R.id.cell_info_list_rate);
cellInfoListRateButton.setOnClickListener(mCellInfoListRateHandler);
imsRegRequiredButton = (Button) findViewById(R.id.ims_reg_required);
imsRegRequiredButton.setOnClickListener(mImsRegRequiredHandler);
imsVoLteProvisionedButton = (Button) findViewById(R.id.volte_provisioned_flag);
imsVoLteProvisionedButton.setOnClickListener(mImsVoLteProvisionedHandler);
smsOverImsButton = (Button) findViewById(R.id.sms_over_ims);
smsOverImsButton.setOnClickListener(mSmsOverImsHandler);
lteRamDumpButton = (Button) findViewById(R.id.lte_ram_dump);
lteRamDumpButton.setOnClickListener(mLteRamDumpHandler);
pingTestButton = (Button) findViewById(R.id.ping_test);
pingTestButton.setOnClickListener(mPingButtonHandler);
updateSmscButton = (Button) findViewById(R.id.update_smsc);
updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
refreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
oemInfoButton = (Button) findViewById(R.id.oem_info);
oemInfoButton.setOnClickListener(mOemInfoButtonHandler);
PackageManager pm = getPackageManager();
Intent oemInfoIntent = new Intent("com.android.settings.OEM_RADIO_INFO");
List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0);
if (oemInfoIntentList.size() == 0) {
oemInfoButton.setEnabled(false);
}
mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler);
mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED);
mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
mPhoneStateReceiver.notifyPhoneCallState(EVENT_PHONE_STATE_CHANGED);
phone.getPreferredNetworkType(
mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
phone.getNeighboringCids(
mHandler.obtainMessage(EVENT_QUERY_NEIGHBORING_CIDS_DONE));
CellLocation.requestLocationUpdate();
// Get current cell info
mCellInfoValue = mTelephonyManager.getAllCellInfo();
log("onCreate: mCellInfoValue=" + mCellInfoValue);
}
@Override
protected void onResume() {
super.onResume();
updatePhoneState();
updateSignalStrength();
updateMessageWaiting();
updateCallRedirect();
updateServiceState();
updateLocation(mTelephonyManager.getCellLocation());
updateDataState();
updateDataStats();
updateDataStats2();
updatePowerState();
updateCellInfoListRate();
updateImsRegRequiredState();
updateImsVoLteProvisionedState();
updateSmsOverImsState();
updateLteRamDumpState();
updateProperties();
updateDnsCheckState();
log("onResume: register phone & data intents");
mPhoneStateReceiver.registerIntent();
mTelephonyManager.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
| PhoneStateListener.LISTEN_DATA_ACTIVITY
| PhoneStateListener.LISTEN_CELL_LOCATION
| PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
| PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
| PhoneStateListener.LISTEN_CELL_INFO
| PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO);
}
@Override
public void onPause() {
super.onPause();
log("onPause: unregister phone & data intents");
mPhoneStateReceiver.unregisterIntent();
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label)
.setOnMenuItemClickListener(mSelectBandCallback)
.setAlphabeticShortcut('b');
menu.add(1, MENU_ITEM_VIEW_ADN, 0,
R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
menu.add(1, MENU_ITEM_VIEW_FDN, 0,
R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
menu.add(1, MENU_ITEM_VIEW_SDN, 0,
R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
menu.add(1, MENU_ITEM_GET_PDP_LIST,
0, R.string.radioInfo_menu_getPDP).setOnMenuItemClickListener(mGetPdpList);
menu.add(1, MENU_ITEM_TOGGLE_DATA,
0, DISABLE_DATA_STR).setOnMenuItemClickListener(mToggleData);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Get the TOGGLE DATA menu item in the right state.
MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
int state = mTelephonyManager.getDataState();
boolean visible = true;
switch (state) {
case TelephonyManager.DATA_CONNECTED:
case TelephonyManager.DATA_SUSPENDED:
item.setTitle(DISABLE_DATA_STR);
break;
case TelephonyManager.DATA_DISCONNECTED:
item.setTitle(ENABLE_DATA_STR);
break;
default:
visible = false;
break;
}
item.setVisible(visible);
return true;
}
private boolean isRadioOn() {
return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
}
private void updatePowerState() {
String buttonText = isRadioOn() ?
getString(R.string.turn_off_radio) :
getString(R.string.turn_on_radio);
radioPowerButton.setText(buttonText);
}
private void updateCellInfoListRate() {
cellInfoListRateButton.setText("CellInfoListRate " + mCellInfoListRateHandler.getRate());
updateCellInfoTv(mTelephonyManager.getAllCellInfo());
}
private void updateDnsCheckState() {
dnsCheckState.setText(phone.isDnsCheckDisabled() ?
"0.0.0.0 allowed" :"0.0.0.0 not allowed");
}
private final void
updateSignalStrength() {
// TODO PhoneStateIntentReceiver is deprecated and PhoneStateListener
// should probably used instead.
int state = mPhoneStateReceiver.getServiceState().getState();
Resources r = getResources();
if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
(ServiceState.STATE_POWER_OFF == state)) {
dBm.setText("0");
}
int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
if (-1 == signalDbm) signalDbm = 0;
int signalAsu = mPhoneStateReceiver.getSignalStrengthLevelAsu();
if (-1 == signalAsu) signalAsu = 0;
dBm.setText(String.valueOf(signalDbm) + " "
+ r.getString(R.string.radioInfo_display_dbm) + " "
+ String.valueOf(signalAsu) + " "
+ r.getString(R.string.radioInfo_display_asu));
}
private final void updateLocation(CellLocation location) {
Resources r = getResources();
if (location instanceof GsmCellLocation) {
GsmCellLocation loc = (GsmCellLocation)location;
int lac = loc.getLac();
int cid = loc.getCid();
mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
+ ((lac == -1) ? "unknown" : Integer.toHexString(lac))
+ " "
+ r.getString(R.string.radioInfo_cid) + " = "
+ ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
} else if (location instanceof CdmaCellLocation) {
CdmaCellLocation loc = (CdmaCellLocation)location;
int bid = loc.getBaseStationId();
int sid = loc.getSystemId();
int nid = loc.getNetworkId();
int lat = loc.getBaseStationLatitude();
int lon = loc.getBaseStationLongitude();
mLocation.setText("BID = "
+ ((bid == -1) ? "unknown" : Integer.toHexString(bid))
+ " "
+ "SID = "
+ ((sid == -1) ? "unknown" : Integer.toHexString(sid))
+ " "
+ "NID = "
+ ((nid == -1) ? "unknown" : Integer.toHexString(nid))
+ "\n"
+ "LAT = "
+ ((lat == -1) ? "unknown" : Integer.toHexString(lat))
+ " "
+ "LONG = "
+ ((lon == -1) ? "unknown" : Integer.toHexString(lon)));
} else {
mLocation.setText("unknown");
}
}
private final void updateNeighboringCids(ArrayList<NeighboringCellInfo> cids) {
StringBuilder sb = new StringBuilder();
if (cids != null) {
if ( cids.isEmpty() ) {
sb.append("no neighboring cells");
} else {
for (NeighboringCellInfo cell : cids) {
sb.append(cell.toString()).append(" ");
}
}
} else {
sb.append("unknown");
}
mNeighboringCids.setText(sb.toString());
}
private final void updateCellInfoTv(List<CellInfo> arrayCi) {
mCellInfoValue = arrayCi;
StringBuilder value = new StringBuilder();
if (mCellInfoValue != null) {
int index = 0;
for (CellInfo ci : mCellInfoValue) {
value.append('[');
value.append(index);
value.append("]=");
value.append(ci.toString());
if (++index < mCellInfoValue.size()) {
value.append("\n");
}
}
}
mCellInfo.setText(value.toString());
}
private final void updateDcRtInfoTv(DataConnectionRealTimeInfo dcRtInfo) {
mDcRtInfoTv.setText(dcRtInfo.toString());
}
private final void
updateMessageWaiting() {
mMwi.setText(String.valueOf(mMwiValue));
}
private final void
updateCallRedirect() {
mCfi.setText(String.valueOf(mCfiValue));
}
private final void
updateServiceState() {
ServiceState serviceState = mPhoneStateReceiver.getServiceState();
int state = serviceState.getState();
Resources r = getResources();
String display = r.getString(R.string.radioInfo_unknown);
switch (state) {
case ServiceState.STATE_IN_SERVICE:
display = r.getString(R.string.radioInfo_service_in);
break;
case ServiceState.STATE_OUT_OF_SERVICE:
case ServiceState.STATE_EMERGENCY_ONLY:
display = r.getString(R.string.radioInfo_service_emergency);
break;
case ServiceState.STATE_POWER_OFF:
display = r.getString(R.string.radioInfo_service_off);
break;
}
gsmState.setText(display);
if (serviceState.getRoaming()) {
roamingState.setText(R.string.radioInfo_roaming_in);
} else {
roamingState.setText(R.string.radioInfo_roaming_not);
}
operatorName.setText(serviceState.getOperatorAlphaLong());
}
private final void
updatePhoneState() {
PhoneConstants.State state = mPhoneStateReceiver.getPhoneState();
Resources r = getResources();
String display = r.getString(R.string.radioInfo_unknown);
switch (state) {
case IDLE:
display = r.getString(R.string.radioInfo_phone_idle);
break;
case RINGING:
display = r.getString(R.string.radioInfo_phone_ringing);
break;
case OFFHOOK:
display = r.getString(R.string.radioInfo_phone_offhook);
break;
}
callState.setText(display);
}
private final void
updateDataState() {
int state = mTelephonyManager.getDataState();
Resources r = getResources();
String display = r.getString(R.string.radioInfo_unknown);
switch (state) {
case TelephonyManager.DATA_CONNECTED:
display = r.getString(R.string.radioInfo_data_connected);
break;
case TelephonyManager.DATA_CONNECTING:
display = r.getString(R.string.radioInfo_data_connecting);
break;
case TelephonyManager.DATA_DISCONNECTED:
display = r.getString(R.string.radioInfo_data_disconnected);
break;
case TelephonyManager.DATA_SUSPENDED:
display = r.getString(R.string.radioInfo_data_suspended);
break;
}
gprsState.setText(display);
}
private final void updateNetworkType() {
Resources r = getResources();
String display = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
r.getString(R.string.radioInfo_unknown));
network.setText(display);
}
private final void
updateProperties() {
String s;
Resources r = getResources();
s = phone.getDeviceId();
if (s == null) s = r.getString(R.string.radioInfo_unknown);
mDeviceId.setText(s);
s = phone.getLine1Number();
if (s == null) s = r.getString(R.string.radioInfo_unknown);
number.setText(s);
}
private final void updateDataStats() {
String s;
s = SystemProperties.get("net.gsm.radio-reset", "0");
resets.setText(s);
s = SystemProperties.get("net.gsm.attempt-gprs", "0");
attempts.setText(s);
s = SystemProperties.get("net.gsm.succeed-gprs", "0");
successes.setText(s);
//s = SystemProperties.get("net.gsm.disconnect", "0");
//disconnects.setText(s);
s = SystemProperties.get("net.ppp.reset-by-timeout", "0");
sentSinceReceived.setText(s);
}
private final void updateDataStats2() {
Resources r = getResources();
long txPackets = TrafficStats.getMobileTxPackets();
long rxPackets = TrafficStats.getMobileRxPackets();
long txBytes = TrafficStats.getMobileTxBytes();
long rxBytes = TrafficStats.getMobileRxBytes();
String packets = r.getString(R.string.radioInfo_display_packets);
String bytes = r.getString(R.string.radioInfo_display_bytes);
sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
}
/**
* Ping a IP address.
*/
private final void pingIpAddr() {
try {
// This is hardcoded IP addr. This is for testing purposes.
// We would need to get rid of this before release.
String ipAddress = "74.125.47.104";
Process p = Runtime.getRuntime().exec("ping -c 1 " + ipAddress);
int status = p.waitFor();
if (status == 0) {
mPingIpAddrResult = "Pass";
} else {
mPingIpAddrResult = "Fail: IP addr not reachable";
}
} catch (IOException e) {
mPingIpAddrResult = "Fail: IOException";
} catch (InterruptedException e) {
mPingIpAddrResult = "Fail: InterruptedException";
}
}
/**
* Ping a host name
*/
private final void pingHostname() {
try {
Process p = Runtime.getRuntime().exec("ping -c 1 www.google.com");
int status = p.waitFor();
if (status == 0) {
mPingHostnameResult = "Pass";
} else {
mPingHostnameResult = "Fail: Host unreachable";
}
} catch (UnknownHostException e) {
mPingHostnameResult = "Fail: Unknown Host";
} catch (IOException e) {
mPingHostnameResult= "Fail: IOException";
} catch (InterruptedException e) {
mPingHostnameResult = "Fail: InterruptedException";
}
}
/**
* This function checks for basic functionality of HTTP Client.
*/
private void httpClientTest() {
HttpURLConnection urlConnection = null;
try {
// TODO: Hardcoded for now, make it UI configurable
URL url = new URL("https://www.google.com");
urlConnection = (HttpURLConnection) url.openConnection();
if (urlConnection.getResponseCode() == 200) {
mHttpClientTestResult = "Pass";
} else {
mHttpClientTestResult = "Fail: Code: " + urlConnection.getResponseMessage();
}
} catch (IOException e) {
mHttpClientTestResult = "Fail: IOException";
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
private void refreshSmsc() {
phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
}
private final void updatePingState() {
final Handler handler = new Handler();
// Set all to unknown since the threads will take a few secs to update.
mPingIpAddrResult = getResources().getString(R.string.radioInfo_unknown);
mPingHostnameResult = getResources().getString(R.string.radioInfo_unknown);
mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
mPingIpAddr.setText(mPingIpAddrResult);
mPingHostname.setText(mPingHostnameResult);
mHttpClientTest.setText(mHttpClientTestResult);
final Runnable updatePingResults = new Runnable() {
public void run() {
mPingIpAddr.setText(mPingIpAddrResult);
mPingHostname.setText(mPingHostnameResult);
mHttpClientTest.setText(mHttpClientTestResult);
}
};
Thread ipAddr = new Thread() {
@Override
public void run() {
pingIpAddr();
handler.post(updatePingResults);
}
};
ipAddr.start();
Thread hostname = new Thread() {
@Override
public void run() {
pingHostname();
handler.post(updatePingResults);
}
};
hostname.start();
Thread httpClient = new Thread() {
@Override
public void run() {
httpClientTest();
handler.post(updatePingResults);
}
};
httpClient.start();
}
private final void updatePdpList() {
StringBuilder sb = new StringBuilder("========DATA=======\n");
// List<DataConnection> dcs = phone.getCurrentDataConnectionList();
//
// for (DataConnection dc : dcs) {
// sb.append(" State=").append(dc.getStateAsString()).append("\n");
// if (dc.isActive()) {
// long timeElapsed =
// (System.currentTimeMillis() - dc.getConnectionTime())/1000;
// sb.append(" connected at ")
// .append(DateUtils.timeString(dc.getConnectionTime()))
// .append(" and elapsed ")
// .append(DateUtils.formatElapsedTime(timeElapsed));
//
// if (dc instanceof GsmDataConnection) {
// GsmDataConnection pdp = (GsmDataConnection)dc;
// sb.append("\n to ")
// .append(pdp.getApn().toString());
// }
// sb.append("\nLinkProperties: ");
// sb.append(phone.getLinkProperties(phone.getActiveApnTypes()[0]).toString());
// } else if (dc.isInactive()) {
// sb.append(" disconnected with last try at ")
// .append(DateUtils.timeString(dc.getLastFailTime()))
// .append("\n fail because ")
// .append(dc.getLastFailCause().toString());
// } else {
// if (dc instanceof GsmDataConnection) {
// GsmDataConnection pdp = (GsmDataConnection)dc;
// sb.append(" is connecting to ")
// .append(pdp.getApn().toString());
// } else {
// sb.append(" is connecting");
// }
// }
// sb.append("\n===================");
// }
disconnects.setText(sb.toString());
}
private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Intent intent = new Intent(Intent.ACTION_VIEW);
// XXX We need to specify the component here because if we don't
// the activity manager will try to resolve the type by calling
// the content provider, which causes it to be loaded in a process
// other than the Dialer process, which causes a lot of stuff to
// break.
intent.setClassName("com.android.phone",
"com.android.phone.SimContacts");
startActivity(intent);
return true;
}
};
private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Intent intent = new Intent(Intent.ACTION_VIEW);
// XXX We need to specify the component here because if we don't
// the activity manager will try to resolve the type by calling
// the content provider, which causes it to be loaded in a process
// other than the Dialer process, which causes a lot of stuff to
// break.
intent.setClassName("com.android.phone",
"com.android.phone.settings.fdn.FdnList");
startActivity(intent);
return true;
}
};
private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Intent intent = new Intent(
Intent.ACTION_VIEW, Uri.parse("content://icc/sdn"));
// XXX We need to specify the component here because if we don't
// the activity manager will try to resolve the type by calling
// the content provider, which causes it to be loaded in a process
// other than the Dialer process, which causes a lot of stuff to
// break.
intent.setClassName("com.android.phone",
"com.android.phone.ADNList");
startActivity(intent);
return true;
}
};
private MenuItem.OnMenuItemClickListener mGetPdpList = new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
phone.getDataCallList(null);
return true;
}
};
private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Intent intent = new Intent();
intent.setClass(RadioInfo.this, BandMode.class);
startActivity(intent);
return true;
}
};
private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
int state = mTelephonyManager.getDataState();
switch (state) {
case TelephonyManager.DATA_CONNECTED:
phone.setDataEnabled(false);
break;
case TelephonyManager.DATA_DISCONNECTED:
phone.setDataEnabled(true);
break;
default:
// do nothing
break;
}
return true;
}
};
OnClickListener mPowerButtonHandler = new OnClickListener() {
public void onClick(View v) {
//log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
phone.setRadioPower(!isRadioOn());
}
};
class CellInfoListRateHandler implements OnClickListener {
int rates[] = {Integer.MAX_VALUE, 0, 1000};
int index = 0;
public int getRate() {
return rates[index];
}
@Override
public void onClick(View v) {
index += 1;
if (index >= rates.length) {
index = 0;
}
phone.setCellInfoListRate(rates[index]);
updateCellInfoListRate();
}
}
CellInfoListRateHandler mCellInfoListRateHandler = new CellInfoListRateHandler();
private Button imsRegRequiredButton;
static final String PROPERTY_IMS_REG_REQUIRED = "persist.radio.imsregrequired";
OnClickListener mImsRegRequiredHandler = new OnClickListener() {
@Override
public void onClick(View v) {
log(String.format("toggle %s: currently %s",
PROPERTY_IMS_REG_REQUIRED, (isImsRegRequired() ? "on":"off")));
boolean newValue = !isImsRegRequired();
SystemProperties.set(PROPERTY_IMS_REG_REQUIRED,
newValue ? "1":"0");
updateImsRegRequiredState();
}
};
private boolean isImsRegRequired() {
return SystemProperties.getBoolean(PROPERTY_IMS_REG_REQUIRED, false);
}
private void updateImsRegRequiredState() {
log("updateImsRegRequiredState isImsRegRequired()=" + isImsRegRequired());
String buttonText = isImsRegRequired() ?
getString(R.string.ims_reg_required_off) :
getString(R.string.ims_reg_required_on);
imsRegRequiredButton.setText(buttonText);
}
private Button smsOverImsButton;
static final String PROPERTY_SMS_OVER_IMS = "persist.radio.imsallowmtsms";
OnClickListener mSmsOverImsHandler = new OnClickListener() {
@Override
public void onClick(View v) {
log(String.format("toggle %s: currently %s",
PROPERTY_SMS_OVER_IMS, (isSmsOverImsEnabled() ? "on":"off")));
boolean newValue = !isSmsOverImsEnabled();
SystemProperties.set(PROPERTY_SMS_OVER_IMS, newValue ? "1":"0");
updateSmsOverImsState();
}
};
private boolean isSmsOverImsEnabled() {
return SystemProperties.getBoolean(PROPERTY_SMS_OVER_IMS, false);
}
private Button imsVoLteProvisionedButton;
OnClickListener mImsVoLteProvisionedHandler = new OnClickListener() {
@Override
public void onClick(View v) {
log(String.format("toggle VoLTE provisioned: currently %s",
(isImsVoLteProvisioned() ? "on":"off")));
final boolean newValue = !isImsVoLteProvisioned();
if (phone != null) {
final ImsManager imsManager = ImsManager.getInstance(phone.getContext(), phone.getSubId());
if (imsManager != null) {
QueuedWork.singleThreadExecutor().submit(new Runnable() {
public void run() {
try {
imsManager.getConfigInterface().setProvisionedValue(
ImsConfig.ConfigConstants.VLT_SETTING_ENABLED,
newValue? 1 : 0);
} catch (ImsException e) {
Log.e(TAG, "setImsVoLteProvisioned() exception:", e);
}
}
});
}
}
updateImsVoLteProvisionedState();
}
};
private boolean isImsVoLteProvisioned() {
if (phone != null) {
ImsManager imsManager = ImsManager.getInstance(phone.getContext(), phone.getSubId());
return imsManager.isVolteProvisionedOnDevice(phone.getContext());
}
return false;
}
private void updateImsVoLteProvisionedState() {
log("updateImsVoLteProvisionedState isImsVoLteProvisioned()=" + isImsVoLteProvisioned());
String buttonText = isImsVoLteProvisioned() ?
getString(R.string.volte_provisioned_flag_off) :
getString(R.string.volte_provisioned_flag_on);
imsVoLteProvisionedButton.setText(buttonText);
}
private void updateSmsOverImsState() {
log("updateSmsOverImsState isSmsOverImsEnabled()=" + isSmsOverImsEnabled());
String buttonText = isSmsOverImsEnabled() ?
getString(R.string.sms_over_ims_off) :
getString(R.string.sms_over_ims_on);
smsOverImsButton.setText(buttonText);
}
private Button lteRamDumpButton;
static final String PROPERTY_LTE_RAM_DUMP = "persist.radio.ramdump";
OnClickListener mLteRamDumpHandler = new OnClickListener() {
@Override
public void onClick(View v) {
log(String.format("toggle %s: currently %s",
PROPERTY_LTE_RAM_DUMP, (isSmsOverImsEnabled() ? "on":"off")));
boolean newValue = !isLteRamDumpEnabled();
SystemProperties.set(PROPERTY_LTE_RAM_DUMP, newValue ? "1":"0");
updateLteRamDumpState();
}
};
private boolean isLteRamDumpEnabled() {
return SystemProperties.getBoolean(PROPERTY_LTE_RAM_DUMP, false);
}
private void updateLteRamDumpState() {
log("updateLteRamDumpState isLteRamDumpEnabled()=" + isLteRamDumpEnabled());
String buttonText = isLteRamDumpEnabled() ?
getString(R.string.lte_ram_dump_off) :
getString(R.string.lte_ram_dump_on);
lteRamDumpButton.setText(buttonText);
}
OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
public void onClick(View v) {
phone.disableDnsCheck(!phone.isDnsCheckDisabled());
updateDnsCheckState();
}
};
OnClickListener mOemInfoButtonHandler = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent("com.android.settings.OEM_RADIO_INFO");
try {
startActivity(intent);
} catch (android.content.ActivityNotFoundException ex) {
log("OEM-specific Info/Settings Activity Not Found : " + ex);
// If the activity does not exist, there are no OEM
// settings, and so we can just do nothing...
}
}
};
OnClickListener mPingButtonHandler = new OnClickListener() {
public void onClick(View v) {
updatePingState();
}
};
OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
public void onClick(View v) {
updateSmscButton.setEnabled(false);
phone.setSmscAddress(smsc.getText().toString(),
mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
}
};
OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
public void onClick(View v) {
refreshSmsc();
}
};
AdapterView.OnItemSelectedListener
mPreferredNetworkHandler = new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView parent, View v, int pos, long id) {
Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
if (pos>=0 && pos<=(mPreferredNetworkLabels.length - 2)) {
phone.setPreferredNetworkType(pos, msg);
}
}
public void onNothingSelected(AdapterView parent) {
}
};
private String[] mPreferredNetworkLabels = {
"WCDMA preferred",
"GSM only",
"WCDMA only",
"GSM auto (PRL)",
"CDMA auto (PRL)",
"CDMA only",
"EvDo only",
"GSM/CDMA auto (PRL)",
"LTE/CDMA auto (PRL)",
"LTE/GSM auto (PRL)",
"LTE/GSM/CDMA auto (PRL)",
"LTE only",
"Unknown"};
private void log(String s) {
Log.d(TAG, "[RadioInfo] " + s);
}
}