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