tray_power.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/system/chromeos/power/tray_power.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/ash_switches.h"
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/system/chromeos/power/power_status_view.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/date/date_view.h"
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/system/system_notifier.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_notification_view.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/system/tray/tray_utils.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/i18n/unicode/fieldpos.h"
18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/i18n/unicode/fmtable.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/message_center/message_center.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/message_center/notification.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/button.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing message_center::MessageCenter;
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing message_center::Notification;
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Top/bottom padding of the text items.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPaddingVertical = 10;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specify min width of status label for layout.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLabelMinWidth = 120;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Notification times.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCriticalSeconds = 5 * 60;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLowPowerSeconds = 15 * 60;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNoWarningSeconds = 30 * 60;
47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Notification in battery percentage.
48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const double kCriticalPercentage = 5.0;
49a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const double kLowPowerPercentage = 10.0;
50a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const double kNoWarningPercentage = 15.0;
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tray {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This view is used only for the tray.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PowerTrayView : public views::ImageView {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PowerTrayView() {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateImage();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PowerTrayView() {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overriden from views::View.
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state->name = accessible_name_;
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void UpdateStatus(bool battery_alert) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateImage();
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SetVisible(PowerStatus::Get()->IsBatteryPresent());
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (battery_alert) {
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      accessible_name_ = PowerStatus::Get()->GetAccessibleNameString();
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateImage() {
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SetImage(PowerStatus::Get()->GetBatteryImage(PowerStatus::ICON_LIGHT));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 accessible_name_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PowerNotificationView : public TrayNotificationView {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit PowerNotificationView(TrayPower* owner)
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : TrayNotificationView(owner, 0) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    power_status_view_ =
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new PowerStatusView(PowerStatusView::VIEW_NOTIFICATION, true);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitView(power_status_view_);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void UpdateStatus() {
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SetIconImage(PowerStatus::Get()->GetBatteryImage(PowerStatus::ICON_DARK));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PowerStatusView* power_status_view_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PowerNotificationView);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace tray
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using tray::PowerNotificationView;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTrayPower::TrayPower(SystemTray* system_tray, MessageCenter* message_center)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SystemTrayItem(system_tray),
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      message_center_(message_center),
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      power_tray_(NULL),
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notification_view_(NULL),
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      notification_state_(NOTIFICATION_NONE),
121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      usb_charger_was_connected_(false) {
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PowerStatus::Get()->AddObserver(this);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrayPower::~TrayPower() {
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PowerStatus::Get()->RemoveObserver(this);
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateTrayView(user::LoginStatus status) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There may not be enough information when this is created about whether
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there is a battery or not. So always create this, and adjust visibility as
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // necessary.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(power_tray_ == NULL);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  power_tray_ = new tray::PowerTrayView();
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  power_tray_->UpdateStatus(false);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return power_tray_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateDefaultView(user::LoginStatus status) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure icon status is up-to-date. (Also triggers stub activation).
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PowerStatus::Get()->RequestStatusUpdate();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateNotificationView(user::LoginStatus status) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(notification_view_ == NULL);
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!PowerStatus::Get()->IsBatteryPresent())
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_view_ = new PowerNotificationView(this);
151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  notification_view_->UpdateStatus();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return notification_view_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyTrayView() {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  power_tray_ = NULL;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyDefaultView() {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyNotificationView() {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_view_ = NULL;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::UpdateAfterLoginStatusChange(user::LoginStatus status) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetTrayImageItemBorder(power_tray_, alignment);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid TrayPower::OnPowerStatusChanged() {
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool battery_alert = UpdateNotificationState();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (power_tray_)
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    power_tray_->UpdateStatus(battery_alert);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (notification_view_)
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    notification_view_->UpdateStatus();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Factory testing may place the battery into unusual states.
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          ash::switches::kAshHideNotificationsForFactory))
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (ash::switches::UseUsbChargerNotification())
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MaybeShowUsbChargerNotification();
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (battery_alert)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShowNotificationView();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (notification_state_ == NOTIFICATION_NONE)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HideNotificationView();
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  usb_charger_was_connected_ = PowerStatus::Get()->IsUsbChargerConnected();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TrayPower::MaybeShowUsbChargerNotification() {
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char kNotificationId[] = "usb-charger";
200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool usb_charger_is_connected = PowerStatus::Get()->IsUsbChargerConnected();
201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for a USB charger being connected.
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (usb_charger_is_connected && !usb_charger_was_connected_) {
204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_ptr<Notification> notification(new Notification(
205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        message_center::NOTIFICATION_TYPE_SIMPLE,
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kNotificationId,
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE),
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE),
209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        rb.GetImageNamed(IDR_AURA_NOTIFICATION_LOW_POWER_CHARGER),
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::string16(),
211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        message_center::NotifierId(NOTIFIER_POWER),
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        message_center::RichNotificationData(),
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        NULL));
214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_center_->AddNotification(notification.Pass());
215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for unplug of a USB charger while the USB charger notification is
219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // showing.
220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!usb_charger_is_connected && usb_charger_was_connected_) {
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_center_->RemoveNotification(kNotificationId, false);
222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return false;
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TrayPower::UpdateNotificationState() {
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const PowerStatus& status = *PowerStatus::Get();
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!status.IsBatteryPresent() ||
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      status.IsBatteryTimeBeingCalculated() ||
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      status.IsMainsChargerConnected()) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notification_state_ = NOTIFICATION_NONE;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return status.IsUsbChargerConnected() ?
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      UpdateNotificationStateForRemainingPercentage() :
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      UpdateNotificationStateForRemainingTime();
239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TrayPower::UpdateNotificationStateForRemainingTime() {
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const int remaining_seconds =
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      PowerStatus::Get()->GetBatteryTimeToEmpty().InSeconds();
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (remaining_seconds >= kNoWarningSeconds) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notification_state_ = NOTIFICATION_NONE;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (notification_state_) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NOTIFICATION_NONE:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (remaining_seconds <= kCriticalSeconds) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notification_state_ = NOTIFICATION_CRITICAL;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (remaining_seconds <= kLowPowerSeconds) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notification_state_ = NOTIFICATION_LOW_POWER;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NOTIFICATION_LOW_POWER:
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (remaining_seconds <= kCriticalSeconds) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notification_state_ = NOTIFICATION_CRITICAL;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NOTIFICATION_CRITICAL:
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TrayPower::UpdateNotificationStateForRemainingPercentage() {
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const double remaining_percentage = PowerStatus::Get()->GetBatteryPercent();
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
277a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (remaining_percentage > kNoWarningPercentage) {
278a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    notification_state_ = NOTIFICATION_NONE;
279a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return false;
280a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
281a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
282a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  switch (notification_state_) {
283a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    case NOTIFICATION_NONE:
284a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (remaining_percentage <= kCriticalPercentage) {
285a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        notification_state_ = NOTIFICATION_CRITICAL;
286a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return true;
287a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      }
288a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (remaining_percentage <= kLowPowerPercentage) {
289a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        notification_state_ = NOTIFICATION_LOW_POWER;
290a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return true;
291a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      }
292a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return false;
293a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    case NOTIFICATION_LOW_POWER:
294a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (remaining_percentage <= kCriticalPercentage) {
295a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        notification_state_ = NOTIFICATION_CRITICAL;
296a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return true;
297a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      }
298a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return false;
299a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    case NOTIFICATION_CRITICAL:
300a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return false;
301a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
302a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  NOTREACHED();
303a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return false;
304a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
305a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
308