Home | History | Annotate | Download | only in deviceinfo
      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 static android.content.Context.CONNECTIVITY_SERVICE;
     20 import static android.content.Context.WIFI_SERVICE;
     21 
     22 import android.bluetooth.BluetoothAdapter;
     23 import android.content.BroadcastReceiver;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.IntentFilter;
     27 import android.content.res.Resources;
     28 import android.net.ConnectivityManager;
     29 import android.net.wifi.WifiInfo;
     30 import android.net.wifi.WifiManager;
     31 import android.os.Build;
     32 import android.os.Bundle;
     33 import android.os.Handler;
     34 import android.os.Message;
     35 import android.os.SystemClock;
     36 import android.os.SystemProperties;
     37 import android.os.UserManager;
     38 import android.support.v7.preference.Preference;
     39 import android.text.TextUtils;
     40 
     41 import com.android.internal.logging.MetricsProto.MetricsEvent;
     42 import com.android.internal.util.ArrayUtils;
     43 import com.android.settings.R;
     44 import com.android.settings.SettingsPreferenceFragment;
     45 import com.android.settings.Utils;
     46 
     47 import java.lang.ref.WeakReference;
     48 
     49 /**
     50  * Display the following information
     51  * # Battery Strength  : TODO
     52  * # Uptime
     53  * # Awake Time
     54  * # XMPP/buzz/tickle status : TODO
     55  *
     56  */
     57 public class Status extends SettingsPreferenceFragment {
     58 
     59     private static final String KEY_BATTERY_STATUS = "battery_status";
     60     private static final String KEY_BATTERY_LEVEL = "battery_level";
     61     private static final String KEY_IP_ADDRESS = "wifi_ip_address";
     62     private static final String KEY_WIFI_MAC_ADDRESS = "wifi_mac_address";
     63     private static final String KEY_BT_ADDRESS = "bt_address";
     64     private static final String KEY_SERIAL_NUMBER = "serial_number";
     65     private static final String KEY_WIMAX_MAC_ADDRESS = "wimax_mac_address";
     66     private static final String KEY_SIM_STATUS = "sim_status";
     67     private static final String KEY_IMEI_INFO = "imei_info";
     68 
     69     // Broadcasts to listen to for connectivity changes.
     70     private static final String[] CONNECTIVITY_INTENTS = {
     71             BluetoothAdapter.ACTION_STATE_CHANGED,
     72             ConnectivityManager.CONNECTIVITY_ACTION,
     73             WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
     74             WifiManager.NETWORK_STATE_CHANGED_ACTION,
     75     };
     76 
     77     private static final int EVENT_UPDATE_STATS = 500;
     78 
     79     private static final int EVENT_UPDATE_CONNECTIVITY = 600;
     80 
     81     private ConnectivityManager mCM;
     82     private WifiManager mWifiManager;
     83 
     84     private Resources mRes;
     85 
     86     private String mUnknown;
     87     private String mUnavailable;
     88 
     89     private Preference mUptime;
     90     private Preference mBatteryStatus;
     91     private Preference mBatteryLevel;
     92     private Preference mBtAddress;
     93     private Preference mIpAddress;
     94     private Preference mWifiMacAddress;
     95     private Preference mWimaxMacAddress;
     96 
     97     private Handler mHandler;
     98 
     99     private static class MyHandler extends Handler {
    100         private WeakReference<Status> mStatus;
    101 
    102         public MyHandler(Status activity) {
    103             mStatus = new WeakReference<Status>(activity);
    104         }
    105 
    106         @Override
    107         public void handleMessage(Message msg) {
    108             Status status = mStatus.get();
    109             if (status == null) {
    110                 return;
    111             }
    112 
    113             switch (msg.what) {
    114                 case EVENT_UPDATE_STATS:
    115                     status.updateTimes();
    116                     sendEmptyMessageDelayed(EVENT_UPDATE_STATS, 1000);
    117                     break;
    118 
    119                 case EVENT_UPDATE_CONNECTIVITY:
    120                     status.updateConnectivity();
    121                     break;
    122             }
    123         }
    124     }
    125 
    126     private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
    127 
    128         @Override
    129         public void onReceive(Context context, Intent intent) {
    130             String action = intent.getAction();
    131             if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
    132                 mBatteryLevel.setSummary(Utils.getBatteryPercentage(intent));
    133                 mBatteryStatus.setSummary(Utils.getBatteryStatus(getResources(), intent));
    134             }
    135         }
    136     };
    137 
    138     private IntentFilter mConnectivityIntentFilter;
    139     private final BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() {
    140         @Override
    141         public void onReceive(Context context, Intent intent) {
    142             String action = intent.getAction();
    143             if (ArrayUtils.contains(CONNECTIVITY_INTENTS, action)) {
    144                 mHandler.sendEmptyMessage(EVENT_UPDATE_CONNECTIVITY);
    145             }
    146         }
    147     };
    148 
    149     private boolean hasBluetooth() {
    150         return BluetoothAdapter.getDefaultAdapter() != null;
    151     }
    152 
    153     private boolean hasWimax() {
    154         return  mCM.getNetworkInfo(ConnectivityManager.TYPE_WIMAX) != null;
    155     }
    156 
    157     @Override
    158     public void onCreate(Bundle icicle) {
    159         super.onCreate(icicle);
    160 
    161         mHandler = new MyHandler(this);
    162 
    163         mCM = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
    164         mWifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
    165 
    166         addPreferencesFromResource(R.xml.device_info_status);
    167         mBatteryLevel = findPreference(KEY_BATTERY_LEVEL);
    168         mBatteryStatus = findPreference(KEY_BATTERY_STATUS);
    169         mBtAddress = findPreference(KEY_BT_ADDRESS);
    170         mWifiMacAddress = findPreference(KEY_WIFI_MAC_ADDRESS);
    171         mWimaxMacAddress = findPreference(KEY_WIMAX_MAC_ADDRESS);
    172         mIpAddress = findPreference(KEY_IP_ADDRESS);
    173 
    174         mRes = getResources();
    175         mUnknown = mRes.getString(R.string.device_info_default);
    176         mUnavailable = mRes.getString(R.string.status_unavailable);
    177 
    178         // Note - missing in zaku build, be careful later...
    179         mUptime = findPreference("up_time");
    180 
    181         if (!hasBluetooth()) {
    182             getPreferenceScreen().removePreference(mBtAddress);
    183             mBtAddress = null;
    184         }
    185 
    186         if (!hasWimax()) {
    187             getPreferenceScreen().removePreference(mWimaxMacAddress);
    188             mWimaxMacAddress = null;
    189         }
    190 
    191         mConnectivityIntentFilter = new IntentFilter();
    192         for (String intent: CONNECTIVITY_INTENTS) {
    193              mConnectivityIntentFilter.addAction(intent);
    194         }
    195 
    196         updateConnectivity();
    197 
    198         String serial = Build.SERIAL;
    199         if (serial != null && !serial.equals("")) {
    200             setSummaryText(KEY_SERIAL_NUMBER, serial);
    201         } else {
    202             removePreferenceFromScreen(KEY_SERIAL_NUMBER);
    203         }
    204 
    205         // Remove SimStatus and Imei for Secondary user as it access Phone b/19165700
    206         // Also remove on Wi-Fi only devices.
    207         //TODO: the bug above will surface in split system user mode.
    208         if (!UserManager.get(getContext()).isAdminUser()
    209                 || Utils.isWifiOnly(getContext())) {
    210             removePreferenceFromScreen(KEY_SIM_STATUS);
    211             removePreferenceFromScreen(KEY_IMEI_INFO);
    212         }
    213     }
    214 
    215     @Override
    216     protected int getMetricsCategory() {
    217         return MetricsEvent.DEVICEINFO_STATUS;
    218     }
    219 
    220     @Override
    221     public void onResume() {
    222         super.onResume();
    223         getContext().registerReceiver(mConnectivityReceiver, mConnectivityIntentFilter,
    224                          android.Manifest.permission.CHANGE_NETWORK_STATE, null);
    225         getContext().registerReceiver(mBatteryInfoReceiver,
    226                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    227         mHandler.sendEmptyMessage(EVENT_UPDATE_STATS);
    228     }
    229 
    230     @Override
    231     public void onPause() {
    232         super.onPause();
    233 
    234         getContext().unregisterReceiver(mBatteryInfoReceiver);
    235         getContext().unregisterReceiver(mConnectivityReceiver);
    236         mHandler.removeMessages(EVENT_UPDATE_STATS);
    237     }
    238 
    239     /**
    240      * Removes the specified preference, if it exists.
    241      * @param key the key for the Preference item
    242      */
    243     private void removePreferenceFromScreen(String key) {
    244         Preference pref = findPreference(key);
    245         if (pref != null) {
    246             getPreferenceScreen().removePreference(pref);
    247         }
    248     }
    249 
    250     /**
    251      * @param preference The key for the Preference item
    252      * @param property The system property to fetch
    253      * @param alt The default value, if the property doesn't exist
    254      */
    255     private void setSummary(String preference, String property, String alt) {
    256         try {
    257             findPreference(preference).setSummary(
    258                     SystemProperties.get(property, alt));
    259         } catch (RuntimeException e) {
    260 
    261         }
    262     }
    263 
    264     private void setSummaryText(String preference, String text) {
    265             if (TextUtils.isEmpty(text)) {
    266                text = mUnknown;
    267              }
    268              // some preferences may be missing
    269              if (findPreference(preference) != null) {
    270                  findPreference(preference).setSummary(text);
    271              }
    272     }
    273 
    274     private void setWimaxStatus() {
    275         if (mWimaxMacAddress != null) {
    276             String macAddress = SystemProperties.get("net.wimax.mac.address", mUnavailable);
    277             mWimaxMacAddress.setSummary(macAddress);
    278         }
    279     }
    280 
    281     private void setWifiStatus() {
    282         WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
    283         String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
    284         mWifiMacAddress.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress : mUnavailable);
    285     }
    286 
    287     private void setIpAddressStatus() {
    288         String ipAddress = Utils.getDefaultIpAddresses(this.mCM);
    289         if (ipAddress != null) {
    290             mIpAddress.setSummary(ipAddress);
    291         } else {
    292             mIpAddress.setSummary(mUnavailable);
    293         }
    294     }
    295 
    296     private void setBtStatus() {
    297         BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
    298         if (bluetooth != null && mBtAddress != null) {
    299             String address = bluetooth.isEnabled() ? bluetooth.getAddress() : null;
    300             if (!TextUtils.isEmpty(address)) {
    301                // Convert the address to lowercase for consistency with the wifi MAC address.
    302                 mBtAddress.setSummary(address.toLowerCase());
    303             } else {
    304                 mBtAddress.setSummary(mUnavailable);
    305             }
    306         }
    307     }
    308 
    309     void updateConnectivity() {
    310         setWimaxStatus();
    311         setWifiStatus();
    312         setBtStatus();
    313         setIpAddressStatus();
    314     }
    315 
    316     void updateTimes() {
    317         long at = SystemClock.uptimeMillis() / 1000;
    318         long ut = SystemClock.elapsedRealtime() / 1000;
    319 
    320         if (ut == 0) {
    321             ut = 1;
    322         }
    323 
    324         mUptime.setSummary(convert(ut));
    325     }
    326 
    327     private String pad(int n) {
    328         if (n >= 10) {
    329             return String.valueOf(n);
    330         } else {
    331             return "0" + String.valueOf(n);
    332         }
    333     }
    334 
    335     private String convert(long t) {
    336         int s = (int)(t % 60);
    337         int m = (int)((t / 60) % 60);
    338         int h = (int)((t / 3600));
    339 
    340         return h + ":" + pad(m) + ":" + pad(s);
    341     }
    342 }
    343