Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: ash/system/chromeos/power/tray_power.cc

Issue 17157007: cros: Show notification when low-power charger connected (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « ash/system/chromeos/power/tray_power.h ('k') | ash/system/chromeos/power/tray_power_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698