Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/system/chromeos/power/tray_power.h" | 5 #include "ash/system/chromeos/power/tray_power.h" |
| 6 | 6 |
| 7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
| 8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 9 #include "ash/shell_delegate.h" | 9 #include "ash/shell_delegate.h" |
| 10 #include "ash/system/chromeos/power/power_status_view.h" | 10 #include "ash/system/chromeos/power/power_status_view.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 #include "third_party/icu/public/i18n/unicode/fieldpos.h" | 22 #include "third_party/icu/public/i18n/unicode/fieldpos.h" |
| 23 #include "third_party/icu/public/i18n/unicode/fmtable.h" | 23 #include "third_party/icu/public/i18n/unicode/fmtable.h" |
| 24 #include "third_party/skia/include/core/SkRect.h" | 24 #include "third_party/skia/include/core/SkRect.h" |
| 25 #include "ui/base/accessibility/accessible_view_state.h" | 25 #include "ui/base/accessibility/accessible_view_state.h" |
| 26 #include "ui/base/l10n/l10n_util.h" | 26 #include "ui/base/l10n/l10n_util.h" |
| 27 #include "ui/base/resource/resource_bundle.h" | 27 #include "ui/base/resource/resource_bundle.h" |
| 28 #include "ui/gfx/image/image.h" | 28 #include "ui/gfx/image/image.h" |
| 29 #include "ui/gfx/image/image_skia.h" | 29 #include "ui/gfx/image/image_skia.h" |
| 30 #include "ui/gfx/image/image_skia_operations.h" | 30 #include "ui/gfx/image/image_skia_operations.h" |
| 31 #include "ui/gfx/size.h" | 31 #include "ui/gfx/size.h" |
| 32 #include "ui/message_center/message_center.h" | |
| 33 #include "ui/message_center/notification.h" | |
| 32 #include "ui/views/controls/button/button.h" | 34 #include "ui/views/controls/button/button.h" |
| 33 #include "ui/views/controls/image_view.h" | 35 #include "ui/views/controls/image_view.h" |
| 34 #include "ui/views/controls/label.h" | 36 #include "ui/views/controls/label.h" |
| 35 #include "ui/views/layout/box_layout.h" | 37 #include "ui/views/layout/box_layout.h" |
| 36 #include "ui/views/layout/fill_layout.h" | 38 #include "ui/views/layout/fill_layout.h" |
| 37 #include "ui/views/layout/grid_layout.h" | 39 #include "ui/views/layout/grid_layout.h" |
| 38 #include "ui/views/view.h" | 40 #include "ui/views/view.h" |
| 39 #include "ui/views/widget/widget.h" | 41 #include "ui/views/widget/widget.h" |
| 40 | 42 |
| 41 using chromeos::PowerManagerHandler; | 43 using chromeos::PowerManagerHandler; |
| 42 using chromeos::PowerSupplyStatus; | 44 using chromeos::PowerSupplyStatus; |
| 45 using message_center::MessageCenter; | |
| 46 using message_center::Notification; | |
| 43 | 47 |
| 44 namespace ash { | 48 namespace ash { |
| 45 namespace internal { | 49 namespace internal { |
| 46 | 50 |
| 47 namespace { | 51 namespace { |
| 48 // Width and height of battery images. | 52 // Width and height of battery images. |
| 49 const int kBatteryImageHeight = 25; | 53 const int kBatteryImageHeight = 25; |
| 50 const int kBatteryImageWidth = 25; | 54 const int kBatteryImageWidth = 25; |
| 51 // Number of different power states. | 55 // Number of different power states. |
| 52 const int kNumPowerImages = 15; | 56 const int kNumPowerImages = 15; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 194 int battery_icon_offset_; | 198 int battery_icon_offset_; |
| 195 bool battery_charging_unreliable_; | 199 bool battery_charging_unreliable_; |
| 196 | 200 |
| 197 DISALLOW_COPY_AND_ASSIGN(PowerNotificationView); | 201 DISALLOW_COPY_AND_ASSIGN(PowerNotificationView); |
| 198 }; | 202 }; |
| 199 | 203 |
| 200 } // namespace tray | 204 } // namespace tray |
| 201 | 205 |
| 202 using tray::PowerNotificationView; | 206 using tray::PowerNotificationView; |
| 203 | 207 |
| 204 TrayPower::TrayPower(SystemTray* system_tray) | 208 TrayPower::TrayPower(SystemTray* system_tray, |
| 209 message_center::MessageCenter* message_center) | |
|
Jun Mukai
2013/06/19 17:43:31
you don't need "meesage_center::" since you declar
James Cook
2013/06/19 18:00:08
Done.
| |
| 205 : SystemTrayItem(system_tray), | 210 : SystemTrayItem(system_tray), |
| 211 message_center_(message_center), | |
| 206 power_tray_(NULL), | 212 power_tray_(NULL), |
| 207 notification_view_(NULL), | 213 notification_view_(NULL), |
| 208 notification_state_(NOTIFICATION_NONE) { | 214 notification_state_(NOTIFICATION_NONE) { |
| 209 PowerManagerHandler::Get()->AddObserver(this); | 215 // Tests may not have a PowerManagerHandler. |
| 216 if (PowerManagerHandler::IsInitialized()) | |
| 217 PowerManagerHandler::Get()->AddObserver(this); | |
| 210 } | 218 } |
| 211 | 219 |
| 212 TrayPower::~TrayPower() { | 220 TrayPower::~TrayPower() { |
| 213 if (PowerManagerHandler::IsInitialized()) | 221 if (PowerManagerHandler::IsInitialized()) |
| 214 PowerManagerHandler::Get()->RemoveObserver(this); | 222 PowerManagerHandler::Get()->RemoveObserver(this); |
| 215 } | 223 } |
| 216 | 224 |
| 217 // static | 225 // static |
| 218 bool TrayPower::IsBatteryChargingUnreliable( | 226 bool TrayPower::IsBatteryChargingUnreliable( |
| 219 const chromeos::PowerSupplyStatus& supply_status) { | 227 const chromeos::PowerSupplyStatus& supply_status) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 IDR_AURA_UBER_TRAY_POWER_SMALL_DARK : IDR_AURA_UBER_TRAY_POWER_SMALL); | 275 IDR_AURA_UBER_TRAY_POWER_SMALL_DARK : IDR_AURA_UBER_TRAY_POWER_SMALL); |
| 268 } | 276 } |
| 269 gfx::Rect region( | 277 gfx::Rect region( |
| 270 image_offset * kBatteryImageWidth, | 278 image_offset * kBatteryImageWidth, |
| 271 image_index * kBatteryImageHeight, | 279 image_index * kBatteryImageHeight, |
| 272 kBatteryImageWidth, kBatteryImageHeight); | 280 kBatteryImageWidth, kBatteryImageHeight); |
| 273 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region); | 281 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region); |
| 274 } | 282 } |
| 275 | 283 |
| 276 // static | 284 // static |
| 285 gfx::Image TrayPower::GetUsbChargerNotificationImage() { | |
| 286 // TODO(jamescook): Use a specialized art asset here. | |
| 287 gfx::ImageSkia icon = | |
| 288 GetBatteryImage(kNumPowerImages - 1, 0, true, ICON_LIGHT); | |
| 289 return gfx::Image(icon); | |
| 290 } | |
| 291 | |
| 292 // static | |
| 277 base::string16 TrayPower::GetAccessibleNameString( | 293 base::string16 TrayPower::GetAccessibleNameString( |
| 278 const chromeos::PowerSupplyStatus& supply_status) { | 294 const chromeos::PowerSupplyStatus& supply_status) { |
| 279 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 295 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 280 if (supply_status.line_power_on && supply_status.battery_is_full) { | 296 if (supply_status.line_power_on && supply_status.battery_is_full) { |
| 281 return rb.GetLocalizedString( | 297 return rb.GetLocalizedString( |
| 282 IDS_ASH_STATUS_TRAY_BATTERY_FULL_CHARGE_ACCESSIBLE); | 298 IDS_ASH_STATUS_TRAY_BATTERY_FULL_CHARGE_ACCESSIBLE); |
| 283 } | 299 } |
| 284 bool charging_unreliable = | 300 bool charging_unreliable = |
| 285 IsBatteryChargingUnreliable(supply_status); | 301 IsBatteryChargingUnreliable(supply_status); |
| 286 if (supply_status.battery_percentage < 0.0f) { | 302 if (supply_status.battery_percentage < 0.0f) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 if (power_tray_) | 409 if (power_tray_) |
| 394 power_tray_->UpdatePowerStatus(status, battery_alert); | 410 power_tray_->UpdatePowerStatus(status, battery_alert); |
| 395 if (notification_view_) | 411 if (notification_view_) |
| 396 notification_view_->UpdatePowerStatus(status); | 412 notification_view_->UpdatePowerStatus(status); |
| 397 | 413 |
| 398 // Factory testing may place the battery into unusual states. | 414 // Factory testing may place the battery into unusual states. |
| 399 if (CommandLine::ForCurrentProcess()->HasSwitch( | 415 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 400 ash::switches::kAshHideNotificationsForFactory)) | 416 ash::switches::kAshHideNotificationsForFactory)) |
| 401 return; | 417 return; |
| 402 | 418 |
| 419 if (ash::switches::UseUsbChargerNotification()) | |
| 420 MaybeShowUsbChargerNotification(last_power_supply_status_, status); | |
| 421 | |
| 403 if (battery_alert) | 422 if (battery_alert) |
| 404 ShowNotificationView(); | 423 ShowNotificationView(); |
| 405 else if (notification_state_ == NOTIFICATION_NONE) | 424 else if (notification_state_ == NOTIFICATION_NONE) |
| 406 HideNotificationView(); | 425 HideNotificationView(); |
| 426 | |
| 427 last_power_supply_status_ = status; | |
| 407 } | 428 } |
| 408 | 429 |
| 409 void TrayPower::RequestStatusUpdate() const { | 430 void TrayPower::RequestStatusUpdate() const { |
| 410 PowerManagerHandler::Get()->RequestStatusUpdate(); | 431 PowerManagerHandler::Get()->RequestStatusUpdate(); |
| 411 } | 432 } |
| 412 | 433 |
| 434 bool TrayPower::MaybeShowUsbChargerNotification( | |
| 435 const PowerSupplyStatus& old_status, | |
| 436 const PowerSupplyStatus& new_status) { | |
| 437 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 438 const char kNotificationId[] = "usb-charger"; | |
| 439 // Check for a USB charger being connected. | |
| 440 if (new_status.battery_state == PowerSupplyStatus::CONNECTED_TO_USB && | |
| 441 old_status.battery_state != PowerSupplyStatus::CONNECTED_TO_USB) { | |
| 442 scoped_ptr<Notification> notification; | |
| 443 notification.reset(new Notification( | |
|
Jun Mukai
2013/06/19 17:43:31
nit: just scoped_ptr<Notification> notification(ne
James Cook
2013/06/19 18:00:08
Done.
| |
| 444 message_center::NOTIFICATION_TYPE_SIMPLE, | |
| 445 kNotificationId, | |
| 446 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE), | |
| 447 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE), | |
| 448 GetUsbChargerNotificationImage(), | |
| 449 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_SOURCE), | |
| 450 kNotificationId, // extension_id | |
|
Jun Mukai
2013/06/19 17:43:31
The extension_id and display_source can be empty.
James Cook
2013/06/19 18:00:08
Done. I might want to provide a way to turn off th
| |
| 451 message_center::RichNotificationData(), | |
| 452 NULL)); | |
|
Jun Mukai
2013/06/19 17:43:31
probably better to call notification->SetSystemPri
James Cook
2013/06/19 18:00:08
I don't think I want this to be system priority --
Jun Mukai
2013/06/19 21:01:56
Then, that's fine. system priority was added to no
| |
| 453 // Tests may not have a message center. | |
| 454 if (message_center_) | |
| 455 message_center_->AddNotification(notification.Pass()); | |
| 456 return true; | |
| 457 } | |
| 458 | |
| 459 // Check for unplug of a USB charger while the USB charger notification is | |
| 460 // showing. | |
| 461 if (new_status.battery_state != PowerSupplyStatus::CONNECTED_TO_USB && | |
| 462 old_status.battery_state == PowerSupplyStatus::CONNECTED_TO_USB) { | |
| 463 // Tests may not have a message center. | |
| 464 if (message_center_) | |
| 465 message_center_->RemoveNotification(kNotificationId, false); | |
| 466 return true; | |
| 467 } | |
| 468 return false; | |
| 469 } | |
| 470 | |
| 413 bool TrayPower::UpdateNotificationState( | 471 bool TrayPower::UpdateNotificationState( |
| 414 const chromeos::PowerSupplyStatus& status) { | 472 const chromeos::PowerSupplyStatus& status) { |
| 415 if (!status.battery_is_present || | 473 if (!status.battery_is_present || |
| 416 status.is_calculating_battery_time || | 474 status.is_calculating_battery_time || |
| 417 status.battery_state == PowerSupplyStatus::CHARGING) { | 475 status.battery_state == PowerSupplyStatus::CHARGING) { |
| 418 notification_state_ = NOTIFICATION_NONE; | 476 notification_state_ = NOTIFICATION_NONE; |
| 419 return false; | 477 return false; |
| 420 } | 478 } |
| 421 | 479 |
| 422 if (TrayPower::IsBatteryChargingUnreliable(status)) { | 480 if (TrayPower::IsBatteryChargingUnreliable(status)) { |
| 423 return UpdateNotificationStateForRemainingPercentage( | 481 return UpdateNotificationStateForRemainingPercentage( |
| 424 status.battery_percentage); | 482 status.battery_percentage); |
| 425 } else { | 483 } else { |
| 426 return UpdateNotificationStateForRemainingTime( | 484 return UpdateNotificationStateForRemainingTime( |
| 427 status.battery_seconds_to_empty); | 485 status.battery_seconds_to_empty); |
| 428 } | 486 } |
| 429 } | 487 } |
| 430 | 488 |
| 431 bool TrayPower::UpdateNotificationStateForRemainingTime(int remaining_seconds) { | 489 bool TrayPower::UpdateNotificationStateForRemainingTime(int remaining_seconds) { |
| 432 if (remaining_seconds >= kNoWarningSeconds) { | 490 if (remaining_seconds >= kNoWarningSeconds) { |
| 433 notification_state_ = NOTIFICATION_NONE; | 491 notification_state_ = NOTIFICATION_NONE; |
| 434 return false; | 492 return false; |
| 435 } | 493 } |
| 436 | 494 |
| 437 switch (notification_state_) { | 495 switch (notification_state_) { |
| 438 case NOTIFICATION_NONE: | 496 case NOTIFICATION_NONE: |
| 439 if (remaining_seconds <= kCriticalSeconds) { | 497 if (remaining_seconds <= kCriticalSeconds) { |
| 440 notification_state_ = NOTIFICATION_CRITICAL; | 498 notification_state_ = NOTIFICATION_CRITICAL; |
| 441 return true; | 499 return true; |
| 442 } else if (remaining_seconds <= kLowPowerSeconds) { | 500 } |
| 501 if (remaining_seconds <= kLowPowerSeconds) { | |
| 443 notification_state_ = NOTIFICATION_LOW_POWER; | 502 notification_state_ = NOTIFICATION_LOW_POWER; |
| 444 return true; | 503 return true; |
| 445 } | 504 } |
| 446 return false; | 505 return false; |
| 447 case NOTIFICATION_LOW_POWER: | 506 case NOTIFICATION_LOW_POWER: |
| 448 if (remaining_seconds <= kCriticalSeconds) { | 507 if (remaining_seconds <= kCriticalSeconds) { |
| 449 notification_state_ = NOTIFICATION_CRITICAL; | 508 notification_state_ = NOTIFICATION_CRITICAL; |
| 450 return true; | 509 return true; |
| 451 } | 510 } |
| 452 return false; | 511 return false; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 483 return false; | 542 return false; |
| 484 case NOTIFICATION_CRITICAL: | 543 case NOTIFICATION_CRITICAL: |
| 485 return false; | 544 return false; |
| 486 } | 545 } |
| 487 NOTREACHED(); | 546 NOTREACHED(); |
| 488 return false; | 547 return false; |
| 489 } | 548 } |
| 490 | 549 |
| 491 } // namespace internal | 550 } // namespace internal |
| 492 } // namespace ash | 551 } // namespace ash |
| OLD | NEW |