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 MyHandler(Status activity)102 public MyHandler(Status activity) { 103 mStatus = new WeakReference<Status>(activity); 104 } 105 106 @Override handleMessage(Message msg)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 hasBluetooth()149 private boolean hasBluetooth() { 150 return BluetoothAdapter.getDefaultAdapter() != null; 151 } 152 hasWimax()153 private boolean hasWimax() { 154 return mCM.getNetworkInfo(ConnectivityManager.TYPE_WIMAX) != null; 155 } 156 157 @Override onCreate(Bundle icicle)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 getMetricsCategory()216 protected int getMetricsCategory() { 217 return MetricsEvent.DEVICEINFO_STATUS; 218 } 219 220 @Override onResume()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 onPause()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 */ removePreferenceFromScreen(String key)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 */ setSummary(String preference, String property, String alt)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 setSummaryText(String preference, String text)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 setWimaxStatus()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 setWifiStatus()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 setIpAddressStatus()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 setBtStatus()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 updateConnectivity()309 void updateConnectivity() { 310 setWimaxStatus(); 311 setWifiStatus(); 312 setBtStatus(); 313 setIpAddressStatus(); 314 } 315 updateTimes()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 pad(int n)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 convert(long t)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