OSDN Git Service

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