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