StatusBarPolicy.java revision 347c5a22a915df5aa180573573adf6b2213a35dc
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.server.status; 18 19import android.app.AlertDialog; 20import android.bluetooth.BluetoothA2dp; 21import android.bluetooth.BluetoothAdapter; 22import android.bluetooth.BluetoothError; 23import android.bluetooth.BluetoothHeadset; 24import android.bluetooth.BluetoothIntent; 25import android.bluetooth.BluetoothPbap; 26import android.content.BroadcastReceiver; 27import android.content.Context; 28import android.content.DialogInterface; 29import android.content.Intent; 30import android.content.IntentFilter; 31import android.content.res.TypedArray; 32import android.graphics.PixelFormat; 33import android.graphics.drawable.Drawable; 34import android.media.AudioManager; 35import android.net.NetworkInfo; 36import android.net.wifi.WifiManager; 37import android.os.Binder; 38import android.os.Handler; 39import android.os.IBinder; 40import android.os.Message; 41import android.os.RemoteException; 42import android.provider.Settings; 43import android.telephony.PhoneStateListener; 44import android.telephony.ServiceState; 45import android.telephony.SignalStrength; 46import android.telephony.TelephonyManager; 47import android.text.format.DateFormat; 48import android.util.Log; 49import android.view.View; 50import android.view.ViewGroup; 51import android.view.WindowManager; 52import android.view.WindowManagerImpl; 53import android.widget.ImageView; 54import android.widget.LinearLayout; 55import android.widget.TextView; 56 57import com.android.internal.R; 58import com.android.internal.app.IBatteryStats; 59import com.android.internal.location.GpsLocationProvider; 60import com.android.internal.telephony.IccCard; 61import com.android.internal.telephony.TelephonyIntents; 62import com.android.internal.telephony.cdma.EriInfo; 63import com.android.internal.telephony.cdma.TtyIntent; 64import com.android.server.am.BatteryStatsService; 65 66import java.util.Calendar; 67import java.util.TimeZone; 68 69/** 70 * This class contains all of the policy about which icons are installed in the status 71 * bar at boot time. In reality, it should go into the android.policy package, but 72 * putting it here is the first step from extracting it. 73 */ 74public class StatusBarPolicy { 75 private static final String TAG = "StatusBarPolicy"; 76 77 private static StatusBarPolicy sInstance; 78 79 // message codes for the handler 80 private static final int EVENT_BATTERY_CLOSE = 4; 81 82 private final Context mContext; 83 private final StatusBarService mService; 84 private final Handler mHandler = new StatusBarHandler(); 85 private final IBatteryStats mBatteryStats; 86 87 // clock 88 private Calendar mCalendar; 89 private IBinder mClockIcon; 90 private IconData mClockData; 91 92 // battery 93 private IBinder mBatteryIcon; 94 private IconData mBatteryData; 95 private boolean mBatteryFirst = true; 96 private boolean mBatteryPlugged; 97 private int mBatteryLevel; 98 private AlertDialog mLowBatteryDialog; 99 private TextView mBatteryLevelTextView; 100 private View mBatteryView; 101 private int mBatteryViewSequence; 102 private boolean mBatteryShowLowOnEndCall = false; 103 private static final boolean SHOW_LOW_BATTERY_WARNING = true; 104 105 // phone 106 private TelephonyManager mPhone; 107 private IBinder mPhoneIcon; 108 109 //***** Signal strength icons 110 private IconData mPhoneData; 111 //GSM/UMTS 112 private static final int[] sSignalImages = new int[] { 113 com.android.internal.R.drawable.stat_sys_signal_0, 114 com.android.internal.R.drawable.stat_sys_signal_1, 115 com.android.internal.R.drawable.stat_sys_signal_2, 116 com.android.internal.R.drawable.stat_sys_signal_3, 117 com.android.internal.R.drawable.stat_sys_signal_4 118 }; 119 private static final int[] sSignalImages_r = new int[] { 120 com.android.internal.R.drawable.stat_sys_r_signal_0, 121 com.android.internal.R.drawable.stat_sys_r_signal_1, 122 com.android.internal.R.drawable.stat_sys_r_signal_2, 123 com.android.internal.R.drawable.stat_sys_r_signal_3, 124 com.android.internal.R.drawable.stat_sys_r_signal_4 125 }; 126 private static final int[] sRoamingIndicatorImages_cdma = new int[] { 127 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //Standard Roaming Indicator 128 // 1 is Standard Roaming Indicator OFF 129 // TODO T: image never used, remove and put 0 instead? 130 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 131 132 // 2 is Standard Roaming Indicator FLASHING 133 // TODO T: image never used, remove and put 0 instead? 134 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 135 136 // 3-12 Standard ERI 137 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //3 138 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 139 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 140 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 141 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 142 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 143 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 144 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 145 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 146 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 147 148 // 13-63 Reserved for Standard ERI 149 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //13 150 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 151 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 152 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 153 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 154 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 155 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 156 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 157 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 158 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 159 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 160 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 161 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 162 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 163 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 164 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 165 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 166 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 167 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 168 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 169 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 170 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 171 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 172 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 173 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 174 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 175 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 176 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 177 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 178 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 179 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 180 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 181 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 182 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 183 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 184 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 185 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 186 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 187 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 188 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 189 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 190 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 191 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 192 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 193 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 194 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 195 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 196 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 197 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 198 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 199 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 200 201 // 64-127 Reserved for Non Standard (Operator Specific) ERI 202 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //64 203 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 204 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 205 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 206 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 207 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 208 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 209 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 210 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 211 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 212 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 213 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 214 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 215 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 216 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 217 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 218 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 219 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 220 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 221 com.android.internal.R.drawable.stat_sys_roaming_cdma_0 //83 222 223 // 128-255 Reserved 224 }; 225 226 //***** Data connection icons 227 private int[] mDataIconList = sDataNetType_g; 228 //GSM/UMTS 229 private static final int[] sDataNetType_g = new int[] { 230 com.android.internal.R.drawable.stat_sys_data_connected_g, 231 com.android.internal.R.drawable.stat_sys_data_in_g, 232 com.android.internal.R.drawable.stat_sys_data_out_g, 233 com.android.internal.R.drawable.stat_sys_data_inandout_g, 234 }; 235 private static final int[] sDataNetType_3g = new int[] { 236 com.android.internal.R.drawable.stat_sys_data_connected_3g, 237 com.android.internal.R.drawable.stat_sys_data_in_3g, 238 com.android.internal.R.drawable.stat_sys_data_out_3g, 239 com.android.internal.R.drawable.stat_sys_data_inandout_3g, 240 }; 241 private static final int[] sDataNetType_e = new int[] { 242 com.android.internal.R.drawable.stat_sys_data_connected_e, 243 com.android.internal.R.drawable.stat_sys_data_in_e, 244 com.android.internal.R.drawable.stat_sys_data_out_e, 245 com.android.internal.R.drawable.stat_sys_data_inandout_e, 246 }; 247 //3.5G 248 private static final int[] sDataNetType_h = new int[] { 249 com.android.internal.R.drawable.stat_sys_data_connected_h, 250 com.android.internal.R.drawable.stat_sys_data_in_h, 251 com.android.internal.R.drawable.stat_sys_data_out_h, 252 com.android.internal.R.drawable.stat_sys_data_inandout_h, 253 }; 254 255 //CDMA 256 private static final int[] sDataNetType_evdo = new int[] { 257 com.android.internal.R.drawable.stat_sys_data_connected_evdo, 258 com.android.internal.R.drawable.stat_sys_data_in_evdo, 259 com.android.internal.R.drawable.stat_sys_data_out_evdo, 260 com.android.internal.R.drawable.stat_sys_data_inandout_evdo, 261 com.android.internal.R.drawable.stat_sys_data_dormant_evdo, 262 }; 263 private static final int[] sDataNetType_1xrtt = new int[] { 264 com.android.internal.R.drawable.stat_sys_data_connected_1xrtt, 265 com.android.internal.R.drawable.stat_sys_data_in_1xrtt, 266 com.android.internal.R.drawable.stat_sys_data_out_1xrtt, 267 com.android.internal.R.drawable.stat_sys_data_inandout_1xrtt, 268 com.android.internal.R.drawable.stat_sys_data_dormant_1xrtt, 269 }; 270 271 // Assume it's all good unless we hear otherwise. We don't always seem 272 // to get broadcasts that it *is* there. 273 IccCard.State mSimState = IccCard.State.READY; 274 int mPhoneState = TelephonyManager.CALL_STATE_IDLE; 275 int mDataState = TelephonyManager.DATA_DISCONNECTED; 276 int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE; 277 ServiceState mServiceState; 278 SignalStrength mSignalStrength; 279 280 // data connection 281 private IBinder mDataIcon; 282 private IconData mDataData; 283 private boolean mDataIconVisible; 284 285 // ringer volume 286 private IBinder mVolumeIcon; 287 private IconData mVolumeData; 288 private boolean mVolumeVisible; 289 290 // bluetooth device status 291 private IBinder mBluetoothIcon; 292 private IconData mBluetoothData; 293 private int mBluetoothHeadsetState; 294 private int mBluetoothA2dpState; 295 private int mBluetoothPbapState; 296 private boolean mBluetoothEnabled; 297 298 // wifi 299 private static final int[] sWifiSignalImages = new int[] { 300 com.android.internal.R.drawable.stat_sys_wifi_signal_1, 301 com.android.internal.R.drawable.stat_sys_wifi_signal_2, 302 com.android.internal.R.drawable.stat_sys_wifi_signal_3, 303 com.android.internal.R.drawable.stat_sys_wifi_signal_4, 304 }; 305 private static final int sWifiTemporarilyNotConnectedImage = 306 com.android.internal.R.drawable.stat_sys_wifi_signal_0; 307 308 private int mLastWifiSignalLevel = -1; 309 private boolean mIsWifiConnected = false; 310 private IBinder mWifiIcon; 311 private IconData mWifiData; 312 313 // gps 314 private IBinder mGpsIcon; 315 private IconData mGpsEnabledIconData; 316 private IconData mGpsFixIconData; 317 318 // alarm clock 319 // Icon lit when clock is set 320 private IBinder mAlarmClockIcon; 321 private IconData mAlarmClockIconData; 322 323 // sync state 324 // If sync is active the SyncActive icon is displayed. If sync is not active but 325 // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed. 326 private IBinder mSyncActiveIcon; 327 private IBinder mSyncFailingIcon; 328 329 // TTY mode 330 // Icon lit when TTY mode is enabled 331 private IBinder mTTYModeIcon; 332 private IconData mTTYModeEnableIconData; 333 334 // Cdma Roaming Indicator, ERI 335 private IBinder mCdmaRoamingIndicatorIcon; 336 private IconData mCdmaRoamingIndicatorIconData; 337 338 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 339 @Override 340 public void onReceive(Context context, Intent intent) { 341 String action = intent.getAction(); 342 if (action.equals(Intent.ACTION_TIME_TICK)) { 343 updateClock(); 344 } 345 else if (action.equals(Intent.ACTION_TIME_CHANGED)) { 346 updateClock(); 347 } 348 else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { 349 updateBattery(intent); 350 } 351 else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { 352 updateClock(); 353 } 354 else if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) { 355 String tz = intent.getStringExtra("time-zone"); 356 mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz)); 357 updateClock(); 358 } 359 else if (action.equals(Intent.ACTION_ALARM_CHANGED)) { 360 updateAlarm(intent); 361 } 362 else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) { 363 updateSyncState(intent); 364 } 365 else if (action.equals(Intent.ACTION_BATTERY_LOW)) { 366 onBatteryLow(intent); 367 } 368 else if (action.equals(Intent.ACTION_BATTERY_OKAY) 369 || action.equals(Intent.ACTION_POWER_CONNECTED)) { 370 onBatteryOkay(intent); 371 } 372 else if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION) || 373 action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION) || 374 action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION) || 375 action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) { 376 updateBluetooth(intent); 377 } 378 else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) || 379 action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) || 380 action.equals(WifiManager.RSSI_CHANGED_ACTION)) { 381 updateWifi(intent); 382 } 383 else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION) || 384 action.equals(GpsLocationProvider.GPS_FIX_CHANGE_ACTION)) { 385 updateGps(intent); 386 } 387 else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) || 388 action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) { 389 updateVolume(); 390 } 391 else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { 392 updateSimState(intent); 393 } 394 else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) { 395 updateTTY(intent); 396 } 397 } 398 }; 399 400 private StatusBarPolicy(Context context, StatusBarService service) { 401 mContext = context; 402 mService = service; 403 mSignalStrength = new SignalStrength(); 404 mBatteryStats = BatteryStatsService.getService(); 405 406 // clock 407 mCalendar = Calendar.getInstance(TimeZone.getDefault()); 408 mClockData = IconData.makeText("clock", ""); 409 mClockIcon = service.addIcon(mClockData, null); 410 updateClock(); 411 412 // battery 413 mBatteryData = IconData.makeIcon("battery", 414 null, com.android.internal.R.drawable.stat_sys_battery_unknown, 0, 0); 415 mBatteryIcon = service.addIcon(mBatteryData, null); 416 417 // phone_signal 418 mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 419 mPhoneData = IconData.makeIcon("phone_signal", 420 null, com.android.internal.R.drawable.stat_sys_signal_null, 0, 0); 421 mPhoneIcon = service.addIcon(mPhoneData, null); 422 423 // register for phone state notifications. 424 ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE)) 425 .listen(mPhoneStateListener, 426 PhoneStateListener.LISTEN_SERVICE_STATE 427 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS 428 | PhoneStateListener.LISTEN_CALL_STATE 429 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE 430 | PhoneStateListener.LISTEN_DATA_ACTIVITY); 431 432 // data_connection 433 mDataData = IconData.makeIcon("data_connection", 434 null, com.android.internal.R.drawable.stat_sys_data_connected_g, 0, 0); 435 mDataIcon = service.addIcon(mDataData, null); 436 service.setIconVisibility(mDataIcon, false); 437 438 // wifi 439 mWifiData = IconData.makeIcon("wifi", null, sWifiSignalImages[0], 0, 0); 440 mWifiIcon = service.addIcon(mWifiData, null); 441 service.setIconVisibility(mWifiIcon, false); 442 // wifi will get updated by the sticky intents 443 444 // TTY status 445 mTTYModeEnableIconData = IconData.makeIcon("tty", 446 null, com.android.internal.R.drawable.stat_sys_tty_mode, 0, 0); 447 mTTYModeIcon = service.addIcon(mTTYModeEnableIconData, null); 448 service.setIconVisibility(mTTYModeIcon, false); 449 450 // Cdma Roaming Indicator, ERI 451 mCdmaRoamingIndicatorIconData = IconData.makeIcon("cdma_eri", 452 null, com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 0, 0); 453 mCdmaRoamingIndicatorIcon = service.addIcon(mCdmaRoamingIndicatorIconData, null); 454 service.setIconVisibility(mCdmaRoamingIndicatorIcon, false); 455 456 // bluetooth status 457 mBluetoothData = IconData.makeIcon("bluetooth", 458 null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0); 459 mBluetoothIcon = service.addIcon(mBluetoothData, null); 460 BluetoothAdapter adapter = 461 (BluetoothAdapter) mContext.getSystemService(Context.BLUETOOTH_SERVICE); 462 if (adapter != null) { 463 mBluetoothEnabled = adapter.isEnabled(); 464 } else { 465 mBluetoothEnabled = false; 466 } 467 mBluetoothA2dpState = BluetoothA2dp.STATE_DISCONNECTED; 468 mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED; 469 mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED; 470 mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled); 471 472 // Gps status 473 mGpsEnabledIconData = IconData.makeIcon("gps", 474 null, com.android.internal.R.drawable.stat_sys_gps_acquiring_anim, 0, 0); 475 mGpsFixIconData = IconData.makeIcon("gps", 476 null, com.android.internal.R.drawable.stat_sys_gps_on, 0, 0); 477 mGpsIcon = service.addIcon(mGpsEnabledIconData, null); 478 service.setIconVisibility(mGpsIcon, false); 479 480 // Alarm clock 481 mAlarmClockIconData = IconData.makeIcon( 482 "alarm_clock", 483 null, com.android.internal.R.drawable.stat_notify_alarm, 0, 0); 484 mAlarmClockIcon = service.addIcon(mAlarmClockIconData, null); 485 service.setIconVisibility(mAlarmClockIcon, false); 486 487 // Sync state 488 mSyncActiveIcon = service.addIcon(IconData.makeIcon("sync_active", 489 null, R.drawable.stat_notify_sync_anim0, 0, 0), null); 490 mSyncFailingIcon = service.addIcon(IconData.makeIcon("sync_failing", 491 null, R.drawable.stat_notify_sync_error, 0, 0), null); 492 service.setIconVisibility(mSyncActiveIcon, false); 493 service.setIconVisibility(mSyncFailingIcon, false); 494 495 // volume 496 mVolumeData = IconData.makeIcon("volume", 497 null, com.android.internal.R.drawable.stat_sys_ringer_silent, 0, 0); 498 mVolumeIcon = service.addIcon(mVolumeData, null); 499 service.setIconVisibility(mVolumeIcon, false); 500 updateVolume(); 501 502 IntentFilter filter = new IntentFilter(); 503 504 // Register for Intent broadcasts for... 505 filter.addAction(Intent.ACTION_TIME_TICK); 506 filter.addAction(Intent.ACTION_TIME_CHANGED); 507 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 508 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 509 filter.addAction(Intent.ACTION_BATTERY_LOW); 510 filter.addAction(Intent.ACTION_BATTERY_OKAY); 511 filter.addAction(Intent.ACTION_POWER_CONNECTED); 512 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 513 filter.addAction(Intent.ACTION_ALARM_CHANGED); 514 filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED); 515 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); 516 filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); 517 filter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION); 518 filter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION); 519 filter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION); 520 filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION); 521 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 522 filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); 523 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 524 filter.addAction(WifiManager.RSSI_CHANGED_ACTION); 525 filter.addAction(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION); 526 filter.addAction(GpsLocationProvider.GPS_FIX_CHANGE_ACTION); 527 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 528 filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION); 529 mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); 530 } 531 532 public static void installIcons(Context context, StatusBarService service) { 533 sInstance = new StatusBarPolicy(context, service); 534 } 535 536 private final void updateClock() { 537 mCalendar.setTimeInMillis(System.currentTimeMillis()); 538 mClockData.text = DateFormat.getTimeFormat(mContext) 539 .format(mCalendar.getTime()); 540 mService.updateIcon(mClockIcon, mClockData, null); 541 } 542 543 private final void updateAlarm(Intent intent) { 544 boolean alarmSet = intent.getBooleanExtra("alarmSet", false); 545 mService.setIconVisibility(mAlarmClockIcon, alarmSet); 546 } 547 548 private final void updateSyncState(Intent intent) { 549 boolean isActive = intent.getBooleanExtra("active", false); 550 boolean isFailing = intent.getBooleanExtra("failing", false); 551 mService.setIconVisibility(mSyncActiveIcon, isActive); 552 // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never" 553 //mService.setIconVisibility(mSyncFailingIcon, isFailing && !isActive); 554 } 555 556 private final void updateBattery(Intent intent) { 557 mBatteryData.iconId = intent.getIntExtra("icon-small", 0); 558 mBatteryData.iconLevel = intent.getIntExtra("level", 0); 559 mService.updateIcon(mBatteryIcon, mBatteryData, null); 560 561 boolean plugged = intent.getIntExtra("plugged", 0) != 0; 562 int level = intent.getIntExtra("level", -1); 563 if (false) { 564 Log.d(TAG, "updateBattery level=" + level 565 + " plugged=" + plugged 566 + " mBatteryPlugged=" + mBatteryPlugged 567 + " mBatteryLevel=" + mBatteryLevel 568 + " mBatteryFirst=" + mBatteryFirst); 569 } 570 571 boolean oldPlugged = mBatteryPlugged; 572 573 mBatteryPlugged = plugged; 574 mBatteryLevel = level; 575 576 if (mBatteryFirst) { 577 mBatteryFirst = false; 578 } 579 /* 580 * No longer showing the battery view because it draws attention away 581 * from the USB storage notification. We could still show it when 582 * connected to a brick, but that could lead to the user into thinking 583 * the device does not charge when plugged into USB (since he/she would 584 * not see the same battery screen on USB as he sees on brick). 585 */ 586 /* else { 587 if (plugged && !oldPlugged) { 588 showBatteryView(); 589 } 590 } 591 */ 592 if (false) { 593 Log.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level); 594 } 595 } 596 597 private void onBatteryLow(Intent intent) { 598 if (SHOW_LOW_BATTERY_WARNING) { 599 if (false) { 600 Log.d(TAG, "mPhoneState=" + mPhoneState 601 + " mLowBatteryDialog=" + mLowBatteryDialog 602 + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall); 603 } 604 605 if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) { 606 showLowBatteryWarning(); 607 } else { 608 mBatteryShowLowOnEndCall = true; 609 } 610 } 611 } 612 613 private void onBatteryOkay(Intent intent) { 614 if (mLowBatteryDialog != null 615 && SHOW_LOW_BATTERY_WARNING) { 616 mLowBatteryDialog.dismiss(); 617 mBatteryShowLowOnEndCall = false; 618 } 619 } 620 621 private void showBatteryView() { 622 closeLastBatteryView(); 623 if (mLowBatteryDialog != null) { 624 mLowBatteryDialog.dismiss(); 625 } 626 627 int level = mBatteryLevel; 628 629 View v = View.inflate(mContext, com.android.internal.R.layout.battery_status, null); 630 mBatteryView = v; 631 int pixelFormat = PixelFormat.TRANSLUCENT; 632 Drawable bg = v.getBackground(); 633 if (bg != null) { 634 pixelFormat = bg.getOpacity(); 635 } 636 637 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 638 ViewGroup.LayoutParams.WRAP_CONTENT, 639 ViewGroup.LayoutParams.WRAP_CONTENT, 640 WindowManager.LayoutParams.TYPE_TOAST, 641 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 642 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 643 | WindowManager.LayoutParams.FLAG_BLUR_BEHIND 644 | WindowManager.LayoutParams.FLAG_DIM_BEHIND, 645 pixelFormat); 646 647 // Get the dim amount from the theme 648 TypedArray a = mContext.obtainStyledAttributes( 649 com.android.internal.R.styleable.Theme); 650 lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f); 651 a.recycle(); 652 653 lp.setTitle("Battery"); 654 655 TextView levelTextView = (TextView)v.findViewById(com.android.internal.R.id.level_percent); 656 levelTextView.setText(mContext.getString( 657 com.android.internal.R.string.battery_status_text_percent_format, level)); 658 659 setBatteryLevel(v, com.android.internal.R.id.spacer, 100-level, 0, 0); 660 setBatteryLevel(v, com.android.internal.R.id.level, level, 661 com.android.internal.R.drawable.battery_charge_fill, level); 662 663 WindowManagerImpl.getDefault().addView(v, lp); 664 665 scheduleCloseBatteryView(); 666 } 667 668 private void setBatteryLevel(View parent, int id, int height, int background, int level) { 669 ImageView v = (ImageView)parent.findViewById(id); 670 LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)v.getLayoutParams(); 671 lp.weight = height; 672 if (background != 0) { 673 v.setBackgroundResource(background); 674 Drawable bkg = v.getBackground(); 675 bkg.setLevel(level); 676 } 677 } 678 679 private void showLowBatteryWarning() { 680 closeLastBatteryView(); 681 682 /* Show exact battery level. 683 * Add 1 because the text says "less than X%". 684 */ 685 CharSequence levelText = mContext.getString( 686 com.android.internal.R.string.battery_low_percent_format, mBatteryLevel + 1); 687 688 if (mBatteryLevelTextView != null) { 689 mBatteryLevelTextView.setText(levelText); 690 } else { 691 View v = View.inflate(mContext, com.android.internal.R.layout.battery_low, null); 692 mBatteryLevelTextView=(TextView)v.findViewById(com.android.internal.R.id.level_percent); 693 694 mBatteryLevelTextView.setText(levelText); 695 696 AlertDialog.Builder b = new AlertDialog.Builder(mContext); 697 b.setCancelable(true); 698 b.setTitle(com.android.internal.R.string.battery_low_title); 699 b.setView(v); 700 b.setIcon(android.R.drawable.ic_dialog_alert); 701 b.setPositiveButton(android.R.string.ok, null); 702 703 final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY); 704 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 705 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK 706 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 707 | Intent.FLAG_ACTIVITY_NO_HISTORY); 708 if (intent.resolveActivity(mContext.getPackageManager()) != null) { 709 b.setNegativeButton(com.android.internal.R.string.battery_low_why, 710 new DialogInterface.OnClickListener() { 711 public void onClick(DialogInterface dialog, int which) { 712 mContext.startActivity(intent); 713 if (mLowBatteryDialog != null) { 714 mLowBatteryDialog.dismiss(); 715 } 716 } 717 }); 718 } 719 720 AlertDialog d = b.create(); 721 d.setOnDismissListener(mLowBatteryListener); 722 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 723 d.show(); 724 mLowBatteryDialog = d; 725 } 726 } 727 728 private final void updateCallState(int state) { 729 mPhoneState = state; 730 if (false) { 731 Log.d(TAG, "mPhoneState=" + mPhoneState 732 + " mLowBatteryDialog=" + mLowBatteryDialog 733 + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall); 734 } 735 if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) { 736 if (mBatteryShowLowOnEndCall) { 737 if (!mBatteryPlugged) { 738 showLowBatteryWarning(); 739 } 740 mBatteryShowLowOnEndCall = false; 741 } 742 } else { 743 if (mLowBatteryDialog != null) { 744 mLowBatteryDialog.dismiss(); 745 mBatteryShowLowOnEndCall = true; 746 } 747 } 748 } 749 750 private DialogInterface.OnDismissListener mLowBatteryListener 751 = new DialogInterface.OnDismissListener() { 752 public void onDismiss(DialogInterface dialog) { 753 mLowBatteryDialog = null; 754 mBatteryLevelTextView = null; 755 } 756 }; 757 758 private void scheduleCloseBatteryView() { 759 Message m = mHandler.obtainMessage(EVENT_BATTERY_CLOSE); 760 m.arg1 = (++mBatteryViewSequence); 761 mHandler.sendMessageDelayed(m, 3000); 762 } 763 764 private void closeLastBatteryView() { 765 if (mBatteryView != null) { 766 //mBatteryView.debug(); 767 WindowManagerImpl.getDefault().removeView(mBatteryView); 768 mBatteryView = null; 769 } 770 } 771 772 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 773 @Override 774 public void onSignalStrengthsChanged(SignalStrength signalStrength) { 775 mSignalStrength = signalStrength; 776 updateSignalStrength(); 777 } 778 779 @Override 780 public void onServiceStateChanged(ServiceState state) { 781 mServiceState = state; 782 updateSignalStrength(); 783 updateCdmaRoamingIcon(); 784 updateDataIcon(); 785 } 786 787 @Override 788 public void onCallStateChanged(int state, String incomingNumber) { 789 updateCallState(state); 790 // In cdma, if a voice call is made, RSSI should switch to 1x. 791 if (isCdma()) { 792 updateSignalStrength(); 793 } 794 } 795 796 @Override 797 public void onDataConnectionStateChanged(int state) { 798 mDataState = state; 799 updateDataNetType(); 800 updateDataIcon(); 801 } 802 803 @Override 804 public void onDataActivity(int direction) { 805 mDataActivity = direction; 806 updateDataIcon(); 807 } 808 }; 809 810 private final void updateSimState(Intent intent) { 811 String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); 812 if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { 813 mSimState = IccCard.State.ABSENT; 814 } 815 else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { 816 mSimState = IccCard.State.READY; 817 } 818 else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { 819 final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); 820 if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { 821 mSimState = IccCard.State.PIN_REQUIRED; 822 } 823 else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { 824 mSimState = IccCard.State.PUK_REQUIRED; 825 } 826 else { 827 mSimState = IccCard.State.NETWORK_LOCKED; 828 } 829 } else { 830 mSimState = IccCard.State.UNKNOWN; 831 } 832 updateDataIcon(); 833 } 834 835 private boolean isCdma() { 836 return ((mPhone != null) && (mPhone.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA)); 837 } 838 839 private boolean isEvdo() { 840 return ( (mServiceState != null) 841 && ((mServiceState.getRadioTechnology() 842 == ServiceState.RADIO_TECHNOLOGY_EVDO_0) 843 || (mServiceState.getRadioTechnology() 844 == ServiceState.RADIO_TECHNOLOGY_EVDO_A))); 845 } 846 847 private boolean hasService() { 848 if (mServiceState != null) { 849 switch (mServiceState.getState()) { 850 case ServiceState.STATE_OUT_OF_SERVICE: 851 case ServiceState.STATE_POWER_OFF: 852 return false; 853 default: 854 return true; 855 } 856 } else { 857 return false; 858 } 859 } 860 861 private final void updateSignalStrength() { 862 int iconLevel = -1; 863 int[] iconList; 864 865 if (!hasService()) { 866 //Log.d(TAG, "updateSignalStrength: no service"); 867 if (Settings.System.getInt(mContext.getContentResolver(), 868 Settings.System.AIRPLANE_MODE_ON, 0) == 1) { 869 mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_flightmode; 870 } else { 871 mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_null; 872 } 873 mService.updateIcon(mPhoneIcon, mPhoneData, null); 874 return; 875 } 876 877 if (!isCdma()) { 878 int asu = mSignalStrength.getGsmSignalStrength(); 879 880 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 881 // asu = 0 (-113dB or less) is very weak 882 // signal, its better to show 0 bars to the user in such cases. 883 // asu = 99 is a special case, where the signal strength is unknown. 884 if (asu <= 0 || asu == 99) iconLevel = 0; 885 else if (asu >= 16) iconLevel = 4; 886 else if (asu >= 8) iconLevel = 3; 887 else if (asu >= 4) iconLevel = 2; 888 else iconLevel = 1; 889 890 if (mPhone.isNetworkRoaming()) { 891 iconList = sSignalImages_r; 892 } else { 893 iconList = sSignalImages; 894 } 895 } else { 896 iconList = this.sSignalImages; 897 898 // If 3G(EV) and 1x network are available than 3G should be 899 // displayed, displayed RSSI should be from the EV side. 900 // If a voice call is made then RSSI should switch to 1x. 901 if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){ 902 iconLevel = getEvdoLevel(); 903 if (false) { 904 Log.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel()); 905 } 906 } else { 907 iconLevel = getCdmaLevel(); 908 } 909 } 910 mPhoneData.iconId = iconList[iconLevel]; 911 mService.updateIcon(mPhoneIcon, mPhoneData, null); 912 } 913 914 private int getCdmaLevel() { 915 final int cdmaDbm = mSignalStrength.getCdmaDbm(); 916 final int cdmaEcio = mSignalStrength.getCdmaEcio(); 917 int levelDbm = 0; 918 int levelEcio = 0; 919 920 if (cdmaDbm >= -75) levelDbm = 4; 921 else if (cdmaDbm >= -85) levelDbm = 3; 922 else if (cdmaDbm >= -95) levelDbm = 2; 923 else if (cdmaDbm >= -100) levelDbm = 1; 924 else levelDbm = 0; 925 926 // Ec/Io are in dB*10 927 if (cdmaEcio >= -90) levelEcio = 4; 928 else if (cdmaEcio >= -110) levelEcio = 3; 929 else if (cdmaEcio >= -130) levelEcio = 2; 930 else if (cdmaEcio >= -150) levelEcio = 1; 931 else levelEcio = 0; 932 933 return (levelDbm < levelEcio) ? levelDbm : levelEcio; 934 } 935 936 private int getEvdoLevel() { 937 int evdoDbm = mSignalStrength.getEvdoDbm(); 938 int evdoSnr = mSignalStrength.getEvdoSnr(); 939 int levelEvdoDbm = 0; 940 int levelEvdoSnr = 0; 941 942 if (evdoDbm >= -65) levelEvdoDbm = 4; 943 else if (evdoDbm >= -75) levelEvdoDbm = 3; 944 else if (evdoDbm >= -90) levelEvdoDbm = 2; 945 else if (evdoDbm >= -105) levelEvdoDbm = 1; 946 else levelEvdoDbm = 0; 947 948 if (evdoSnr > 7) levelEvdoSnr = 4; 949 else if (evdoSnr > 5) levelEvdoSnr = 3; 950 else if (evdoSnr > 3) levelEvdoSnr = 2; 951 else if (evdoSnr > 1) levelEvdoSnr = 1; 952 else levelEvdoSnr = 0; 953 954 return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 955 } 956 957 private final void updateDataNetType() { 958 int net = mPhone.getNetworkType(); 959 960 switch (net) { 961 case TelephonyManager.NETWORK_TYPE_EDGE: 962 mDataIconList = sDataNetType_e; 963 break; 964 case TelephonyManager.NETWORK_TYPE_UMTS: 965 mDataIconList = sDataNetType_3g; 966 break; 967 case TelephonyManager.NETWORK_TYPE_HSDPA: 968 case TelephonyManager.NETWORK_TYPE_HSUPA: 969 case TelephonyManager.NETWORK_TYPE_HSPA: 970 mDataIconList = sDataNetType_h; 971 break; 972 case TelephonyManager.NETWORK_TYPE_CDMA: 973 // display 1xRTT for IS95A/B 974 mDataIconList = this.sDataNetType_1xrtt; 975 break; 976 case TelephonyManager.NETWORK_TYPE_1xRTT: 977 mDataIconList = this.sDataNetType_1xrtt; 978 break; 979 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through 980 case TelephonyManager.NETWORK_TYPE_EVDO_A: 981 mDataIconList = sDataNetType_evdo; 982 break; 983 default: 984 mDataIconList = sDataNetType_g; 985 break; 986 } 987 } 988 989 private final void updateDataIcon() { 990 int iconId; 991 boolean visible = true; 992 993 if (!isCdma()) { 994 // GSM case, we have to check also the sim state 995 if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) { 996 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { 997 switch (mDataActivity) { 998 case TelephonyManager.DATA_ACTIVITY_IN: 999 iconId = mDataIconList[1]; 1000 break; 1001 case TelephonyManager.DATA_ACTIVITY_OUT: 1002 iconId = mDataIconList[2]; 1003 break; 1004 case TelephonyManager.DATA_ACTIVITY_INOUT: 1005 iconId = mDataIconList[3]; 1006 break; 1007 default: 1008 iconId = mDataIconList[0]; 1009 break; 1010 } 1011 mDataData.iconId = iconId; 1012 mService.updateIcon(mDataIcon, mDataData, null); 1013 } else { 1014 visible = false; 1015 } 1016 } else { 1017 mDataData.iconId = com.android.internal.R.drawable.stat_sys_no_sim; 1018 mService.updateIcon(mDataIcon, mDataData, null); 1019 } 1020 } else { 1021 // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT 1022 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { 1023 switch (mDataActivity) { 1024 case TelephonyManager.DATA_ACTIVITY_IN: 1025 iconId = mDataIconList[1]; 1026 break; 1027 case TelephonyManager.DATA_ACTIVITY_OUT: 1028 iconId = mDataIconList[2]; 1029 break; 1030 case TelephonyManager.DATA_ACTIVITY_INOUT: 1031 iconId = mDataIconList[3]; 1032 break; 1033 case TelephonyManager.DATA_ACTIVITY_DORMANT: 1034 iconId = mDataIconList[4]; 1035 break; 1036 default: 1037 iconId = mDataIconList[0]; 1038 break; 1039 } 1040 mDataData.iconId = iconId; 1041 mService.updateIcon(mDataIcon, mDataData, null); 1042 } else { 1043 visible = false; 1044 } 1045 } 1046 1047 long ident = Binder.clearCallingIdentity(); 1048 try { 1049 mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible); 1050 } catch (RemoteException e) { 1051 } finally { 1052 Binder.restoreCallingIdentity(ident); 1053 } 1054 1055 if (mDataIconVisible != visible) { 1056 mService.setIconVisibility(mDataIcon, visible); 1057 mDataIconVisible = visible; 1058 } 1059 } 1060 1061 private final void updateVolume() { 1062 AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 1063 final int ringerMode = audioManager.getRingerMode(); 1064 final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT || 1065 ringerMode == AudioManager.RINGER_MODE_VIBRATE; 1066 final int iconId = audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER) 1067 ? com.android.internal.R.drawable.stat_sys_ringer_vibrate 1068 : com.android.internal.R.drawable.stat_sys_ringer_silent; 1069 1070 if (visible) { 1071 mVolumeData.iconId = iconId; 1072 mService.updateIcon(mVolumeIcon, mVolumeData, null); 1073 } 1074 if (visible != mVolumeVisible) { 1075 mService.setIconVisibility(mVolumeIcon, visible); 1076 mVolumeVisible = visible; 1077 } 1078 } 1079 1080 private final void updateBluetooth(Intent intent) { 1081 int iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth; 1082 1083 String action = intent.getAction(); 1084 if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) { 1085 int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE, 1086 BluetoothError.ERROR); 1087 mBluetoothEnabled = state == BluetoothAdapter.BLUETOOTH_STATE_ON; 1088 } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) { 1089 mBluetoothHeadsetState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE, 1090 BluetoothHeadset.STATE_ERROR); 1091 } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) { 1092 mBluetoothA2dpState = intent.getIntExtra(BluetoothA2dp.SINK_STATE, 1093 BluetoothA2dp.STATE_DISCONNECTED); 1094 } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) { 1095 mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE, 1096 BluetoothPbap.STATE_DISCONNECTED); 1097 } else { 1098 return; 1099 } 1100 1101 if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || 1102 mBluetoothA2dpState == BluetoothA2dp.STATE_CONNECTED || 1103 mBluetoothA2dpState == BluetoothA2dp.STATE_PLAYING || 1104 mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) { 1105 iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth_connected; 1106 } 1107 1108 mBluetoothData.iconId = iconId; 1109 mService.updateIcon(mBluetoothIcon, mBluetoothData, null); 1110 mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled); 1111 } 1112 1113 private final void updateWifi(Intent intent) { 1114 final String action = intent.getAction(); 1115 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 1116 1117 final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 1118 WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; 1119 1120 if (!enabled) { 1121 // If disabled, hide the icon. (We show icon when connected.) 1122 mService.setIconVisibility(mWifiIcon, false); 1123 } 1124 1125 } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) { 1126 final boolean enabled = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, 1127 false); 1128 if (!enabled) { 1129 mService.setIconVisibility(mWifiIcon, false); 1130 } 1131 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 1132 1133 final NetworkInfo networkInfo = (NetworkInfo) 1134 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 1135 1136 int iconId; 1137 if (networkInfo != null && networkInfo.isConnected()) { 1138 mIsWifiConnected = true; 1139 if (mLastWifiSignalLevel == -1) { 1140 iconId = sWifiSignalImages[0]; 1141 } else { 1142 iconId = sWifiSignalImages[mLastWifiSignalLevel]; 1143 } 1144 1145 // Show the icon since wi-fi is connected 1146 mService.setIconVisibility(mWifiIcon, true); 1147 1148 } else { 1149 mLastWifiSignalLevel = -1; 1150 mIsWifiConnected = false; 1151 iconId = sWifiSignalImages[0]; 1152 1153 // Hide the icon since we're not connected 1154 mService.setIconVisibility(mWifiIcon, false); 1155 } 1156 1157 mWifiData.iconId = iconId; 1158 mService.updateIcon(mWifiIcon, mWifiData, null); 1159 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { 1160 final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200); 1161 int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 1162 sWifiSignalImages.length); 1163 if (newSignalLevel != mLastWifiSignalLevel) { 1164 mLastWifiSignalLevel = newSignalLevel; 1165 if (mIsWifiConnected) { 1166 mWifiData.iconId = sWifiSignalImages[newSignalLevel]; 1167 } else { 1168 mWifiData.iconId = sWifiTemporarilyNotConnectedImage; 1169 } 1170 mService.updateIcon(mWifiIcon, mWifiData, null); 1171 } 1172 } 1173 } 1174 1175 private final void updateGps(Intent intent) { 1176 final String action = intent.getAction(); 1177 final boolean enabled = intent.getBooleanExtra(GpsLocationProvider.EXTRA_ENABLED, false); 1178 1179 if (action.equals(GpsLocationProvider.GPS_FIX_CHANGE_ACTION) && enabled) { 1180 // GPS is getting fixes 1181 mService.updateIcon(mGpsIcon, mGpsFixIconData, null); 1182 mService.setIconVisibility(mGpsIcon, true); 1183 } else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION) && !enabled) { 1184 // GPS is off 1185 mService.setIconVisibility(mGpsIcon, false); 1186 } else { 1187 // GPS is on, but not receiving fixes 1188 mService.updateIcon(mGpsIcon, mGpsEnabledIconData, null); 1189 mService.setIconVisibility(mGpsIcon, true); 1190 } 1191 } 1192 1193 private final void updateTTY(Intent intent) { 1194 final String action = intent.getAction(); 1195 final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false); 1196 1197 Log.i(TAG, "updateTTY: enabled: " + enabled); 1198 1199 if (enabled) { 1200 // TTY is on 1201 Log.i(TAG, "updateTTY: set TTY on"); 1202 mService.updateIcon(mTTYModeIcon, mTTYModeEnableIconData, null); 1203 mService.setIconVisibility(mTTYModeIcon, true); 1204 } else { 1205 // TTY is off 1206 Log.i(TAG, "updateTTY: set TTY off"); 1207 mService.setIconVisibility(mTTYModeIcon, false); 1208 } 1209 } 1210 1211 private final void updateCdmaRoamingIcon() { 1212 if (!hasService()) { 1213 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false); 1214 return; 1215 } 1216 1217 if (!isCdma()) { 1218 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false); 1219 return; 1220 } 1221 1222 int[] iconList = sRoamingIndicatorImages_cdma; 1223 int iconIndex = mPhone.getCdmaEriIconIndex(); 1224 int iconMode = mPhone.getCdmaEriIconMode(); 1225 1226 if (iconIndex == -1) { 1227 Log.e(TAG, "getCdmaEriIconIndex returned null, skipping ERI icon update"); 1228 return; 1229 } 1230 1231 if (iconMode == -1) { 1232 Log.e(TAG, "getCdmeEriIconMode returned null, skipping ERI icon update"); 1233 return; 1234 } 1235 1236 if (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) { 1237 Log.d(TAG, "Cdma ROAMING_INDICATOR_OFF, removing ERI icon"); 1238 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false); 1239 return; 1240 } 1241 1242 switch (iconMode) { 1243 case EriInfo.ROAMING_ICON_MODE_NORMAL: 1244 mCdmaRoamingIndicatorIconData.iconId = iconList[iconIndex]; 1245 mService.updateIcon(mCdmaRoamingIndicatorIcon, mCdmaRoamingIndicatorIconData, null); 1246 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, true); 1247 break; 1248 case EriInfo.ROAMING_ICON_MODE_FLASH: 1249 mCdmaRoamingIndicatorIconData.iconId = 1250 com.android.internal.R.drawable.stat_sys_roaming_cdma_flash; 1251 mService.updateIcon(mCdmaRoamingIndicatorIcon, mCdmaRoamingIndicatorIconData, null); 1252 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, true); 1253 break; 1254 1255 } 1256 mService.updateIcon(mPhoneIcon, mPhoneData, null); 1257 } 1258 1259 1260 private class StatusBarHandler extends Handler { 1261 @Override 1262 public void handleMessage(Message msg) { 1263 switch (msg.what) { 1264 case EVENT_BATTERY_CLOSE: 1265 if (msg.arg1 == mBatteryViewSequence) { 1266 closeLastBatteryView(); 1267 } 1268 break; 1269 } 1270 } 1271 } 1272} 1273