• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.deviceinfo;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.res.Resources;
25 import android.net.ConnectivityManager;
26 import android.net.NetworkInfo;
27 import android.net.wifi.WifiInfo;
28 import android.net.wifi.WifiManager;
29 import android.os.BatteryManager;
30 import android.os.Bundle;
31 import android.os.Handler;
32 import android.os.Message;
33 import android.os.SystemClock;
34 import android.os.SystemProperties;
35 import android.preference.Preference;
36 import android.preference.PreferenceActivity;
37 import android.preference.PreferenceScreen;
38 import android.telephony.PhoneNumberUtils;
39 import android.telephony.PhoneStateListener;
40 import android.telephony.ServiceState;
41 import android.telephony.TelephonyManager;
42 import android.text.TextUtils;
43 
44 import com.android.internal.telephony.Phone;
45 import com.android.internal.telephony.PhoneFactory;
46 import com.android.internal.telephony.PhoneStateIntentReceiver;
47 import com.android.internal.telephony.TelephonyProperties;
48 import com.android.settings.R;
49 
50 import java.lang.ref.WeakReference;
51 
52 /**
53  * Display the following information
54  * # Phone Number
55  * # Network
56  * # Roaming
57  * # Device Id (IMEI in GSM and MEID in CDMA)
58  * # Network type
59  * # Signal Strength
60  * # Battery Strength  : TODO
61  * # Uptime
62  * # Awake Time
63  * # XMPP/buzz/tickle status : TODO
64  *
65  */
66 public class Status extends PreferenceActivity {
67 
68     private static final String KEY_WIMAX_MAC_ADDRESS = "wimax_mac_address";
69     private static final String KEY_WIFI_MAC_ADDRESS = "wifi_mac_address";
70     private static final String KEY_BT_ADDRESS = "bt_address";
71     private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
72     private static final int EVENT_SERVICE_STATE_CHANGED = 300;
73 
74     private static final int EVENT_UPDATE_STATS = 500;
75 
76     private TelephonyManager mTelephonyManager;
77     private Phone mPhone = null;
78     private PhoneStateIntentReceiver mPhoneStateReceiver;
79     private Resources mRes;
80     private Preference mSignalStrength;
81     private Preference mUptime;
82 
83     private static String sUnknown;
84 
85     private Preference mBatteryStatus;
86     private Preference mBatteryLevel;
87 
88     private Handler mHandler;
89 
90     private static class MyHandler extends Handler {
91         private WeakReference<Status> mStatus;
92 
MyHandler(Status activity)93         public MyHandler(Status activity) {
94             mStatus = new WeakReference<Status>(activity);
95         }
96 
97         @Override
handleMessage(Message msg)98         public void handleMessage(Message msg) {
99             Status status = mStatus.get();
100             if (status == null) {
101                 return;
102             }
103 
104             switch (msg.what) {
105                 case EVENT_SIGNAL_STRENGTH_CHANGED:
106                     status.updateSignalStrength();
107                     break;
108 
109                 case EVENT_SERVICE_STATE_CHANGED:
110                     ServiceState serviceState = status.mPhoneStateReceiver.getServiceState();
111                     status.updateServiceState(serviceState);
112                     break;
113 
114                 case EVENT_UPDATE_STATS:
115                     status.updateTimes();
116                     sendEmptyMessageDelayed(EVENT_UPDATE_STATS, 1000);
117                     break;
118             }
119         }
120     }
121 
122     private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
123 
124         @Override
125         public void onReceive(Context context, Intent intent) {
126             String action = intent.getAction();
127             if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
128 
129                 int level = intent.getIntExtra("level", 0);
130                 int scale = intent.getIntExtra("scale", 100);
131 
132                 mBatteryLevel.setSummary(String.valueOf(level * 100 / scale) + "%");
133 
134                 int plugType = intent.getIntExtra("plugged", 0);
135                 int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
136                 String statusString;
137                 if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
138                     statusString = getString(R.string.battery_info_status_charging);
139                     if (plugType > 0) {
140                         statusString = statusString + " " + getString(
141                                 (plugType == BatteryManager.BATTERY_PLUGGED_AC)
142                                         ? R.string.battery_info_status_charging_ac
143                                         : R.string.battery_info_status_charging_usb);
144                     }
145                 } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
146                     statusString = getString(R.string.battery_info_status_discharging);
147                 } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
148                     statusString = getString(R.string.battery_info_status_not_charging);
149                 } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
150                     statusString = getString(R.string.battery_info_status_full);
151                 } else {
152                     statusString = getString(R.string.battery_info_status_unknown);
153                 }
154                 mBatteryStatus.setSummary(statusString);
155             }
156         }
157     };
158 
159     private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
160         @Override
161         public void onDataConnectionStateChanged(int state) {
162             updateDataState();
163             updateNetworkType();
164         }
165     };
166 
167     @Override
onCreate(Bundle icicle)168     protected void onCreate(Bundle icicle) {
169         super.onCreate(icicle);
170         Preference removablePref;
171 
172         mHandler = new MyHandler(this);
173 
174         mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
175 
176         addPreferencesFromResource(R.xml.device_info_status);
177         mBatteryLevel = findPreference("battery_level");
178         mBatteryStatus = findPreference("battery_status");
179 
180         mRes = getResources();
181         if (sUnknown == null) {
182             sUnknown = mRes.getString(R.string.device_info_default);
183         }
184 
185         mPhone = PhoneFactory.getDefaultPhone();
186         // Note - missing in zaku build, be careful later...
187         mSignalStrength = findPreference("signal_strength");
188         mUptime = findPreference("up_time");
189 
190         //NOTE "imei" is the "Device ID" since it represents the IMEI in GSM and the MEID in CDMA
191         if (mPhone.getPhoneName().equals("CDMA")) {
192             setSummaryText("meid_number", mPhone.getMeid());
193             setSummaryText("min_number", mPhone.getCdmaMin());
194             if (getResources().getBoolean(R.bool.config_msid_enable)) {
195                 findPreference("min_number").setTitle(R.string.status_msid_number);
196             }
197             setSummaryText("prl_version", mPhone.getCdmaPrlVersion());
198 
199             // device is not GSM/UMTS, do not display GSM/UMTS features
200             // check Null in case no specified preference in overlay xml
201             removablePref = findPreference("imei");
202             if (removablePref != null) {
203                 getPreferenceScreen().removePreference(removablePref);
204             }
205             removablePref = findPreference("imei_sv");
206             if (removablePref != null) {
207                 getPreferenceScreen().removePreference(removablePref);
208             }
209         } else {
210             setSummaryText("imei", mPhone.getDeviceId());
211 
212             setSummaryText("imei_sv",
213                     ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
214                         .getDeviceSoftwareVersion());
215 
216             // device is not CDMA, do not display CDMA features
217             // check Null in case no specified preference in overlay xml
218             removablePref = findPreference("prl_version");
219             if (removablePref != null) {
220                 getPreferenceScreen().removePreference(removablePref);
221             }
222             removablePref = findPreference("meid_number");
223             if (removablePref != null) {
224                 getPreferenceScreen().removePreference(removablePref);
225             }
226             removablePref = findPreference("min_number");
227             if (removablePref != null) {
228                 getPreferenceScreen().removePreference(removablePref);
229             }
230         }
231 
232         String rawNumber = mPhone.getLine1Number();  // may be null or empty
233         String formattedNumber = null;
234         if (!TextUtils.isEmpty(rawNumber)) {
235             formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
236         }
237         // If formattedNumber is null or empty, it'll display as "Unknown".
238         setSummaryText("number", formattedNumber);
239 
240         mPhoneStateReceiver = new PhoneStateIntentReceiver(this, mHandler);
241         mPhoneStateReceiver.notifySignalStrength(EVENT_SIGNAL_STRENGTH_CHANGED);
242         mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
243 
244         setWimaxStatus();
245         setWifiStatus();
246         setBtStatus();
247     }
248 
249     @Override
onResume()250     protected void onResume() {
251         super.onResume();
252 
253         mPhoneStateReceiver.registerIntent();
254         registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
255 
256         updateSignalStrength();
257         updateServiceState(mPhone.getServiceState());
258         updateDataState();
259 
260         mTelephonyManager.listen(mPhoneStateListener,
261                   PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
262 
263         mHandler.sendEmptyMessage(EVENT_UPDATE_STATS);
264     }
265 
266     @Override
onPause()267     public void onPause() {
268         super.onPause();
269 
270         mPhoneStateReceiver.unregisterIntent();
271         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
272         unregisterReceiver(mBatteryInfoReceiver);
273         mHandler.removeMessages(EVENT_UPDATE_STATS);
274     }
275 
276     /**
277      * @param preference The key for the Preference item
278      * @param property The system property to fetch
279      * @param alt The default value, if the property doesn't exist
280      */
setSummary(String preference, String property, String alt)281     private void setSummary(String preference, String property, String alt) {
282         try {
283             findPreference(preference).setSummary(
284                     SystemProperties.get(property, alt));
285         } catch (RuntimeException e) {
286 
287         }
288     }
289 
setSummaryText(String preference, String text)290     private void setSummaryText(String preference, String text) {
291             if (TextUtils.isEmpty(text)) {
292                text = sUnknown;
293              }
294              // some preferences may be missing
295              if (findPreference(preference) != null) {
296                  findPreference(preference).setSummary(text);
297              }
298     }
299 
updateNetworkType()300     private void updateNetworkType() {
301         // Whether EDGE, UMTS, etc...
302         setSummary("network_type", TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, sUnknown);
303     }
304 
updateDataState()305     private void updateDataState() {
306         int state = mTelephonyManager.getDataState();
307         String display = mRes.getString(R.string.radioInfo_unknown);
308 
309         switch (state) {
310             case TelephonyManager.DATA_CONNECTED:
311                 display = mRes.getString(R.string.radioInfo_data_connected);
312                 break;
313             case TelephonyManager.DATA_SUSPENDED:
314                 display = mRes.getString(R.string.radioInfo_data_suspended);
315                 break;
316             case TelephonyManager.DATA_CONNECTING:
317                 display = mRes.getString(R.string.radioInfo_data_connecting);
318                 break;
319             case TelephonyManager.DATA_DISCONNECTED:
320                 display = mRes.getString(R.string.radioInfo_data_disconnected);
321                 break;
322         }
323 
324         setSummaryText("data_state", display);
325     }
326 
updateServiceState(ServiceState serviceState)327     private void updateServiceState(ServiceState serviceState) {
328         int state = serviceState.getState();
329         String display = mRes.getString(R.string.radioInfo_unknown);
330 
331         switch (state) {
332             case ServiceState.STATE_IN_SERVICE:
333                 display = mRes.getString(R.string.radioInfo_service_in);
334                 break;
335             case ServiceState.STATE_OUT_OF_SERVICE:
336             case ServiceState.STATE_EMERGENCY_ONLY:
337                 display = mRes.getString(R.string.radioInfo_service_out);
338                 break;
339             case ServiceState.STATE_POWER_OFF:
340                 display = mRes.getString(R.string.radioInfo_service_off);
341                 break;
342         }
343 
344         setSummaryText("service_state", display);
345 
346         if (serviceState.getRoaming()) {
347             setSummaryText("roaming_state", mRes.getString(R.string.radioInfo_roaming_in));
348         } else {
349             setSummaryText("roaming_state", mRes.getString(R.string.radioInfo_roaming_not));
350         }
351         setSummaryText("operator_name", serviceState.getOperatorAlphaLong());
352     }
353 
updateSignalStrength()354     void updateSignalStrength() {
355         // TODO PhoneStateIntentReceiver is deprecated and PhoneStateListener
356         // should probably used instead.
357 
358         // not loaded in some versions of the code (e.g., zaku)
359         if (mSignalStrength != null) {
360             int state =
361                     mPhoneStateReceiver.getServiceState().getState();
362             Resources r = getResources();
363 
364             if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
365                     (ServiceState.STATE_POWER_OFF == state)) {
366                 mSignalStrength.setSummary("0");
367             }
368 
369             int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
370 
371             if (-1 == signalDbm) signalDbm = 0;
372 
373             int signalAsu = mPhoneStateReceiver.getSignalStrength();
374 
375             if (-1 == signalAsu) signalAsu = 0;
376 
377             mSignalStrength.setSummary(String.valueOf(signalDbm) + " "
378                         + r.getString(R.string.radioInfo_display_dbm) + "   "
379                         + String.valueOf(signalAsu) + " "
380                         + r.getString(R.string.radioInfo_display_asu));
381         }
382     }
383 
setWimaxStatus()384     private void setWimaxStatus() {
385         ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
386         NetworkInfo ni = cm.getNetworkInfo(ConnectivityManager.TYPE_WIMAX);
387 
388         if (ni == null) {
389             PreferenceScreen root = getPreferenceScreen();
390             Preference ps = (Preference) findPreference(KEY_WIMAX_MAC_ADDRESS);
391             if (ps != null)
392                 root.removePreference(ps);
393         } else {
394             Preference wimaxMacAddressPref = findPreference(KEY_WIMAX_MAC_ADDRESS);
395             String macAddress = SystemProperties.get("net.wimax.mac.address",
396                     getString(R.string.status_unavailable));
397             wimaxMacAddressPref.setSummary(macAddress);
398         }
399     }
400 
setWifiStatus()401     private void setWifiStatus() {
402         WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
403         WifiInfo wifiInfo = wifiManager.getConnectionInfo();
404 
405         Preference wifiMacAddressPref = findPreference(KEY_WIFI_MAC_ADDRESS);
406         String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
407         wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress
408                 : getString(R.string.status_unavailable));
409     }
410 
setBtStatus()411     private void setBtStatus() {
412         BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
413         Preference btAddressPref = findPreference(KEY_BT_ADDRESS);
414 
415         if (bluetooth == null) {
416             // device not BT capable
417             getPreferenceScreen().removePreference(btAddressPref);
418         } else {
419             String address = bluetooth.isEnabled() ? bluetooth.getAddress() : null;
420             btAddressPref.setSummary(!TextUtils.isEmpty(address) ? address
421                     : getString(R.string.status_unavailable));
422         }
423     }
424 
updateTimes()425     void updateTimes() {
426         long at = SystemClock.uptimeMillis() / 1000;
427         long ut = SystemClock.elapsedRealtime() / 1000;
428 
429         if (ut == 0) {
430             ut = 1;
431         }
432 
433         mUptime.setSummary(convert(ut));
434     }
435 
pad(int n)436     private String pad(int n) {
437         if (n >= 10) {
438             return String.valueOf(n);
439         } else {
440             return "0" + String.valueOf(n);
441         }
442     }
443 
convert(long t)444     private String convert(long t) {
445         int s = (int)(t % 60);
446         int m = (int)((t / 60) % 60);
447         int h = (int)((t / 3600));
448 
449         return h + ":" + pad(m) + ":" + pad(s);
450     }
451 }
452