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