blob: b7ff28a91658e16ee4fbc187afdd4b34e2f12d19 [file] [log] [blame]
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -07001/*
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
17package com.android.settings;
18
19import android.app.Activity;
20import android.app.AlertDialog;
21import android.content.DialogInterface;
22import android.content.Intent;
23import android.content.SharedPreferences;
24import android.content.res.Resources;
25import android.net.Uri;
26import android.os.AsyncResult;
27import android.os.Bundle;
28import android.os.Handler;
29import android.os.INetStatService;
30import android.os.Message;
31import android.os.RemoteException;
32import android.os.ServiceManager;
33import android.os.SystemProperties;
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -070034import android.preference.PreferenceManager;
35import android.telephony.CellLocation;
36import android.telephony.PhoneStateListener;
37import android.telephony.ServiceState;
38import android.telephony.TelephonyManager;
The Android Open Source Projectabc48f82008-12-17 18:06:01 -080039import android.telephony.NeighboringCellInfo;
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -070040import android.telephony.gsm.GsmCellLocation;
The Android Open Source Projectabc48f82008-12-17 18:06:01 -080041import android.text.format.DateUtils;
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -070042import android.util.Log;
43import android.view.Menu;
44import android.view.MenuItem;
45import android.view.View;
46import android.view.View.OnClickListener;
47import android.widget.AdapterView;
48import android.widget.ArrayAdapter;
49import android.widget.Button;
50import android.widget.Spinner;
51import android.widget.TextView;
52import android.widget.EditText;
53
54import com.android.internal.telephony.Phone;
55import com.android.internal.telephony.PhoneFactory;
56import com.android.internal.telephony.PhoneStateIntentReceiver;
57import com.android.internal.telephony.TelephonyProperties;
58import com.android.internal.telephony.gsm.GSMPhone;
59import com.android.internal.telephony.gsm.PdpConnection;
60
61import org.apache.http.HttpResponse;
62import org.apache.http.client.HttpClient;
63import org.apache.http.client.methods.HttpGet;
64import org.apache.http.impl.client.DefaultHttpClient;
65
66import java.io.ByteArrayOutputStream;
67import java.io.DataOutputStream;
68import java.io.IOException;
69import java.net.UnknownHostException;
The Android Open Source Projectabc48f82008-12-17 18:06:01 -080070import java.util.ArrayList;
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -070071import java.util.List;
72
73public class RadioInfo extends Activity {
74 private final String TAG = "phone";
75
76 private static final int EVENT_PHONE_STATE_CHANGED = 100;
77 private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
78 private static final int EVENT_SERVICE_STATE_CHANGED = 300;
79 private static final int EVENT_CFI_CHANGED = 302;
80
81 private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
82 private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
83 private static final int EVENT_QUERY_NEIGHBORING_CIDS_DONE = 1002;
84 private static final int EVENT_SET_QXDMLOG_DONE = 1003;
85 private static final int EVENT_SET_CIPHER_DONE = 1004;
86 private static final int EVENT_QUERY_SMSC_DONE = 1005;
87 private static final int EVENT_UPDATE_SMSC_DONE = 1006;
88
89 private static final int MENU_ITEM_SELECT_BAND = 0;
90 private static final int MENU_ITEM_VIEW_ADN = 1;
91 private static final int MENU_ITEM_VIEW_FDN = 2;
92 private static final int MENU_ITEM_VIEW_SDN = 3;
93 private static final int MENU_ITEM_GET_PDP_LIST = 4;
94 private static final int MENU_ITEM_TOGGLE_DATA = 5;
95 private static final int MENU_ITEM_TOGGLE_DATA_ON_BOOT = 6;
96
97 private TextView mImei;
98 private TextView mImsi;
99 private TextView number;
100 private TextView callState;
101 private TextView operatorName;
102 private TextView roamingState;
103 private TextView gsmState;
104 private TextView gprsState;
105 private TextView network;
106 private TextView dBm;
107 private TextView mMwi;
108 private TextView mCfi;
109 private TextView mLocation;
110 private TextView mNeighboringCids;
111 private TextView resets;
112 private TextView attempts;
113 private TextView successes;
114 private TextView disconnects;
115 private TextView sentSinceReceived;
116 private TextView sent;
117 private TextView received;
118 private TextView mPingIpAddr;
119 private TextView mPingHostname;
120 private TextView mHttpClientTest;
121 private TextView cipherState;
The Android Open Source Project1feaa852009-02-10 15:44:05 -0800122 private TextView dnsCheckState;
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700123 private EditText smsc;
124 private Button radioPowerButton;
125 private Button qxdmLogButton;
126 private Button cipherToggleButton;
The Android Open Source Project1feaa852009-02-10 15:44:05 -0800127 private Button dnsCheckToggleButton;
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700128 private Button pingTestButton;
129 private Button updateSmscButton;
130 private Button refreshSmscButton;
131 private Spinner preferredNetworkType;
132
133 private TelephonyManager mTelephonyManager;
134 private Phone phone = null;
135 private PhoneStateIntentReceiver mPhoneStateReceiver;
136 private INetStatService netstat;
137
138 private OemCommands mOem = null;
139 private boolean mQxdmLogEnabled;
140 // The requested cipher state
141 private boolean mCipherOn;
142
143 private String mPingIpAddrResult;
144 private String mPingHostnameResult;
145 private String mHttpClientTestResult;
146 private boolean mMwiValue = false;
147 private boolean mCfiValue = false;
148
149 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
150 @Override
151 public void onDataConnectionStateChanged(int state) {
152 updateDataState();
153 updateDataStats();
154 updatePdpList();
155 updateNetworkType();
156 }
157
158 @Override
159 public void onDataActivity(int direction) {
160 updateDataStats2();
161 }
162
163 @Override
164 public void onCellLocationChanged(CellLocation location) {
165 updateLocation(location);
166 }
167
168 @Override
169 public void onMessageWaitingIndicatorChanged(boolean mwi) {
170 mMwiValue = mwi;
171 updateMessageWaiting();
172 }
173
174 @Override
175 public void onCallForwardingIndicatorChanged(boolean cfi) {
176 mCfiValue = cfi;
177 updateCallRedirect();
178 }
179 };
180
181 private Handler mHandler = new Handler() {
182 public void handleMessage(Message msg) {
183 AsyncResult ar;
184 switch (msg.what) {
185 case EVENT_PHONE_STATE_CHANGED:
186 updatePhoneState();
187 break;
188
189 case EVENT_SIGNAL_STRENGTH_CHANGED:
190 updateSignalStrength();
191 break;
192
193 case EVENT_SERVICE_STATE_CHANGED:
194 updateServiceState();
195 updatePowerState();
196 break;
197
198 case EVENT_QUERY_PREFERRED_TYPE_DONE:
199 ar= (AsyncResult) msg.obj;
200 if (ar.exception == null) {
201 int type = ((int[])ar.result)[0];
202 preferredNetworkType.setSelection(type, true);
203 } else {
204 preferredNetworkType.setSelection(3, true);
205 }
206 break;
207 case EVENT_SET_PREFERRED_TYPE_DONE:
208 ar= (AsyncResult) msg.obj;
209 if (ar.exception != null) {
210 phone.getPreferredNetworkType(
211 obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
212 }
213 break;
214 case EVENT_QUERY_NEIGHBORING_CIDS_DONE:
215 ar= (AsyncResult) msg.obj;
216 if (ar.exception == null) {
The Android Open Source Projectabc48f82008-12-17 18:06:01 -0800217 updateNeighboringCids((ArrayList<NeighboringCellInfo>)ar.result);
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700218 } else {
219 mNeighboringCids.setText("unknown");
220 }
221 break;
222 case EVENT_SET_QXDMLOG_DONE:
223 ar= (AsyncResult) msg.obj;
224 if (ar.exception == null) {
225 mQxdmLogEnabled = !mQxdmLogEnabled;
226
227 updateQxdmState(mQxdmLogEnabled);
228 displayQxdmEnableResult();
229 }
230 break;
231 case EVENT_SET_CIPHER_DONE:
232 ar= (AsyncResult) msg.obj;
233 if (ar.exception == null) {
234 setCiphPref(mCipherOn);
235 }
236 updateCiphState();
237 break;
238 case EVENT_QUERY_SMSC_DONE:
239 ar= (AsyncResult) msg.obj;
240 if (ar.exception != null) {
241 smsc.setText("refresh error");
242 } else {
243 byte[] buf = (byte[]) ar.result;
244 smsc.setText(new String(buf));
245 }
246 break;
247 case EVENT_UPDATE_SMSC_DONE:
248 updateSmscButton.setEnabled(true);
249 ar= (AsyncResult) msg.obj;
250 if (ar.exception != null) {
251 smsc.setText("update error");
252 }
253 break;
254 default:
255 break;
256
257 }
258 }
259 };
260
261 private class OemCommands {
262
263 public final int OEM_QXDM_SDLOG_DEFAULT_FILE_SIZE = 32;
264 public final int OEM_QXDM_SDLOG_DEFAULT_MASK = 0;
265 public final int OEM_QXDM_SDLOG_DEFAULT_MAX_INDEX = 8;
266
267 final int SIZE_OF_INT = 4;
268 final int OEM_FEATURE_ENABLE = 1;
269 final int OEM_FEATURE_DISABLE = 0;
270 final int OEM_SIMPE_FEAUTURE_LEN = 1;
271
272 final int OEM_QXDM_SDLOG_FUNCTAG = 0x00010000;
273 final int OEM_QXDM_SDLOG_LEN = 4;
274 final int OEM_PS_AUTO_ATTACH_FUNCTAG = 0x00020000;
275 final int OEM_CIPHERING_FUNCTAG = 0x00020001;
276 final int OEM_SMSC_UPDATE_FUNCTAG = 0x00020002;
277 final int OEM_SMSC_QUERY_FUNCTAG = 0x00020003;
278 final int OEM_SMSC_QUERY_LEN = 0;
279
280 /**
281 * The OEM interface to store QXDM to SD.
282 *
283 * To start/stop logging QXDM logs to SD card, use tag
284 * OEM_RIL_HOOK_QXDM_SD_LOG_SETUP 0x00010000
285 *
286 * "data" is a const oem_ril_hook_qxdm_sdlog_setup_data_st *
287 * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->head.func_tag
288 * should be OEM_RIL_HOOK_QXDM_SD_LOG_SETUP
289 * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->head.len
290 * should be "sizeof(unsigned int) * 4"
291 * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->mode
292 * could be 0 for 'stop logging', or 1 for 'start logging'
293 * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_file_size
294 * will assign the size of each log file, and it could be a value between
295 * 1 and 512 (in megabytes, default value is recommended to set as 32).
296 * This value will be ignored when mode == 0.
297 * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_mask will
298 * assign the rule to filter logs, and it is a bitmask (bit0 is for MsgAll,
299 * bit1 is for LogAll, and bit2 is for EventAll) recommended to be set as 0
300 * by default. This value will be ignored when mode == 0.
301 * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_max_fileindex
302 * set the how many logfiles will storted before roll over. This value will
303 * be ignored when mode == 0.
304 *
305 * "response" is NULL
306 *
307 * typedef struct _oem_ril_hook_raw_head_st {
308 * unsigned int func_tag;
309 * unsigned int len;
310 * } oem_ril_hook_raw_head_st;
311 *
312 * typedef struct _oem_ril_hook_qxdm_sdlog_setup_data_st {
313 * oem_ril_hook_raw_head_st head;
314 * unsigned int mode;
315 * unsigned int log_file_size;
316 * unsigned int log_mask;
317 * unsigned int log_max_fileindex;
318 * } oem_ril_hook_qxdm_sdlog_setup_data_st;
319 *
320 * @param enable set true to start logging QXDM in SD card
321 * @param fileSize is the log file size in MB
322 * @param mask is the log mask to filter
323 * @param maxIndex is the maximum roll-over file number
324 * @return byteArray to use in RIL RAW command
325 */
326 byte[] getQxdmSdlogData(boolean enable, int fileSize, int mask, int maxIndex) {
327 ByteArrayOutputStream bos = new ByteArrayOutputStream();
328 DataOutputStream dos = new DataOutputStream(bos);
329 try {
330 writeIntLittleEndian(dos, OEM_QXDM_SDLOG_FUNCTAG);
331 writeIntLittleEndian(dos, OEM_QXDM_SDLOG_LEN * SIZE_OF_INT);
332 writeIntLittleEndian(dos, enable ?
333 OEM_FEATURE_ENABLE : OEM_FEATURE_DISABLE);
334 writeIntLittleEndian(dos, fileSize);
335 writeIntLittleEndian(dos, mask);
336 writeIntLittleEndian(dos, maxIndex);
337 } catch (IOException e) {
338 return null;
339 }
340 return bos.toByteArray();
341 }
342
343 byte[] getSmscQueryData() {
344 ByteArrayOutputStream bos = new ByteArrayOutputStream();
345 DataOutputStream dos = new DataOutputStream(bos);
346 try {
347 writeIntLittleEndian(dos, OEM_SMSC_QUERY_FUNCTAG);
348 writeIntLittleEndian(dos, OEM_SMSC_QUERY_LEN * SIZE_OF_INT);
349 } catch (IOException e) {
350 return null;
351 }
352 return bos.toByteArray();
353 }
354
355 byte[] getSmscUpdateData(String smsc) {
356 ByteArrayOutputStream bos = new ByteArrayOutputStream();
357 DataOutputStream dos = new DataOutputStream(bos);
358 try {
359 byte[] smsc_bytes = smsc.getBytes();
360 writeIntLittleEndian(dos, OEM_SMSC_UPDATE_FUNCTAG);
361 writeIntLittleEndian(dos, smsc_bytes.length);
362 dos.write(smsc_bytes);
363 } catch (IOException e) {
364 return null;
365 }
366 return bos.toByteArray();
367 }
368
369 byte[] getPsAutoAttachData(boolean enable) {
370 return getSimpleFeatureData(OEM_PS_AUTO_ATTACH_FUNCTAG, enable);
371 }
372
373 byte[] getCipheringData(boolean enable) {
374 return getSimpleFeatureData(OEM_CIPHERING_FUNCTAG, enable);
375 }
376
377 private byte[] getSimpleFeatureData(int tag, boolean enable) {
378 ByteArrayOutputStream bos = new ByteArrayOutputStream();
379 DataOutputStream dos = new DataOutputStream(bos);
380 try {
381 writeIntLittleEndian(dos, tag);
382 writeIntLittleEndian(dos, OEM_SIMPE_FEAUTURE_LEN * SIZE_OF_INT);
383 writeIntLittleEndian(dos, enable ?
384 OEM_FEATURE_ENABLE : OEM_FEATURE_DISABLE);
385 } catch (IOException e) {
386 return null;
387 }
388 return bos.toByteArray();
389 }
390
391 private void writeIntLittleEndian(DataOutputStream dos, int val)
392 throws IOException {
393 dos.writeByte(val);
394 dos.writeByte(val >> 8);
395 dos.writeByte(val >> 16);
396 dos.writeByte(val >> 24);
397 }
398 }
399
400 @Override
401 public void onCreate(Bundle icicle) {
402 super.onCreate(icicle);
403
404 setContentView(R.layout.radio_info);
405
406 mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
407 phone = PhoneFactory.getDefaultPhone();
408
409 mImei = (TextView) findViewById(R.id.imei);
410 mImsi = (TextView) findViewById(R.id.imsi);
411 number = (TextView) findViewById(R.id.number);
412 callState = (TextView) findViewById(R.id.call);
413 operatorName = (TextView) findViewById(R.id.operator);
414 roamingState = (TextView) findViewById(R.id.roaming);
415 gsmState = (TextView) findViewById(R.id.gsm);
416 gprsState = (TextView) findViewById(R.id.gprs);
417 network = (TextView) findViewById(R.id.network);
418 dBm = (TextView) findViewById(R.id.dbm);
419 mMwi = (TextView) findViewById(R.id.mwi);
420 mCfi = (TextView) findViewById(R.id.cfi);
421 mLocation = (TextView) findViewById(R.id.location);
422 mNeighboringCids = (TextView) findViewById(R.id.neighboring);
423
424 resets = (TextView) findViewById(R.id.resets);
425 attempts = (TextView) findViewById(R.id.attempts);
426 successes = (TextView) findViewById(R.id.successes);
427 disconnects = (TextView) findViewById(R.id.disconnects);
428 sentSinceReceived = (TextView) findViewById(R.id.sentSinceReceived);
429 sent = (TextView) findViewById(R.id.sent);
430 received = (TextView) findViewById(R.id.received);
431 cipherState = (TextView) findViewById(R.id.ciphState);
432 smsc = (EditText) findViewById(R.id.smsc);
The Android Open Source Project1feaa852009-02-10 15:44:05 -0800433 dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700434
435 mPingIpAddr = (TextView) findViewById(R.id.pingIpAddr);
436 mPingHostname = (TextView) findViewById(R.id.pingHostname);
437 mHttpClientTest = (TextView) findViewById(R.id.httpClientTest);
438
439 preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
440 ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,
441 android.R.layout.simple_spinner_item, mPreferredNetworkLabels);
442 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
443 preferredNetworkType.setAdapter(adapter);
444 preferredNetworkType.setOnItemSelectedListener(mPreferredNetworkHandler);
445
446 radioPowerButton = (Button) findViewById(R.id.radio_power);
447 radioPowerButton.setOnClickListener(mPowerButtonHandler);
448
449 qxdmLogButton = (Button) findViewById(R.id.qxdm_log);
450 qxdmLogButton.setOnClickListener(mQxdmButtonHandler);
451
452 cipherToggleButton = (Button) findViewById(R.id.ciph_toggle);
453 cipherToggleButton.setOnClickListener(mCipherButtonHandler);
454 pingTestButton = (Button) findViewById(R.id.ping_test);
455 pingTestButton.setOnClickListener(mPingButtonHandler);
456 updateSmscButton = (Button) findViewById(R.id.update_smsc);
457 updateSmscButton.setOnClickListener(mUpdateSmscButtonHandler);
458 refreshSmscButton = (Button) findViewById(R.id.refresh_smsc);
459 refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
The Android Open Source Project1feaa852009-02-10 15:44:05 -0800460 dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
461 dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700462
463 mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler);
464 mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED);
465 mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
466 mPhoneStateReceiver.notifyPhoneCallState(EVENT_PHONE_STATE_CHANGED);
467
468 updateQxdmState(null);
469 mOem = new OemCommands();
470
471 phone.getPreferredNetworkType(
472 mHandler.obtainMessage(EVENT_QUERY_PREFERRED_TYPE_DONE));
473 phone.getNeighboringCids(
474 mHandler.obtainMessage(EVENT_QUERY_NEIGHBORING_CIDS_DONE));
475
476 netstat = INetStatService.Stub.asInterface(ServiceManager.getService("netstat"));
477
478 CellLocation.requestLocationUpdate();
479 }
480
481 @Override
482 protected void onResume() {
483 super.onResume();
484
485 updatePhoneState();
486 updateSignalStrength();
487 updateMessageWaiting();
488 updateCallRedirect();
489 updateServiceState();
490 updateLocation(mTelephonyManager.getCellLocation());
491 updateDataState();
492 updateDataStats();
493 updateDataStats2();
494 updatePowerState();
495 updateQxdmState(null);
496 updateProperties();
497 updateCiphState();
The Android Open Source Project1feaa852009-02-10 15:44:05 -0800498 updateDnsCheckState();
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700499
500 Log.i(TAG, "[RadioInfo] onResume: register phone & data intents");
501
502 mPhoneStateReceiver.registerIntent();
503 mTelephonyManager.listen(mPhoneStateListener,
504 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
505 | PhoneStateListener.LISTEN_DATA_ACTIVITY
506 | PhoneStateListener.LISTEN_CELL_LOCATION
507 | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
508 | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
509 }
510
511 @Override
512 public void onPause() {
513 super.onPause();
514
515 Log.i(TAG, "[RadioInfo] onPause: unregister phone & data intents");
516
517 mPhoneStateReceiver.unregisterIntent();
518 mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
519 }
520
521 @Override
522 public boolean onCreateOptionsMenu(Menu menu) {
523 menu.add(0, MENU_ITEM_SELECT_BAND, 0, R.string.radio_info_band_mode_label).setOnMenuItemClickListener(mSelectBandCallback)
524 .setAlphabeticShortcut('b');
525 menu.add(1, MENU_ITEM_VIEW_ADN, 0,
526 R.string.radioInfo_menu_viewADN).setOnMenuItemClickListener(mViewADNCallback);
527 menu.add(1, MENU_ITEM_VIEW_FDN, 0,
528 R.string.radioInfo_menu_viewFDN).setOnMenuItemClickListener(mViewFDNCallback);
529 menu.add(1, MENU_ITEM_VIEW_SDN, 0,
530 R.string.radioInfo_menu_viewSDN).setOnMenuItemClickListener(mViewSDNCallback);
531 menu.add(1, MENU_ITEM_GET_PDP_LIST,
532 0, R.string.radioInfo_menu_getPDP).setOnMenuItemClickListener(mGetPdpList);
533 menu.add(1, MENU_ITEM_TOGGLE_DATA,
534 0, R.string.radioInfo_menu_disableData).setOnMenuItemClickListener(mToggleData);
535 menu.add(1, MENU_ITEM_TOGGLE_DATA_ON_BOOT,
536 0, R.string.radioInfo_menu_disableDataOnBoot).setOnMenuItemClickListener(mToggleDataOnBoot);
537 return true;
538 }
539
540
541 @Override
542 public boolean onPrepareOptionsMenu(Menu menu)
543 {
544 // Get the TOGGLE DATA menu item in the right state.
545 MenuItem item = menu.findItem(MENU_ITEM_TOGGLE_DATA);
546 int state = mTelephonyManager.getDataState();
547 boolean visible = true;
548
549 switch (state) {
550 case TelephonyManager.DATA_CONNECTED:
551 case TelephonyManager.DATA_SUSPENDED:
552 item.setTitle(R.string.radioInfo_menu_disableData);
553 break;
554 case TelephonyManager.DATA_DISCONNECTED:
555 item.setTitle(R.string.radioInfo_menu_enableData);
556 break;
557 default:
558 visible = false;
559 break;
560 }
561 item.setVisible(visible);
562
563 // Get the toggle-data-on-boot menu item in the right state.
564 item = menu.findItem(MENU_ITEM_TOGGLE_DATA_ON_BOOT);
565 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.getApplication());
566 boolean value = sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false);
567 if (value) {
568 item.setTitle(R.string.radioInfo_menu_enableDataOnBoot);
569 } else {
570 item.setTitle(R.string.radioInfo_menu_disableDataOnBoot);
571 }
572 return true;
573 }
574
575 private boolean isRadioOn() {
576 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
577 }
578
579 private void updatePowerState() {
580 //log("updatePowerState");
581 String buttonText = isRadioOn() ?
582 getString(R.string.turn_off_radio) :
583 getString(R.string.turn_on_radio);
584 radioPowerButton.setText(buttonText);
585 }
586
587 private void updateQxdmState(Boolean newQxdmStatus) {
588 SharedPreferences sp =
589 PreferenceManager.getDefaultSharedPreferences(this.getApplication());
590 mQxdmLogEnabled = sp.getBoolean("qxdmstatus", false);
591 // This is called from onCreate, onResume, and the handler when the status
592 // is updated.
593 if (newQxdmStatus != null) {
594 SharedPreferences.Editor editor = sp.edit();
595 editor.putBoolean("qxdmstatus", newQxdmStatus);
596 editor.commit();
597 mQxdmLogEnabled = newQxdmStatus;
598 }
599
600 String buttonText = mQxdmLogEnabled ?
601 getString(R.string.turn_off_qxdm) :
602 getString(R.string.turn_on_qxdm);
603 qxdmLogButton.setText(buttonText);
604 }
605
606 private void setCiphPref(boolean value) {
607 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.getApplication());
608 SharedPreferences.Editor editor = sp.edit();
609 editor.putBoolean(GSMPhone.CIPHERING_KEY, value);
610 editor.commit();
611 }
612
613 private boolean getCiphPref() {
614 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.getApplication());
615 boolean ret = sp.getBoolean(GSMPhone.CIPHERING_KEY, true);
616 return ret;
617 }
618
619 private void updateCiphState() {
620 cipherState.setText(getCiphPref() ? "Ciphering ON" : "Ciphering OFF");
621 }
622
The Android Open Source Project1feaa852009-02-10 15:44:05 -0800623 private void updateDnsCheckState() {
624 GSMPhone gsmPhone = (GSMPhone) phone;
625 dnsCheckState.setText(gsmPhone.isDnsCheckDisabled() ?
626 "0.0.0.0 allowed" :"0.0.0.0 not allowed");
627 }
628
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700629 private final void
630 updateSignalStrength() {
631 int state =
632 mPhoneStateReceiver.getServiceState().getState();
633 Resources r = getResources();
634
635 if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
636 (ServiceState.STATE_POWER_OFF == state)) {
637 dBm.setText("0");
638 }
639
640 int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
641
642 if (-1 == signalDbm) signalDbm = 0;
643
644 int signalAsu = mPhoneStateReceiver.getSignalStrength();
645
646 if (-1 == signalAsu) signalAsu = 0;
647
648 dBm.setText(String.valueOf(signalDbm) + " "
649 + r.getString(R.string.radioInfo_display_dbm) + " "
650 + String.valueOf(signalAsu) + " "
651 + r.getString(R.string.radioInfo_display_asu));
652 }
653
654 private final void updateLocation(CellLocation location) {
655 GsmCellLocation loc = (GsmCellLocation)location;
656 Resources r = getResources();
657
658 int lac = loc.getLac();
659 int cid = loc.getCid();
660
661 mLocation.setText(r.getString(R.string.radioInfo_lac) + " = "
662 + ((lac == -1) ? "unknown" : Integer.toHexString(lac))
663 + " "
664 + r.getString(R.string.radioInfo_cid) + " = "
665 + ((cid == -1) ? "unknown" : Integer.toHexString(cid)));
666 }
667
The Android Open Source Projectabc48f82008-12-17 18:06:01 -0800668 private final void updateNeighboringCids(ArrayList<NeighboringCellInfo> cids) {
669 String neighborings = "";
670 if (cids != null) {
671 if ( cids.isEmpty() ) {
672 neighborings = "no neighboring cells";
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700673 } else {
The Android Open Source Projectabc48f82008-12-17 18:06:01 -0800674 for (NeighboringCellInfo cell : cids) {
675 neighborings += "{" + Integer.toHexString(cell.getCid())
676 + "@" + cell.getRssi() + "} ";
677 }
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700678 }
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700679 } else {
The Android Open Source Projectabc48f82008-12-17 18:06:01 -0800680 neighborings = "unknown";
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700681 }
The Android Open Source Projectabc48f82008-12-17 18:06:01 -0800682 mNeighboringCids.setText(neighborings);
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700683 }
684
685 private final void
686 updateMessageWaiting() {
687 mMwi.setText(String.valueOf(mMwiValue));
688 }
689
690 private final void
691 updateCallRedirect() {
692 mCfi.setText(String.valueOf(mCfiValue));
693 }
694
695
696 private final void
697 updateServiceState() {
698 ServiceState serviceState = mPhoneStateReceiver.getServiceState();
699 int state = serviceState.getState();
700 Resources r = getResources();
701 String display = r.getString(R.string.radioInfo_unknown);
702
703 switch (state) {
704 case ServiceState.STATE_IN_SERVICE:
705 display = r.getString(R.string.radioInfo_service_in);
706 break;
707 case ServiceState.STATE_OUT_OF_SERVICE:
708 case ServiceState.STATE_EMERGENCY_ONLY:
709 display = r.getString(R.string.radioInfo_service_emergency);
710 break;
711 case ServiceState.STATE_POWER_OFF:
712 display = r.getString(R.string.radioInfo_service_off);
713 break;
714 }
715
716 gsmState.setText(display);
717
718 if (serviceState.getRoaming()) {
719 roamingState.setText(R.string.radioInfo_roaming_in);
720 } else {
721 roamingState.setText(R.string.radioInfo_roaming_not);
722 }
723
724 operatorName.setText(serviceState.getOperatorAlphaLong());
725 }
726
727 private final void
728 updatePhoneState() {
729 Phone.State state = mPhoneStateReceiver.getPhoneState();
730 Resources r = getResources();
731 String display = r.getString(R.string.radioInfo_unknown);
732
733 switch (state) {
734 case IDLE:
735 display = r.getString(R.string.radioInfo_phone_idle);
736 break;
737 case RINGING:
738 display = r.getString(R.string.radioInfo_phone_ringing);
739 break;
740 case OFFHOOK:
741 display = r.getString(R.string.radioInfo_phone_offhook);
742 break;
743 }
744
745 callState.setText(display);
746 }
747
748 private final void
749 updateDataState() {
750 int state = mTelephonyManager.getDataState();
751 Resources r = getResources();
752 String display = r.getString(R.string.radioInfo_unknown);
753
754 switch (state) {
755 case TelephonyManager.DATA_CONNECTED:
756 display = r.getString(R.string.radioInfo_data_connected);
757 break;
758 case TelephonyManager.DATA_CONNECTING:
759 display = r.getString(R.string.radioInfo_data_connecting);
760 break;
761 case TelephonyManager.DATA_DISCONNECTED:
762 display = r.getString(R.string.radioInfo_data_disconnected);
763 break;
764 case TelephonyManager.DATA_SUSPENDED:
765 display = r.getString(R.string.radioInfo_data_suspended);
766 break;
767 }
768
769 gprsState.setText(display);
770 }
771
772 private final void updateNetworkType() {
773 Resources r = getResources();
774 String display = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
775 r.getString(R.string.radioInfo_unknown));
776
777 network.setText(display);
778 }
779
780 private final void
781 updateProperties() {
782 String s;
783 Resources r = getResources();
784
785 s = phone.getDeviceId();
786 if (s == null) s = r.getString(R.string.radioInfo_unknown);
787 mImei.setText(s);
788
789 s = phone.getSubscriberId();
790 if (s == null) s = r.getString(R.string.radioInfo_unknown);
791 mImsi.setText(s);
792
793 s = phone.getLine1Number();
794 if (s == null) s = r.getString(R.string.radioInfo_unknown);
795 number.setText(s);
796 }
797
798 private final void updateDataStats() {
799 String s;
800
801 s = SystemProperties.get("net.gsm.radio-reset", "0");
802 resets.setText(s);
803
804 s = SystemProperties.get("net.gsm.attempt-gprs", "0");
805 attempts.setText(s);
806
807 s = SystemProperties.get("net.gsm.succeed-gprs", "0");
808 successes.setText(s);
809
810 //s = SystemProperties.get("net.gsm.disconnect", "0");
811 //disconnects.setText(s);
812
813 s = SystemProperties.get("net.ppp.reset-by-timeout", "0");
814 sentSinceReceived.setText(s);
815 }
816
817 private final void updateDataStats2() {
818 Resources r = getResources();
819
820 try {
The Android Open Source Project1feaa852009-02-10 15:44:05 -0800821 long txPackets = netstat.getMobileTxPackets();
822 long rxPackets = netstat.getMobileRxPackets();
823 long txBytes = netstat.getMobileTxBytes();
824 long rxBytes = netstat.getMobileRxBytes();
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700825
826 String packets = r.getString(R.string.radioInfo_display_packets);
827 String bytes = r.getString(R.string.radioInfo_display_bytes);
828
829 sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
830 received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
831 } catch (RemoteException e) {
832 }
833 }
834
835 /**
836 * Ping a IP address.
837 */
838 private final void pingIpAddr() {
839 try {
840 // This is hardcoded IP addr. This is for testing purposes.
841 // We would need to get rid of this before release.
842 String ipAddress = "74.125.47.104";
843 Process p = Runtime.getRuntime().exec("ping -c 1 " + ipAddress);
844 int status = p.waitFor();
845 if (status == 0) {
846 mPingIpAddrResult = "Pass";
847 } else {
848 mPingIpAddrResult = "Fail: IP addr not reachable";
849 }
850 } catch (IOException e) {
851 mPingIpAddrResult = "Fail: IOException";
852 } catch (InterruptedException e) {
853 mPingIpAddrResult = "Fail: InterruptedException";
854 }
855 }
856
857 /**
858 * Ping a host name
859 */
860 private final void pingHostname() {
861 try {
862 Process p = Runtime.getRuntime().exec("ping -c 1 www.google.com");
863 int status = p.waitFor();
864 if (status == 0) {
865 mPingHostnameResult = "Pass";
866 } else {
867 mPingHostnameResult = "Fail: Host unreachable";
868 }
869 } catch (UnknownHostException e) {
870 mPingHostnameResult = "Fail: Unknown Host";
871 } catch (IOException e) {
872 mPingHostnameResult= "Fail: IOException";
873 } catch (InterruptedException e) {
874 mPingHostnameResult = "Fail: InterruptedException";
875 }
876 }
877
878 /**
879 * This function checks for basic functionality of HTTP Client.
880 */
881 private void httpClientTest() {
882 HttpClient client = new DefaultHttpClient();
883 try {
884 HttpGet request = new HttpGet("http://www.google.com");
885 HttpResponse response = client.execute(request);
886 if (response.getStatusLine().getStatusCode() == 200) {
887 mHttpClientTestResult = "Pass";
888 } else {
889 mHttpClientTestResult = "Fail: Code: " + String.valueOf(response);
890 }
891 request.abort();
892 } catch (IOException e) {
893 mHttpClientTestResult = "Fail: IOException";
894 }
895 }
896
897 private void refreshSmsc() {
898 byte[] data = mOem.getSmscQueryData();
899 if (data == null) return;
900 phone.invokeOemRilRequestRaw(data,
901 mHandler.obtainMessage(EVENT_QUERY_SMSC_DONE));
902 }
903
904 private final void updatePingState() {
905 final Handler handler = new Handler();
906 // Set all to unknown since the threads will take a few secs to update.
907 mPingIpAddrResult = getResources().getString(R.string.radioInfo_unknown);
908 mPingHostnameResult = getResources().getString(R.string.radioInfo_unknown);
909 mHttpClientTestResult = getResources().getString(R.string.radioInfo_unknown);
910
911 mPingIpAddr.setText(mPingIpAddrResult);
912 mPingHostname.setText(mPingHostnameResult);
913 mHttpClientTest.setText(mHttpClientTestResult);
914
915 final Runnable updatePingResults = new Runnable() {
916 public void run() {
917 mPingIpAddr.setText(mPingIpAddrResult);
918 mPingHostname.setText(mPingHostnameResult);
919 mHttpClientTest.setText(mHttpClientTestResult);
920 }
921 };
922 Thread ipAddr = new Thread() {
923 @Override
924 public void run() {
925 pingIpAddr();
926 handler.post(updatePingResults);
927 }
928 };
929 ipAddr.start();
930
931 Thread hostname = new Thread() {
932 @Override
933 public void run() {
934 pingHostname();
935 handler.post(updatePingResults);
936 }
937 };
938 hostname.start();
939
940 Thread httpClient = new Thread() {
941 @Override
942 public void run() {
943 httpClientTest();
944 handler.post(updatePingResults);
945 }
946 };
947 httpClient.start();
948 }
949
950 private final void updatePdpList() {
951 StringBuilder sb = new StringBuilder("========DATA=======\n");
952
953 List<PdpConnection> pdps = phone.getCurrentPdpList();
954
955 for (PdpConnection pdp : pdps) {
956 sb.append(" State: ").append(pdp.getState().toString()).append("\n");
957 if (pdp.getState().isActive()) {
958 long timeElapsed =
959 (System.currentTimeMillis() - pdp.getConnectionTime())/1000;
960 sb.append(" connected at ")
961 .append(DateUtils.timeString(pdp.getConnectionTime()))
962 .append(" and elapsed ")
963 .append(DateUtils.formatElapsedTime(timeElapsed))
964 .append("\n to ")
965 .append(pdp.getApn().toString())
966 .append("\ninterface: ")
The Android Open Source Projectabc48f82008-12-17 18:06:01 -0800967 .append(phone.getInterfaceName(phone.getActiveApnTypes()[0]))
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700968 .append("\naddress: ")
The Android Open Source Projectabc48f82008-12-17 18:06:01 -0800969 .append(phone.getIpAddress(phone.getActiveApnTypes()[0]))
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700970 .append("\ngateway: ")
The Android Open Source Projectabc48f82008-12-17 18:06:01 -0800971 .append(phone.getGateway(phone.getActiveApnTypes()[0]));
972 String[] dns = phone.getDnsServers(phone.getActiveApnTypes()[0]);
973 if (dns != null) {
974 sb.append("\ndns: ").append(dns[0]).append(", ").append(dns[1]);
975 }
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -0700976 } else if (pdp.getState().isInactive()) {
977 sb.append(" disconnected with last try at ")
978 .append(DateUtils.timeString(pdp.getLastFailTime()))
979 .append("\n fail because ")
980 .append(pdp.getLastFailCause().toString());
981 } else {
982 sb.append(" is connecting to ")
983 .append(pdp.getApn().toString());
984 }
985 sb.append("\n===================");
986 }
987
988
989 disconnects.setText(sb.toString());
990 }
991
992 private void displayQxdmEnableResult() {
993 String status = mQxdmLogEnabled ? "Start QXDM Log" : "Stop QXDM Log";
994
995 DialogInterface mProgressPanel = new AlertDialog.
996 Builder(this).setMessage(status).show();
997
998 mHandler.postDelayed(
999 new Runnable() {
1000 public void run() {
1001 finish();
1002 }
1003 }, 2000);
1004 }
1005
1006 private MenuItem.OnMenuItemClickListener mViewADNCallback = new MenuItem.OnMenuItemClickListener() {
1007 public boolean onMenuItemClick(MenuItem item) {
1008 Intent intent = new Intent(Intent.ACTION_VIEW);
1009 // XXX We need to specify the component here because if we don't
1010 // the activity manager will try to resolve the type by calling
1011 // the content provider, which causes it to be loaded in a process
1012 // other than the Dialer process, which causes a lot of stuff to
1013 // break.
1014 intent.setClassName("com.android.phone",
1015 "com.android.phone.SimContacts");
1016 startActivity(intent);
1017 return true;
1018 }
1019 };
1020
1021 private MenuItem.OnMenuItemClickListener mViewFDNCallback = new MenuItem.OnMenuItemClickListener() {
1022 public boolean onMenuItemClick(MenuItem item) {
1023 Intent intent = new Intent(Intent.ACTION_VIEW);
1024 // XXX We need to specify the component here because if we don't
1025 // the activity manager will try to resolve the type by calling
1026 // the content provider, which causes it to be loaded in a process
1027 // other than the Dialer process, which causes a lot of stuff to
1028 // break.
1029 intent.setClassName("com.android.phone",
1030 "com.android.phone.FdnList");
1031 startActivity(intent);
1032 return true;
1033 }
1034 };
1035
1036 private MenuItem.OnMenuItemClickListener mViewSDNCallback = new MenuItem.OnMenuItemClickListener() {
1037 public boolean onMenuItemClick(MenuItem item) {
1038 Intent intent = new Intent(
1039 Intent.ACTION_VIEW, Uri.parse("content://sim/sdn"));
1040 // XXX We need to specify the component here because if we don't
1041 // the activity manager will try to resolve the type by calling
1042 // the content provider, which causes it to be loaded in a process
1043 // other than the Dialer process, which causes a lot of stuff to
1044 // break.
1045 intent.setClassName("com.android.phone",
1046 "com.android.phone.ADNList");
1047 startActivity(intent);
1048 return true;
1049 }
1050 };
1051
1052 private void toggleDataDisabledOnBoot() {
1053 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.getApplication());
1054 SharedPreferences.Editor editor = sp.edit();
1055 boolean value = sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false);
1056 editor.putBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, !value);
1057 byte[] data = mOem.getPsAutoAttachData(value);
1058 if (data == null) {
1059 // don't commit
1060 return;
1061 }
1062
1063 editor.commit();
1064 phone.invokeOemRilRequestRaw(data, null);
1065 }
1066
1067 private MenuItem.OnMenuItemClickListener mToggleDataOnBoot = new MenuItem.OnMenuItemClickListener() {
1068 public boolean onMenuItemClick(MenuItem item) {
1069 toggleDataDisabledOnBoot();
1070 return true;
1071 }
1072 };
1073
1074 private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
1075 public boolean onMenuItemClick(MenuItem item) {
1076 int state = mTelephonyManager.getDataState();
1077 switch (state) {
1078 case TelephonyManager.DATA_CONNECTED:
1079 phone.disableDataConnectivity();
1080 break;
1081 case TelephonyManager.DATA_DISCONNECTED:
1082 phone.enableDataConnectivity();
1083 break;
1084 default:
1085 // do nothing
1086 break;
1087 }
1088 return true;
1089 }
1090 };
1091
1092 private MenuItem.OnMenuItemClickListener mGetPdpList = new MenuItem.OnMenuItemClickListener() {
1093 public boolean onMenuItemClick(MenuItem item) {
1094 phone.getPdpContextList(null);
1095 return true;
1096 }
1097 };
1098
1099 private MenuItem.OnMenuItemClickListener mSelectBandCallback = new MenuItem.OnMenuItemClickListener() {
1100 public boolean onMenuItemClick(MenuItem item) {
1101 Intent intent = new Intent();
1102 intent.setClass(RadioInfo.this, BandMode.class);
1103 startActivity(intent);
1104 return true;
1105 }
1106 };
1107
1108 OnClickListener mPowerButtonHandler = new OnClickListener() {
1109 public void onClick(View v) {
1110 //log("toggle radio power: currently " + (isRadioOn()?"on":"off"));
1111 phone.setRadioPower(!isRadioOn());
1112 }
1113 };
1114
1115 OnClickListener mCipherButtonHandler = new OnClickListener() {
1116 public void onClick(View v) {
1117 mCipherOn = !getCiphPref();
1118 byte[] data = mOem.getCipheringData(mCipherOn);
1119
1120 if (data == null)
1121 return;
1122
1123 cipherState.setText("Setting...");
1124 phone.invokeOemRilRequestRaw(data,
1125 mHandler.obtainMessage(EVENT_SET_CIPHER_DONE));
1126 }
1127 };
1128
The Android Open Source Project1feaa852009-02-10 15:44:05 -08001129 OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
1130 public void onClick(View v) {
1131 GSMPhone gsmPhone = (GSMPhone) phone;
1132 gsmPhone.disableDnsCheck(!gsmPhone.isDnsCheckDisabled());
1133 updateDnsCheckState();
1134 }
1135 };
1136
The Android Open Source Projectde2d9f52008-10-21 07:00:00 -07001137 OnClickListener mPingButtonHandler = new OnClickListener() {
1138 public void onClick(View v) {
1139 updatePingState();
1140 }
1141 };
1142
1143 OnClickListener mUpdateSmscButtonHandler = new OnClickListener() {
1144 public void onClick(View v) {
1145 updateSmscButton.setEnabled(false);
1146 byte[] data = mOem.getSmscUpdateData(smsc.getText().toString());
1147 if (data == null) return;
1148 phone.invokeOemRilRequestRaw(data,
1149 mHandler.obtainMessage(EVENT_UPDATE_SMSC_DONE));
1150 }
1151 };
1152
1153 OnClickListener mRefreshSmscButtonHandler = new OnClickListener() {
1154 public void onClick(View v) {
1155 refreshSmsc();
1156 }
1157 };
1158
1159 OnClickListener mQxdmButtonHandler = new OnClickListener() {
1160 public void onClick(View v) {
1161 byte[] data = mOem.getQxdmSdlogData(
1162 !mQxdmLogEnabled,
1163 mOem.OEM_QXDM_SDLOG_DEFAULT_FILE_SIZE,
1164 mOem.OEM_QXDM_SDLOG_DEFAULT_MASK,
1165 mOem.OEM_QXDM_SDLOG_DEFAULT_MAX_INDEX);
1166
1167 if (data == null)
1168 return;
1169
1170 phone.invokeOemRilRequestRaw(data,
1171 mHandler.obtainMessage(EVENT_SET_QXDMLOG_DONE));
1172 }
1173 };
1174
1175 AdapterView.OnItemSelectedListener
1176 mPreferredNetworkHandler = new AdapterView.OnItemSelectedListener() {
1177 public void onItemSelected(AdapterView parent, View v, int pos, long id) {
1178 Message msg = mHandler.obtainMessage(EVENT_SET_PREFERRED_TYPE_DONE);
1179 if (pos>=0 && pos<=2) {
1180 phone.setPreferredNetworkType(pos, msg);
1181 }
1182 }
1183
1184 public void onNothingSelected(AdapterView parent) {
1185 }
1186 };
1187
1188 private String[] mPreferredNetworkLabels = {
1189 "WCDMA preferred", "GSM only", "WCDMA only", "Unknown"};
1190}