• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings;
18 
19 import android.app.Activity;
20 import android.content.Context;
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.net.ConnectivityManager;
26 import android.net.LinkProperties;
27 import android.net.TrafficStats;
28 import android.net.Uri;
29 import android.os.AsyncResult;
30 import android.os.Bundle;
31 import android.os.Handler;
32 import android.os.Message;
33 import android.os.RemoteException;
34 import android.os.ServiceManager;
35 import android.os.SystemProperties;
36 import android.telephony.CellLocation;
37 import android.telephony.PhoneStateListener;
38 import android.telephony.ServiceState;
39 import android.telephony.TelephonyManager;
40 import android.telephony.NeighboringCellInfo;
41 import android.telephony.cdma.CdmaCellLocation;
42 import android.telephony.gsm.GsmCellLocation;
43 import android.text.format.DateUtils;
44 import android.util.Log;
45 import android.view.Menu;
46 import android.view.MenuItem;
47 import android.view.View;
48 import android.view.View.OnClickListener;
49 import android.widget.AdapterView;
50 import android.widget.ArrayAdapter;
51 import android.widget.Button;
52 import android.widget.Spinner;
53 import android.widget.TextView;
54 import android.widget.EditText;
55 
56 import com.android.internal.telephony.DataConnection;
57 import com.android.internal.telephony.Phone;
58 import com.android.internal.telephony.PhoneFactory;
59 import com.android.internal.telephony.PhoneStateIntentReceiver;
60 import com.android.internal.telephony.TelephonyProperties;
61 import com.android.internal.telephony.gsm.GsmDataConnection;
62 
63 import org.apache.http.HttpResponse;
64 import org.apache.http.client.HttpClient;
65 import org.apache.http.client.methods.HttpGet;
66 import org.apache.http.impl.client.DefaultHttpClient;
67 
68 import java.io.IOException;
69 import java.net.InetAddress;
70 import java.net.UnknownHostException;
71 import java.util.ArrayList;
72 import java.util.List;
73 
74 import android.util.Log;
75 
76 public class RadioInfo extends Activity {
77     private final String TAG = "phone";
78 
79     private static final int EVENT_PHONE_STATE_CHANGED = 100;
80     private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
81     private static final int EVENT_SERVICE_STATE_CHANGED = 300;
82     private static final int EVENT_CFI_CHANGED = 302;
83 
84     private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
85     private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
86     private static final int EVENT_QUERY_NEIGHBORING_CIDS_DONE = 1002;
87     private static final int EVENT_QUERY_SMSC_DONE = 1005;
88     private static final int EVENT_UPDATE_SMSC_DONE = 1006;
89 
90     private static final int MENU_ITEM_SELECT_BAND  = 0;
91     private static final int MENU_ITEM_VIEW_ADN     = 1;
92     private static final int MENU_ITEM_VIEW_FDN     = 2;
93     private static final int MENU_ITEM_VIEW_SDN     = 3;
94     private static final int MENU_ITEM_GET_PDP_LIST = 4;
95     private static final int MENU_ITEM_TOGGLE_DATA  = 5;
96 
97     static final String ENABLE_DATA_STR = "Enable data connection";
98     static final String DISABLE_DATA_STR = "Disable data connection";
99 
100     private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
101     private TextView number;
102     private TextView callState;
103     private TextView operatorName;
104     private TextView roamingState;
105     private TextView gsmState;
106     private TextView gprsState;
107     private TextView network;
108     private TextView dBm;
109     private TextView mMwi;
110     private TextView mCfi;
111     private TextView mLocation;
112     private TextView mNeighboringCids;
113     private TextView resets;
114     private TextView attempts;
115     private TextView successes;
116     private TextView disconnects;
117     private TextView sentSinceReceived;
118     private TextView sent;
119     private TextView received;
120     private TextView mPingIpAddr;
121     private TextView mPingHostname;
122     private TextView mHttpClientTest;
123     private TextView dnsCheckState;
124     private EditText smsc;
125     private Button radioPowerButton;
126     private Button dnsCheckToggleButton;
127     private Button pingTestButton;
128     private Button updateSmscButton;
129     private Button refreshSmscButton;
130     private Button oemInfoButton;
131     private Spinner preferredNetworkType;
132 
133     private TelephonyManager mTelephonyManager;
134     private Phone phone = null;
135     private PhoneStateIntentReceiver mPhoneStateReceiver;
136 
137     private String mPingIpAddrResult;
138     private String mPingHostnameResult;
139     private String mHttpClientTestResult;
140     private boolean mMwiValue = false;
141     private boolean mCfiValue = false;
142 
143     private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
144         @Override
145         public void onDataConnectionStateChanged(int state) {
146             updateDataState();
147             updateDataStats();
148             updatePdpList();
149             updateNetworkType();
150         }
151 
152         @Override
153         public void onDataActivity(int direction) {
154             updateDataStats2();
155         }
156 
157         @Override
158         public void onCellLocationChanged(CellLocation location) {
159             updateLocation(location);
160         }
161 
162         @Override
163         public void onMessageWaitingIndicatorChanged(boolean mwi) {
164             mMwiValue = mwi;
165             updateMessageWaiting();
166         }
167 
168         @Override
169         public void onCallForwardingIndicatorChanged(boolean cfi) {
170             mCfiValue = cfi;
171             updateCallRedirect();
172         }
173     };
174 
175     private Handler mHandler = new Handler() {
176         public void handleMessage(Message msg) {
177             AsyncResult ar;
178             switch (msg.what) {
179                 case EVENT_PHONE_STATE_CHANGED:
180                     updatePhoneState();
181                     break;
182 
183                 case EVENT_SIGNAL_STRENGTH_CHANGED:
184                     updateSignalStrength();
185                     break;
186 
187                 case EVENT_SERVICE_STATE_CHANGED:
188                     updateServiceState();
189                     updatePowerState();
190                     break;
191 
192                 case EVENT_QUERY_PREFERRED_TYPE_DONE:
193                     ar= (AsyncResult) msg.obj;
194                     if (ar.exception == null) {
195                         int type = ((int[])ar.result)[0];
196                         preferredNetworkType.setSelection(type, true);
197                     } else {
198                         preferredNetworkType.setSelection(8, true);
199                     }
200                     break;
201                 case EVENT_SET_PREFERRED_TYPE_DONE:
202                     ar= (AsyncResult) msg.obj;
203                     if (ar.exception != null) {
204                         phone.getPreferredNetworkType(
205                                 obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
206                     }
207                     break;
208                 case EVENT_QUERY_NEIGHBORING_CIDS_DONE:
209                     ar= (AsyncResult) msg.obj;
210                     if (ar.exception == null) {
211                         updateNeighboringCids((ArrayList<NeighboringCellInfo>)ar.result);
212                     } else {
213                         mNeighboringCids.setText("unknown");
214                     }
215                     break;
216                 case EVENT_QUERY_SMSC_DONE:
217                     ar= (AsyncResult) msg.obj;
218                     if (ar.exception != null) {
219                         smsc.setText("refresh error");
220                     } else {
221                         smsc.setText((String)ar.result);
222                     }
223                     break;
224                 case EVENT_UPDATE_SMSC_DONE:
225                     updateSmscButton.setEnabled(true);
226                     ar= (AsyncResult) msg.obj;
227                     if (ar.exception != null) {
228                         smsc.setText("update error");
229                     }
230                     break;
231                 default:
232                     break;
233 
234             }
235         }
236     };
237 
238     @Override
onCreate(Bundle icicle)239     public void onCreate(Bundle icicle) {
240         super.onCreate(icicle);
241 
242         setContentView(R.layout.radio_info);
243 
244         mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
245         phone = PhoneFactory.getDefaultPhone();
246 
247         mDeviceId= (TextView) findViewById(R.id.imei);
248         number = (TextView) findViewById(R.id.number);
249         callState = (TextView) findViewById(R.id.call);
250         operatorName = (TextView) findViewById(R.id.operator);
251         roamingState = (TextView) findViewById(R.id.roaming);
252         gsmState = (TextView) findViewById(R.id.gsm);
253         gprsState = (TextView) findViewById(R.id.gprs);
254         network = (TextView) findViewById(R.id.network);
255         dBm = (TextView) findViewById(R.id.dbm);
256         mMwi = (TextView) findViewById(R.id.mwi);
257         mCfi = (TextView) findViewById(R.id.cfi);
258         mLocation = (TextView) findViewById(R.id.location);
259         mNeighboringCids = (TextView) findViewById(R.id.neighboring);
260 
261         resets = (TextView) findViewById(R.id.resets);
262         attempts = (TextView) findViewById(R.id.attempts);
263         successes = (TextView) findViewById(R.id.successes);
264         disconnects = (TextView) findViewById(R.id.disconnects);
265         sentSinceReceived = (TextView) findViewById(R.id.sentSinceReceived);
266         sent = (TextView) findViewById(R.id.sent);
267         received = (TextView) findViewById(R.id.received);
268         smsc = (EditText) findViewById(R.id.smsc);
269         dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
270 
271         mPingIpAddr = (TextView) findViewById(R.id.pingIpAddr);
272         mPingHostname = (TextView) findViewById(R.id.pingHostname);
273         mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
274 
275         preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
276         ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
277                 android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
278         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
279         preferredNetworkType.setAdapter(adapter);
280         preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
281 
282         radioPowerButton = (Button) findViewById(R.id.radio_power);
283         radioPowerButton.setOnClickListener(mPowerButtonHandler);
284 
285         imsRegRequiredButton = (Button) findViewById(R.id.ims_reg_required);
286         imsRegRequiredButton.setOnClickListener(mImsRegRequiredHandler);
287 
288         smsOverImsButton = (Button) findViewById(R.id.sms_over_ims);
289         smsOverImsButton.setOnClickListener(mSmsOverImsHandler);
290 
291         lteRamDumpButton = (Button) findViewById(R.id.lte_ram_dump);
292         lteRamDumpButton.setOnClickListener(mLteRamDumpHandler);
293 
294         pingTestButton = (Button) findViewById(R.id.ping_test);
295         pingTestButton.setOnClickListener(mPingButtonHandler);
296         updateSmscButton = (Button) findViewById(R.id.update_smsc);
297         updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
298         refreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
299         refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
300         dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
301         dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
302 
303         oemInfoButton = (Button) findViewById(R.id.oem_info);
304         oemInfoButton.setOnClickListener(mOemInfoButtonHandler);
305         PackageManager pm = getPackageManager();
306         Intent oemInfoIntent = new Intent("com.android.settings.OEM_RADIO_INFO");
307         List<ResolveInfo> oemInfoIntentList = pm.queryIntentActivities(oemInfoIntent, 0);
308         if (oemInfoIntentList.size() == 0) {
309             oemInfoButton.setEnabled(false);
310         }
311 
312         mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler);
313         mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED);
314         mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
315         mPhoneStateReceiver.notifyPhoneCallState(EVENT_PHONE_STATE_CHANGED);
316 
317         phone.getPreferredNetworkType(
318                 mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
319         phone.getNeighboringCids(
320                 mHandler.obtainMessage(EVENT_QUERY_NEIGHBORING_CIDS_DONE));
321 
322         CellLocation.requestLocationUpdate();
323     }
324 
325     @Override
onResume()326     protected void onResume() {
327         super.onResume();
328 
329         updatePhoneState();
330         updateSignalStrength();
331         updateMessageWaiting();
332         updateCallRedirect();
333         updateServiceState();
334         updateLocation(mTelephonyManager.getCellLocation());
335         updateDataState();
336         updateDataStats();
337         updateDataStats2();
338         updatePowerState();
339         updateImsRegRequiredState();
340         updateSmsOverImsState();
341         updateLteRamDumpState();
342         updateProperties();
343         updateDnsCheckState();
344 
345         Log.i(TAG, "[RadioInfo] onResume: register phone & data intents");
346 
347         mPhoneStateReceiver.registerIntent();
348         mTelephonyManager.listen(mPhoneStateListener,
349                   PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
350                 | PhoneStateListener.LISTEN_DATA_ACTIVITY
351                 | PhoneStateListener.LISTEN_CELL_LOCATION
352                 | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
353                 | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
354     }
355 
356     @Override
onPause()357     public void onPause() {
358         super.onPause();
359 
360         Log.i(TAG, "[RadioInfo] onPause: unregister phone & data intents");
361 
362         mPhoneStateReceiver.unregisterIntent();
363         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
364     }
365 
366     @Override
onCreateOptionsMenu(Menu menu)367     public boolean onCreateOptionsMenu(Menu menu) {
368         menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label)
369                 .setOnMenuItemClickListener(mSelectBandCallback)
370                 .setAlphabeticShortcut('b');
371         menu.add(1, MENU_ITEM_VIEW_ADN, 0,
372                 R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
373         menu.add(1, MENU_ITEM_VIEW_FDN, 0,
374                 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
375         menu.add(1, MENU_ITEM_VIEW_SDN, 0,
376                 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
377         menu.add(1, MENU_ITEM_GET_PDP_LIST,
378                 0, R.string.radioInfo_menu_getPDP).setOnMenuItemClickListener(mGetPdpList);
379         menu.add(1, MENU_ITEM_TOGGLE_DATA,
380                 0, DISABLE_DATA_STR).setOnMenuItemClickListener(mToggleData);
381         return true;
382     }
383 
384     @Override
onPrepareOptionsMenu(Menu menu)385     public boolean onPrepareOptionsMenu(Menu menu) {
386         // Get the TOGGLE DATA menu item in the right state.
387         MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
388         int state = mTelephonyManager.getDataState();
389         boolean visible = true;
390 
391         switch (state) {
392             case TelephonyManager.DATA_CONNECTED:
393             case TelephonyManager.DATA_SUSPENDED:
394                 item.setTitle(DISABLE_DATA_STR);
395                 break;
396             case TelephonyManager.DATA_DISCONNECTED:
397                 item.setTitle(ENABLE_DATA_STR);
398                 break;
399             default:
400                 visible = false;
401                 break;
402         }
403         item.setVisible(visible);
404         return true;
405     }
406 
isRadioOn()407     private boolean isRadioOn() {
408         return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
409     }
410 
updatePowerState()411     private void updatePowerState() {
412         String buttonText = isRadioOn() ?
413                             getString(R.string.turn_off_radio) :
414                             getString(R.string.turn_on_radio);
415         radioPowerButton.setText(buttonText);
416     }
417 
updateDnsCheckState()418     private void updateDnsCheckState() {
419         dnsCheckState.setText(phone.isDnsCheckDisabled() ?
420                 "0.0.0.0 allowed" :"0.0.0.0 not allowed");
421     }
422 
423     private final void
updateSignalStrength()424     updateSignalStrength() {
425         // TODO PhoneStateIntentReceiver is deprecated and PhoneStateListener
426         // should probably used instead.
427         int state = mPhoneStateReceiver.getServiceState().getState();
428         Resources r = getResources();
429 
430         if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
431                 (ServiceState.STATE_POWER_OFF == state)) {
432             dBm.setText("0");
433         }
434 
435         int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
436 
437         if (-1 == signalDbm) signalDbm = 0;
438 
439         int signalAsu = mPhoneStateReceiver.getSignalStrengthLevelAsu();
440 
441         if (-1 == signalAsu) signalAsu = 0;
442 
443         dBm.setText(String.valueOf(signalDbm) + " "
444             + r.getString(R.string.radioInfo_display_dbm) + "   "
445             + String.valueOf(signalAsu) + " "
446             + r.getString(R.string.radioInfo_display_asu));
447     }
448 
updateLocation(CellLocation location)449     private final void updateLocation(CellLocation location) {
450         Resources r = getResources();
451         if (location instanceof GsmCellLocation) {
452             GsmCellLocation loc = (GsmCellLocation)location;
453             int lac = loc.getLac();
454             int cid = loc.getCid();
455             mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
456                     + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
457                     + "   "
458                     + r.getString(R.string.radioInfo_cid) + " = "
459                     + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
460         } else if (location instanceof CdmaCellLocation) {
461             CdmaCellLocation loc = (CdmaCellLocation)location;
462             int bid = loc.getBaseStationId();
463             int sid = loc.getSystemId();
464             int nid = loc.getNetworkId();
465             int lat = loc.getBaseStationLatitude();
466             int lon = loc.getBaseStationLongitude();
467             mLocation.setText("BID = "
468                     + ((bid == -1) ? "unknown" : Integer.toHexString(bid))
469                     + "   "
470                     + "SID = "
471                     + ((sid == -1) ? "unknown" : Integer.toHexString(sid))
472                     + "   "
473                     + "NID = "
474                     + ((nid == -1) ? "unknown" : Integer.toHexString(nid))
475                     + "\n"
476                     + "LAT = "
477                     + ((lat == -1) ? "unknown" : Integer.toHexString(lat))
478                     + "   "
479                     + "LONG = "
480                     + ((lon == -1) ? "unknown" : Integer.toHexString(lon)));
481         } else {
482             mLocation.setText("unknown");
483         }
484 
485 
486     }
487 
updateNeighboringCids(ArrayList<NeighboringCellInfo> cids)488     private final void updateNeighboringCids(ArrayList<NeighboringCellInfo> cids) {
489         StringBuilder sb = new StringBuilder();
490 
491         if (cids != null) {
492             if ( cids.isEmpty() ) {
493                 sb.append("no neighboring cells");
494             } else {
495                 for (NeighboringCellInfo cell : cids) {
496                     sb.append(cell.toString()).append(" ");
497                 }
498             }
499         } else {
500             sb.append("unknown");
501         }
502         mNeighboringCids.setText(sb.toString());
503     }
504 
505     private final void
updateMessageWaiting()506     updateMessageWaiting() {
507         mMwi.setText(String.valueOf(mMwiValue));
508     }
509 
510     private final void
updateCallRedirect()511     updateCallRedirect() {
512         mCfi.setText(String.valueOf(mCfiValue));
513     }
514 
515 
516     private final void
updateServiceState()517     updateServiceState() {
518         ServiceState serviceState = mPhoneStateReceiver.getServiceState();
519         int state = serviceState.getState();
520         Resources r = getResources();
521         String display = r.getString(R.string.radioInfo_unknown);
522 
523         switch (state) {
524             case ServiceState.STATE_IN_SERVICE:
525                 display = r.getString(R.string.radioInfo_service_in);
526                 break;
527             case ServiceState.STATE_OUT_OF_SERVICE:
528             case ServiceState.STATE_EMERGENCY_ONLY:
529                 display = r.getString(R.string.radioInfo_service_emergency);
530                 break;
531             case ServiceState.STATE_POWER_OFF:
532                 display = r.getString(R.string.radioInfo_service_off);
533                 break;
534         }
535 
536         gsmState.setText(display);
537 
538         if (serviceState.getRoaming()) {
539             roamingState.setText(R.string.radioInfo_roaming_in);
540         } else {
541             roamingState.setText(R.string.radioInfo_roaming_not);
542         }
543 
544         operatorName.setText(serviceState.getOperatorAlphaLong());
545     }
546 
547     private final void
updatePhoneState()548     updatePhoneState() {
549         Phone.State state = mPhoneStateReceiver.getPhoneState();
550         Resources r = getResources();
551         String display = r.getString(R.string.radioInfo_unknown);
552 
553         switch (state) {
554             case IDLE:
555                 display = r.getString(R.string.radioInfo_phone_idle);
556                 break;
557             case RINGING:
558                 display = r.getString(R.string.radioInfo_phone_ringing);
559                 break;
560             case OFFHOOK:
561                 display = r.getString(R.string.radioInfo_phone_offhook);
562                 break;
563         }
564 
565         callState.setText(display);
566     }
567 
568     private final void
updateDataState()569     updateDataState() {
570         int state = mTelephonyManager.getDataState();
571         Resources r = getResources();
572         String display = r.getString(R.string.radioInfo_unknown);
573 
574         switch (state) {
575             case TelephonyManager.DATA_CONNECTED:
576                 display = r.getString(R.string.radioInfo_data_connected);
577                 break;
578             case TelephonyManager.DATA_CONNECTING:
579                 display = r.getString(R.string.radioInfo_data_connecting);
580                 break;
581             case TelephonyManager.DATA_DISCONNECTED:
582                 display = r.getString(R.string.radioInfo_data_disconnected);
583                 break;
584             case TelephonyManager.DATA_SUSPENDED:
585                 display = r.getString(R.string.radioInfo_data_suspended);
586                 break;
587         }
588 
589         gprsState.setText(display);
590     }
591 
updateNetworkType()592     private final void updateNetworkType() {
593         Resources r = getResources();
594         String display = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
595                 r.getString(R.string.radioInfo_unknown));
596 
597         network.setText(display);
598     }
599 
600     private final void
updateProperties()601     updateProperties() {
602         String s;
603         Resources r = getResources();
604 
605         s = phone.getDeviceId();
606         if (s == null) s = r.getString(R.string.radioInfo_unknown);
607         mDeviceId.setText(s);
608 
609 
610         s = phone.getLine1Number();
611         if (s == null) s = r.getString(R.string.radioInfo_unknown);
612         number.setText(s);
613     }
614 
updateDataStats()615     private final void updateDataStats() {
616         String s;
617 
618         s = SystemProperties.get("net.gsm.radio-reset", "0");
619         resets.setText(s);
620 
621         s = SystemProperties.get("net.gsm.attempt-gprs", "0");
622         attempts.setText(s);
623 
624         s = SystemProperties.get("net.gsm.succeed-gprs", "0");
625         successes.setText(s);
626 
627         //s = SystemProperties.get("net.gsm.disconnect", "0");
628         //disconnects.setText(s);
629 
630         s = SystemProperties.get("net.ppp.reset-by-timeout", "0");
631         sentSinceReceived.setText(s);
632     }
633 
updateDataStats2()634     private final void updateDataStats2() {
635         Resources r = getResources();
636 
637         long txPackets = TrafficStats.getMobileTxPackets();
638         long rxPackets = TrafficStats.getMobileRxPackets();
639         long txBytes   = TrafficStats.getMobileTxBytes();
640         long rxBytes   = TrafficStats.getMobileRxBytes();
641 
642         String packets = r.getString(R.string.radioInfo_display_packets);
643         String bytes   = r.getString(R.string.radioInfo_display_bytes);
644 
645         sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
646         received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
647     }
648 
649     /**
650      * Ping a IP address.
651      */
pingIpAddr()652     private final void pingIpAddr() {
653         try {
654             // This is hardcoded IP addr. This is for testing purposes.
655             // We would need to get rid of this before release.
656             String ipAddress = "74.125.47.104";
657             Process p = Runtime.getRuntime().exec("ping -c 1 " + ipAddress);
658             int status = p.waitFor();
659             if (status == 0) {
660                 mPingIpAddrResult = "Pass";
661             } else {
662                 mPingIpAddrResult = "Fail: IP addr not reachable";
663             }
664         } catch (IOException e) {
665             mPingIpAddrResult = "Fail: IOException";
666         } catch (InterruptedException e) {
667             mPingIpAddrResult = "Fail: InterruptedException";
668         }
669     }
670 
671     /**
672      *  Ping a host name
673      */
pingHostname()674     private final void pingHostname() {
675         try {
676             Process p = Runtime.getRuntime().exec("ping -c 1 www.google.com");
677             int status = p.waitFor();
678             if (status == 0) {
679                 mPingHostnameResult = "Pass";
680             } else {
681                 mPingHostnameResult = "Fail: Host unreachable";
682             }
683         } catch (UnknownHostException e) {
684             mPingHostnameResult = "Fail: Unknown Host";
685         } catch (IOException e) {
686             mPingHostnameResult= "Fail: IOException";
687         } catch (InterruptedException e) {
688             mPingHostnameResult = "Fail: InterruptedException";
689         }
690     }
691 
692     /**
693      * This function checks for basic functionality of HTTP Client.
694      */
httpClientTest()695     private void httpClientTest() {
696         HttpClient client = new DefaultHttpClient();
697         try {
698             HttpGet request = new HttpGet("http://www.google.com");
699             HttpResponse response = client.execute(request);
700             if (response.getStatusLine().getStatusCode() == 200) {
701                 mHttpClientTestResult = "Pass";
702             } else {
703                 mHttpClientTestResult = "Fail: Code: " + String.valueOf(response);
704             }
705             request.abort();
706         } catch (IOException e) {
707             mHttpClientTestResult = "Fail: IOException";
708         }
709     }
710 
refreshSmsc()711     private void refreshSmsc() {
712         phone.getSmscAddress(mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
713     }
714 
updatePingState()715     private final void updatePingState() {
716         final Handler handler = new Handler();
717         // Set all to unknown since the threads will take a few secs to update.
718         mPingIpAddrResult = getResources().getString(R.string.radioInfo_unknown);
719         mPingHostnameResult = getResources().getString(R.string.radioInfo_unknown);
720         mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
721 
722         mPingIpAddr.setText(mPingIpAddrResult);
723         mPingHostname.setText(mPingHostnameResult);
724         mHttpClientTest.setText(mHttpClientTestResult);
725 
726         final Runnable updatePingResults = new Runnable() {
727             public void run() {
728                 mPingIpAddr.setText(mPingIpAddrResult);
729                 mPingHostname.setText(mPingHostnameResult);
730                 mHttpClientTest.setText(mHttpClientTestResult);
731             }
732         };
733         Thread ipAddr = new Thread() {
734             @Override
735             public void run() {
736                 pingIpAddr();
737                 handler.post(updatePingResults);
738             }
739         };
740         ipAddr.start();
741 
742         Thread hostname = new Thread() {
743             @Override
744             public void run() {
745                 pingHostname();
746                 handler.post(updatePingResults);
747             }
748         };
749         hostname.start();
750 
751         Thread httpClient = new Thread() {
752             @Override
753             public void run() {
754                 httpClientTest();
755                 handler.post(updatePingResults);
756             }
757         };
758         httpClient.start();
759     }
760 
updatePdpList()761     private final void updatePdpList() {
762         StringBuilder sb = new StringBuilder("========DATA=======\n");
763 
764 //        List<DataConnection> dcs = phone.getCurrentDataConnectionList();
765 //
766 //        for (DataConnection dc : dcs) {
767 //            sb.append("    State=").append(dc.getStateAsString()).append("\n");
768 //            if (dc.isActive()) {
769 //                long timeElapsed =
770 //                    (System.currentTimeMillis() - dc.getConnectionTime())/1000;
771 //                sb.append("    connected at ")
772 //                  .append(DateUtils.timeString(dc.getConnectionTime()))
773 //                  .append(" and elapsed ")
774 //                  .append(DateUtils.formatElapsedTime(timeElapsed));
775 //
776 //                if (dc instanceof GsmDataConnection) {
777 //                    GsmDataConnection pdp = (GsmDataConnection)dc;
778 //                    sb.append("\n    to ")
779 //                      .append(pdp.getApn().toString());
780 //                }
781 //                sb.append("\nLinkProperties: ");
782 //                sb.append(phone.getLinkProperties(phone.getActiveApnTypes()[0]).toString());
783 //            } else if (dc.isInactive()) {
784 //                sb.append("    disconnected with last try at ")
785 //                  .append(DateUtils.timeString(dc.getLastFailTime()))
786 //                  .append("\n    fail because ")
787 //                  .append(dc.getLastFailCause().toString());
788 //            } else {
789 //                if (dc instanceof GsmDataConnection) {
790 //                    GsmDataConnection pdp = (GsmDataConnection)dc;
791 //                    sb.append("    is connecting to ")
792 //                      .append(pdp.getApn().toString());
793 //                } else {
794 //                    sb.append("    is connecting");
795 //                }
796 //            }
797 //            sb.append("\n===================");
798 //        }
799 
800         disconnects.setText(sb.toString());
801     }
802 
803     private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() {
804         public boolean onMenuItemClick(MenuItem item) {
805             Intent intent = new Intent(Intent.ACTION_VIEW);
806             // XXX We need to specify the component here because if we don't
807             // the activity manager will try to resolve the type by calling
808             // the content provider, which causes it to be loaded in a process
809             // other than the Dialer process, which causes a lot of stuff to
810             // break.
811             intent.setClassName("com.android.phone",
812                     "com.android.phone.SimContacts");
813             startActivity(intent);
814             return true;
815         }
816     };
817 
818     private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() {
819         public boolean onMenuItemClick(MenuItem item) {
820             Intent intent = new Intent(Intent.ACTION_VIEW);
821             // XXX We need to specify the component here because if we don't
822             // the activity manager will try to resolve the type by calling
823             // the content provider, which causes it to be loaded in a process
824             // other than the Dialer process, which causes a lot of stuff to
825             // break.
826             intent.setClassName("com.android.phone",
827                     "com.android.phone.FdnList");
828             startActivity(intent);
829             return true;
830         }
831     };
832 
833     private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() {
834         public boolean onMenuItemClick(MenuItem item) {
835             Intent intent = new Intent(
836                     Intent.ACTION_VIEW, Uri.parse("content://icc/sdn"));
837             // XXX We need to specify the component here because if we don't
838             // the activity manager will try to resolve the type by calling
839             // the content provider, which causes it to be loaded in a process
840             // other than the Dialer process, which causes a lot of stuff to
841             // break.
842             intent.setClassName("com.android.phone",
843                     "com.android.phone.ADNList");
844             startActivity(intent);
845             return true;
846         }
847     };
848 
849     private MenuItem.OnMenuItemClickListener mGetPdpList = new MenuItem.OnMenuItemClickListener() {
850         public boolean onMenuItemClick(MenuItem item) {
851             phone.getDataCallList(null);
852             return true;
853         }
854     };
855 
856     private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() {
857         public boolean onMenuItemClick(MenuItem item) {
858             Intent intent = new Intent();
859             intent.setClass(RadioInfo.this, BandMode.class);
860             startActivity(intent);
861             return true;
862         }
863     };
864 
865     private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
866         public boolean onMenuItemClick(MenuItem item) {
867             ConnectivityManager cm =
868                     (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
869             int state = mTelephonyManager.getDataState();
870             switch (state) {
871                 case TelephonyManager.DATA_CONNECTED:
872                     cm.setMobileDataEnabled(false);
873                     break;
874                 case TelephonyManager.DATA_DISCONNECTED:
875                     cm.setMobileDataEnabled(true);
876                     break;
877                 default:
878                     // do nothing
879                     break;
880             }
881             return true;
882         }
883     };
884 
885     OnClickListener mPowerButtonHandler = new OnClickListener() {
886         public void onClick(View v) {
887             //log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
888             phone.setRadioPower(!isRadioOn());
889         }
890     };
891 
892     private Button imsRegRequiredButton;
893     static final String PROPERTY_IMS_REG_REQUIRED = "persist.radio.imsregrequired";
894     OnClickListener mImsRegRequiredHandler = new OnClickListener() {
895         @Override
896         public void onClick(View v) {
897             Log.d(TAG, String.format("toggle %s: currently %s",
898                 PROPERTY_IMS_REG_REQUIRED, (isImsRegRequired() ? "on":"off")));
899             boolean newValue = !isImsRegRequired();
900             SystemProperties.set(PROPERTY_IMS_REG_REQUIRED,
901                     newValue ? "1":"0");
902             updateImsRegRequiredState();
903         }
904     };
905 
isImsRegRequired()906     private boolean isImsRegRequired() {
907         return SystemProperties.getBoolean(PROPERTY_IMS_REG_REQUIRED, false);
908     }
909 
updateImsRegRequiredState()910     private void updateImsRegRequiredState() {
911         Log.d(TAG, "updateImsRegRequiredState isImsRegRequired()=" + isImsRegRequired());
912         String buttonText = isImsRegRequired() ?
913                             getString(R.string.ims_reg_required_off) :
914                             getString(R.string.ims_reg_required_on);
915         imsRegRequiredButton.setText(buttonText);
916     }
917 
918     private Button smsOverImsButton;
919     static final String PROPERTY_SMS_OVER_IMS = "persist.radio.imsallowmtsms";
920     OnClickListener mSmsOverImsHandler = new OnClickListener() {
921         @Override
922         public void onClick(View v) {
923             Log.d(TAG, String.format("toggle %s: currently %s",
924                     PROPERTY_SMS_OVER_IMS, (isSmsOverImsEnabled() ? "on":"off")));
925             boolean newValue = !isSmsOverImsEnabled();
926             SystemProperties.set(PROPERTY_SMS_OVER_IMS, newValue ? "1":"0");
927             updateSmsOverImsState();
928         }
929     };
930 
isSmsOverImsEnabled()931     private boolean isSmsOverImsEnabled() {
932         return SystemProperties.getBoolean(PROPERTY_SMS_OVER_IMS, false);
933     }
934 
updateSmsOverImsState()935     private void updateSmsOverImsState() {
936         Log.d(TAG, "updateSmsOverImsState isSmsOverImsEnabled()=" + isSmsOverImsEnabled());
937         String buttonText = isSmsOverImsEnabled() ?
938                             getString(R.string.sms_over_ims_off) :
939                             getString(R.string.sms_over_ims_on);
940         smsOverImsButton.setText(buttonText);
941     }
942 
943     private Button lteRamDumpButton;
944     static final String PROPERTY_LTE_RAM_DUMP = "persist.radio.ramdump";
945     OnClickListener mLteRamDumpHandler = new OnClickListener() {
946         @Override
947         public void onClick(View v) {
948             Log.d(TAG, String.format("toggle %s: currently %s",
949                     PROPERTY_LTE_RAM_DUMP, (isSmsOverImsEnabled() ? "on":"off")));
950             boolean newValue = !isLteRamDumpEnabled();
951             SystemProperties.set(PROPERTY_LTE_RAM_DUMP, newValue ? "1":"0");
952             updateLteRamDumpState();
953         }
954     };
955 
isLteRamDumpEnabled()956     private boolean isLteRamDumpEnabled() {
957         return SystemProperties.getBoolean(PROPERTY_LTE_RAM_DUMP, false);
958     }
959 
updateLteRamDumpState()960     private void updateLteRamDumpState() {
961         Log.d(TAG, "updateLteRamDumpState isLteRamDumpEnabled()=" + isLteRamDumpEnabled());
962         String buttonText = isLteRamDumpEnabled() ?
963                             getString(R.string.lte_ram_dump_off) :
964                             getString(R.string.lte_ram_dump_on);
965         lteRamDumpButton.setText(buttonText);
966     }
967 
968     OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
969         public void onClick(View v) {
970             phone.disableDnsCheck(!phone.isDnsCheckDisabled());
971             updateDnsCheckState();
972         }
973     };
974 
975     OnClickListener mOemInfoButtonHandler = new OnClickListener() {
976         public void onClick(View v) {
977             Intent intent = new Intent("com.android.settings.OEM_RADIO_INFO");
978             try {
979                 startActivity(intent);
980             } catch (android.content.ActivityNotFoundException ex) {
981                 Log.d(TAG, "OEM-specific Info/Settings Activity Not Found : " + ex);
982                 // If the activity does not exist, there are no OEM
983                 // settings, and so we can just do nothing...
984             }
985         }
986     };
987 
988     OnClickListener mPingButtonHandler = new OnClickListener() {
989         public void onClick(View v) {
990             updatePingState();
991         }
992     };
993 
994     OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
995         public void onClick(View v) {
996             updateSmscButton.setEnabled(false);
997             phone.setSmscAddress(smsc.getText().toString(),
998                     mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
999         }
1000     };
1001 
1002     OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
1003         public void onClick(View v) {
1004             refreshSmsc();
1005         }
1006     };
1007 
1008     AdapterView.OnItemSelectedListener
1009             mPreferredNetworkHandler = new AdapterView.OnItemSelectedListener() {
1010         public void onItemSelected(AdapterView parent, View v, int pos, long id) {
1011             Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
1012             if (pos>=0 && pos<=7) { //IS THIS NEEDED to extend to the entire range of values
1013                 phone.setPreferredNetworkType(pos, msg);
1014             }
1015         }
1016 
1017         public void onNothingSelected(AdapterView parent) {
1018         }
1019     };
1020 
1021     private String[] mPreferredNetworkLabels = {
1022             "WCDMA preferred",
1023             "GSM only",
1024             "WCDMA only",
1025             "GSM auto (PRL)",
1026             "CDMA auto (PRL)",
1027             "CDMA only",
1028             "EvDo only",
1029             "GSM/CDMA auto (PRL)",
1030             "Unknown"};
1031 }
1032