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

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

Issue 18176013: chromeos: Refactor system tray code into PowerStatus. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove virtual Created 7 years, 5 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"
9 #include "ash/shell_delegate.h"
10 #include "ash/system/chromeos/power/power_status_view.h" 8 #include "ash/system/chromeos/power/power_status_view.h"
11 #include "ash/system/date/date_view.h" 9 #include "ash/system/date/date_view.h"
12 #include "ash/system/tray/tray_constants.h" 10 #include "ash/system/tray/tray_constants.h"
13 #include "ash/system/tray/tray_notification_view.h" 11 #include "ash/system/tray/tray_notification_view.h"
14 #include "ash/system/tray/tray_utils.h" 12 #include "ash/system/tray/tray_utils.h"
15 #include "base/command_line.h" 13 #include "base/command_line.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "chromeos/dbus/power_supply_status.h"
20 #include "grit/ash_resources.h" 14 #include "grit/ash_resources.h"
21 #include "grit/ash_strings.h" 15 #include "grit/ash_strings.h"
22 #include "third_party/icu/public/i18n/unicode/fieldpos.h" 16 #include "third_party/icu/public/i18n/unicode/fieldpos.h"
23 #include "third_party/icu/public/i18n/unicode/fmtable.h" 17 #include "third_party/icu/public/i18n/unicode/fmtable.h"
24 #include "third_party/skia/include/core/SkRect.h"
25 #include "ui/base/accessibility/accessible_view_state.h" 18 #include "ui/base/accessibility/accessible_view_state.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/image/image.h"
29 #include "ui/gfx/image/image_skia.h"
30 #include "ui/gfx/image/image_skia_operations.h"
31 #include "ui/gfx/size.h"
32 #include "ui/message_center/message_center.h" 20 #include "ui/message_center/message_center.h"
33 #include "ui/message_center/notification.h" 21 #include "ui/message_center/notification.h"
34 #include "ui/views/controls/button/button.h" 22 #include "ui/views/controls/button/button.h"
35 #include "ui/views/controls/image_view.h" 23 #include "ui/views/controls/image_view.h"
36 #include "ui/views/controls/label.h" 24 #include "ui/views/controls/label.h"
37 #include "ui/views/layout/box_layout.h" 25 #include "ui/views/layout/box_layout.h"
38 #include "ui/views/layout/fill_layout.h" 26 #include "ui/views/layout/fill_layout.h"
39 #include "ui/views/layout/grid_layout.h" 27 #include "ui/views/layout/grid_layout.h"
40 #include "ui/views/view.h" 28 #include "ui/views/view.h"
41 #include "ui/views/widget/widget.h" 29 #include "ui/views/widget/widget.h"
42 30
43 using chromeos::PowerSupplyStatus;
44 using message_center::MessageCenter; 31 using message_center::MessageCenter;
45 using message_center::Notification; 32 using message_center::Notification;
46 33
47 namespace ash { 34 namespace ash {
48 namespace internal { 35 namespace internal {
49 36
50 namespace { 37 namespace {
51 // Width and height of battery images.
52 const int kBatteryImageHeight = 25;
53 const int kBatteryImageWidth = 25;
54 // Number of different power states.
55 const int kNumPowerImages = 15;
56 // Top/bottom padding of the text items. 38 // Top/bottom padding of the text items.
57 const int kPaddingVertical = 10; 39 const int kPaddingVertical = 10;
58 // Specify min width of status label for layout. 40 // Specify min width of status label for layout.
59 const int kLabelMinWidth = 120; 41 const int kLabelMinWidth = 120;
60 // Notification times. 42 // Notification times.
61 const int kCriticalSeconds = 5 * 60; 43 const int kCriticalSeconds = 5 * 60;
62 const int kLowPowerSeconds = 15 * 60; 44 const int kLowPowerSeconds = 15 * 60;
63 const int kNoWarningSeconds = 30 * 60; 45 const int kNoWarningSeconds = 30 * 60;
64 // Minimum battery percentage rendered in UI.
65 const int kMinBatteryPercent = 1;
66 // Notification in battery percentage. 46 // Notification in battery percentage.
67 const double kCriticalPercentage = 5.0; 47 const double kCriticalPercentage = 5.0;
68 const double kLowPowerPercentage = 10.0; 48 const double kLowPowerPercentage = 10.0;
69 const double kNoWarningPercentage = 15.0; 49 const double kNoWarningPercentage = 15.0;
70 50
71 base::string16 GetBatteryTimeAccessibilityString(int hour, int min) {
72 DCHECK(hour || min);
73 if (hour && !min) {
74 return Shell::GetInstance()->delegate()->GetTimeDurationLongString(
75 base::TimeDelta::FromHours(hour));
76 }
77 if (min && !hour) {
78 return Shell::GetInstance()->delegate()->GetTimeDurationLongString(
79 base::TimeDelta::FromMinutes(min));
80 }
81 return l10n_util::GetStringFUTF16(
82 IDS_ASH_STATUS_TRAY_BATTERY_TIME_ACCESSIBLE,
83 Shell::GetInstance()->delegate()->GetTimeDurationLongString(
84 base::TimeDelta::FromHours(hour)),
85 Shell::GetInstance()->delegate()->GetTimeDurationLongString(
86 base::TimeDelta::FromMinutes(min)));
87 }
88
89 } // namespace 51 } // namespace
90 52
91 namespace tray { 53 namespace tray {
92 54
93 // This view is used only for the tray. 55 // This view is used only for the tray.
94 class PowerTrayView : public views::ImageView { 56 class PowerTrayView : public views::ImageView {
95 public: 57 public:
96 PowerTrayView() 58 PowerTrayView() {
97 : battery_icon_index_(-1),
98 battery_icon_offset_(0),
99 battery_charging_unreliable_(false) {
100 UpdateImage(); 59 UpdateImage();
101 } 60 }
102 61
103 virtual ~PowerTrayView() { 62 virtual ~PowerTrayView() {
104 } 63 }
105 64
106 // Overriden from views::View. 65 // Overriden from views::View.
107 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE { 66 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE {
108 state->name = accessible_name_; 67 state->name = accessible_name_;
109 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; 68 state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
110 } 69 }
111 70
112 void UpdatePowerStatus(const PowerSupplyStatus& status, 71 void UpdateStatus(bool battery_alert) {
113 bool battery_alert) {
114 supply_status_ = status;
115 // Sanitize.
116 if (supply_status_.battery_is_full)
117 supply_status_.battery_percentage = 100.0;
118
119 UpdateImage(); 72 UpdateImage();
120 SetVisible(status.battery_is_present); 73 SetVisible(PowerStatus::Get()->IsBatteryPresent());
121 74
122 if (battery_alert) { 75 if (battery_alert) {
123 accessible_name_ = TrayPower::GetAccessibleNameString(status); 76 accessible_name_ = PowerStatus::Get()->GetAccessibleNameString();
124 NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true); 77 NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
125 } 78 }
126 } 79 }
127 80
128 private: 81 private:
129 void UpdateImage() { 82 void UpdateImage() {
130 int index = TrayPower::GetBatteryImageIndex(supply_status_); 83 SetImage(PowerStatus::Get()->GetBatteryImage(PowerStatus::ICON_LIGHT));
131 int offset = TrayPower::GetBatteryImageOffset(supply_status_);
132 bool charging_unreliable =
133 TrayPower::IsBatteryChargingUnreliable(supply_status_);
134 if (battery_icon_index_ != index ||
135 battery_icon_offset_ != offset ||
136 battery_charging_unreliable_ != charging_unreliable) {
137 battery_icon_index_ = index;
138 battery_icon_offset_ = offset;
139 battery_charging_unreliable_ = charging_unreliable;
140 if (battery_icon_index_ != -1)
141 SetImage(TrayPower::GetBatteryImage(battery_icon_index_,
142 battery_icon_offset_,
143 battery_charging_unreliable_,
144 ICON_LIGHT));
145 }
146 } 84 }
147 85
148 PowerSupplyStatus supply_status_;
149 base::string16 accessible_name_; 86 base::string16 accessible_name_;
150 87
151 // Index of the current icon in the icon array image, or -1 if unknown.
152 int battery_icon_index_;
153 int battery_icon_offset_;
154 bool battery_charging_unreliable_;
155
156 DISALLOW_COPY_AND_ASSIGN(PowerTrayView); 88 DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
157 }; 89 };
158 90
159 class PowerNotificationView : public TrayNotificationView { 91 class PowerNotificationView : public TrayNotificationView {
160 public: 92 public:
161 explicit PowerNotificationView(TrayPower* owner) 93 explicit PowerNotificationView(TrayPower* owner)
162 : TrayNotificationView(owner, 0), 94 : TrayNotificationView(owner, 0) {
163 battery_icon_index_(-1),
164 battery_icon_offset_(0),
165 battery_charging_unreliable_(false) {
166 power_status_view_ = 95 power_status_view_ =
167 new PowerStatusView(PowerStatusView::VIEW_NOTIFICATION, true); 96 new PowerStatusView(PowerStatusView::VIEW_NOTIFICATION, true);
168 InitView(power_status_view_); 97 InitView(power_status_view_);
169 } 98 }
170 99
171 void UpdatePowerStatus(const PowerSupplyStatus& status) { 100 void UpdateStatus() {
172 int index = TrayPower::GetBatteryImageIndex(status); 101 SetIconImage(PowerStatus::Get()->GetBatteryImage(PowerStatus::ICON_DARK));
173 int offset = TrayPower::GetBatteryImageOffset(status);
174 bool charging_unreliable = TrayPower::IsBatteryChargingUnreliable(status);
175 if (battery_icon_index_ != index ||
176 battery_icon_offset_ != offset ||
177 battery_charging_unreliable_ != charging_unreliable) {
178 battery_icon_index_ = index;
179 battery_icon_offset_ = offset;
180 battery_charging_unreliable_ = charging_unreliable;
181 if (battery_icon_index_ != -1) {
182 SetIconImage(TrayPower::GetBatteryImage(
183 battery_icon_index_,
184 battery_icon_offset_,
185 battery_charging_unreliable_,
186 ICON_DARK));
187 }
188 }
189 power_status_view_->UpdatePowerStatus(status);
190 } 102 }
191 103
192 private: 104 private:
193 PowerStatusView* power_status_view_; 105 PowerStatusView* power_status_view_;
194 106
195 // Index of the current icon in the icon array image, or -1 if unknown.
196 int battery_icon_index_;
197 int battery_icon_offset_;
198 bool battery_charging_unreliable_;
199
200 DISALLOW_COPY_AND_ASSIGN(PowerNotificationView); 107 DISALLOW_COPY_AND_ASSIGN(PowerNotificationView);
201 }; 108 };
202 109
203 } // namespace tray 110 } // namespace tray
204 111
205 using tray::PowerNotificationView; 112 using tray::PowerNotificationView;
206 113
207 TrayPower::TrayPower(SystemTray* system_tray, MessageCenter* message_center) 114 TrayPower::TrayPower(SystemTray* system_tray, MessageCenter* message_center)
208 : SystemTrayItem(system_tray), 115 : SystemTrayItem(system_tray),
209 message_center_(message_center), 116 message_center_(message_center),
210 power_tray_(NULL), 117 power_tray_(NULL),
211 notification_view_(NULL), 118 notification_view_(NULL),
212 notification_state_(NOTIFICATION_NONE) { 119 notification_state_(NOTIFICATION_NONE),
120 usb_charger_was_connected_(false) {
213 PowerStatus::Get()->AddObserver(this); 121 PowerStatus::Get()->AddObserver(this);
214 } 122 }
215 123
216 TrayPower::~TrayPower() { 124 TrayPower::~TrayPower() {
217 PowerStatus::Get()->RemoveObserver(this); 125 PowerStatus::Get()->RemoveObserver(this);
218 } 126 }
219 127
220 // static
221 bool TrayPower::IsBatteryChargingUnreliable(
222 const chromeos::PowerSupplyStatus& supply_status) {
223 // Sometimes devices can get into a state where the battery is almost fully
224 // charged and the power subsystem reports "neither charging nor discharging"
225 // despite the battery not at 100%. For now, only report unreliable charging
226 // on USB.
227 // TODO(derat): Update this when the power manager code is refactored for M29.
228 return supply_status.battery_state == PowerSupplyStatus::CONNECTED_TO_USB;
229 }
230
231 // static
232 int TrayPower::GetBatteryImageIndex(
233 const chromeos::PowerSupplyStatus& supply_status) {
234 int image_index = 0;
235 if (supply_status.battery_percentage >= 100) {
236 image_index = kNumPowerImages - 1;
237 } else if (!supply_status.battery_is_present) {
238 image_index = kNumPowerImages;
239 } else {
240 image_index = static_cast<int>(supply_status.battery_percentage /
241 100.0 * (kNumPowerImages - 1));
242 image_index = std::max(std::min(image_index, kNumPowerImages - 2), 0);
243 }
244 return image_index;
245 }
246
247 // static
248 int TrayPower::GetBatteryImageOffset(
249 const chromeos::PowerSupplyStatus& supply_status) {
250 if (IsBatteryChargingUnreliable(supply_status) ||
251 !supply_status.line_power_on)
252 return 0;
253 return 1;
254 }
255
256 // static
257 gfx::ImageSkia TrayPower::GetBatteryImage(int image_index,
258 int image_offset,
259 bool charging_unreliable,
260 IconSet icon_set) {
261 gfx::Image all;
262 if (charging_unreliable) {
263 all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
264 icon_set == ICON_DARK ?
265 IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK :
266 IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE);
267 } else {
268 all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
269 icon_set == ICON_DARK ?
270 IDR_AURA_UBER_TRAY_POWER_SMALL_DARK : IDR_AURA_UBER_TRAY_POWER_SMALL);
271 }
272 gfx::Rect region(
273 image_offset * kBatteryImageWidth,
274 image_index * kBatteryImageHeight,
275 kBatteryImageWidth, kBatteryImageHeight);
276 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region);
277 }
278
279 // static
280 base::string16 TrayPower::GetAccessibleNameString(
281 const chromeos::PowerSupplyStatus& supply_status) {
282 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
283 if (supply_status.line_power_on && supply_status.battery_is_full) {
284 return rb.GetLocalizedString(
285 IDS_ASH_STATUS_TRAY_BATTERY_FULL_CHARGE_ACCESSIBLE);
286 }
287 bool charging_unreliable =
288 IsBatteryChargingUnreliable(supply_status);
289 if (supply_status.battery_percentage < 0.0f) {
290 if (charging_unreliable) {
291 return rb.GetLocalizedString(
292 IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE_ACCESSIBLE);
293 }
294 return rb.GetLocalizedString(
295 IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE);
296 }
297 base::string16 battery_percentage_accessbile = l10n_util::GetStringFUTF16(
298 supply_status.line_power_on ?
299 IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_CHARGING_ACCESSIBLE:
300 IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_ACCESSIBLE ,
301 base::IntToString16(GetRoundedBatteryPercentage(
302 supply_status.battery_percentage)));
303 base::string16 battery_time_accessible = base::string16();
304 if (charging_unreliable) {
305 battery_time_accessible = rb.GetLocalizedString(
306 IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE_ACCESSIBLE);
307 } else {
308 if (supply_status.is_calculating_battery_time) {
309 battery_time_accessible = rb.GetLocalizedString(
310 IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE);
311 } else {
312 base::TimeDelta time = base::TimeDelta::FromSeconds(
313 supply_status.line_power_on ?
314 supply_status.battery_seconds_to_full :
315 supply_status.battery_seconds_to_empty);
316 int hour = time.InHours();
317 int min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
318 if (hour || min) {
319 base::string16 minute = min < 10 ?
320 ASCIIToUTF16("0") + base::IntToString16(min) :
321 base::IntToString16(min);
322 battery_time_accessible =
323 l10n_util::GetStringFUTF16(
324 supply_status.line_power_on ?
325 IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL_ACCESSIBLE :
326 IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_ACCESSIBLE,
327 GetBatteryTimeAccessibilityString(hour, min));
328 }
329 }
330 }
331 return battery_time_accessible.empty() ?
332 battery_percentage_accessbile :
333 battery_percentage_accessbile + ASCIIToUTF16(". ")
334 + battery_time_accessible;
335 }
336
337 // static
338 int TrayPower::GetRoundedBatteryPercentage(double battery_percentage) {
339 DCHECK(battery_percentage >= 0.0);
340 return std::max(kMinBatteryPercent,
341 static_cast<int>(battery_percentage + 0.5));
342 }
343
344 views::View* TrayPower::CreateTrayView(user::LoginStatus status) { 128 views::View* TrayPower::CreateTrayView(user::LoginStatus status) {
345 // There may not be enough information when this is created about whether 129 // There may not be enough information when this is created about whether
346 // there is a battery or not. So always create this, and adjust visibility as 130 // there is a battery or not. So always create this, and adjust visibility as
347 // necessary. 131 // necessary.
348 PowerSupplyStatus power_status = PowerStatus::Get()->GetPowerSupplyStatus();
349 CHECK(power_tray_ == NULL); 132 CHECK(power_tray_ == NULL);
350 power_tray_ = new tray::PowerTrayView(); 133 power_tray_ = new tray::PowerTrayView();
351 power_tray_->UpdatePowerStatus(power_status, false); 134 power_tray_->UpdateStatus(false);
352 return power_tray_; 135 return power_tray_;
353 } 136 }
354 137
355 views::View* TrayPower::CreateDefaultView(user::LoginStatus status) { 138 views::View* TrayPower::CreateDefaultView(user::LoginStatus status) {
356 // Make sure icon status is up-to-date. (Also triggers stub activation). 139 // Make sure icon status is up-to-date. (Also triggers stub activation).
357 RequestStatusUpdate(); 140 PowerStatus::Get()->RequestStatusUpdate();
358 return NULL; 141 return NULL;
359 } 142 }
360 143
361 views::View* TrayPower::CreateNotificationView(user::LoginStatus status) { 144 views::View* TrayPower::CreateNotificationView(user::LoginStatus status) {
362 CHECK(notification_view_ == NULL); 145 CHECK(notification_view_ == NULL);
363 PowerSupplyStatus power_status = PowerStatus::Get()->GetPowerSupplyStatus(); 146 if (!PowerStatus::Get()->IsBatteryPresent())
364 if (!power_status.battery_is_present)
365 return NULL; 147 return NULL;
366 148
367 notification_view_ = new PowerNotificationView(this); 149 notification_view_ = new PowerNotificationView(this);
368 notification_view_->UpdatePowerStatus(power_status); 150 notification_view_->UpdateStatus();
369 151
370 return notification_view_; 152 return notification_view_;
371 } 153 }
372 154
373 void TrayPower::DestroyTrayView() { 155 void TrayPower::DestroyTrayView() {
374 power_tray_ = NULL; 156 power_tray_ = NULL;
375 } 157 }
376 158
377 void TrayPower::DestroyDefaultView() { 159 void TrayPower::DestroyDefaultView() {
378 } 160 }
379 161
380 void TrayPower::DestroyNotificationView() { 162 void TrayPower::DestroyNotificationView() {
381 notification_view_ = NULL; 163 notification_view_ = NULL;
382 } 164 }
383 165
384 void TrayPower::UpdateAfterLoginStatusChange(user::LoginStatus status) { 166 void TrayPower::UpdateAfterLoginStatusChange(user::LoginStatus status) {
385 } 167 }
386 168
387 void TrayPower::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { 169 void TrayPower::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
388 SetTrayImageItemBorder(power_tray_, alignment); 170 SetTrayImageItemBorder(power_tray_, alignment);
389 } 171 }
390 172
391 void TrayPower::OnPowerStatusChanged( 173 void TrayPower::OnPowerStatusChanged() {
392 const chromeos::PowerSupplyStatus& status) { 174 bool battery_alert = UpdateNotificationState();
393 bool battery_alert = UpdateNotificationState(status);
394 if (power_tray_) 175 if (power_tray_)
395 power_tray_->UpdatePowerStatus(status, battery_alert); 176 power_tray_->UpdateStatus(battery_alert);
396 if (notification_view_) 177 if (notification_view_)
397 notification_view_->UpdatePowerStatus(status); 178 notification_view_->UpdateStatus();
398 179
399 // Factory testing may place the battery into unusual states. 180 // Factory testing may place the battery into unusual states.
400 if (CommandLine::ForCurrentProcess()->HasSwitch( 181 if (CommandLine::ForCurrentProcess()->HasSwitch(
401 ash::switches::kAshHideNotificationsForFactory)) 182 ash::switches::kAshHideNotificationsForFactory))
402 return; 183 return;
403 184
404 if (ash::switches::UseUsbChargerNotification()) 185 if (ash::switches::UseUsbChargerNotification())
405 MaybeShowUsbChargerNotification(last_power_supply_status_, status); 186 MaybeShowUsbChargerNotification();
406 187
407 if (battery_alert) 188 if (battery_alert)
408 ShowNotificationView(); 189 ShowNotificationView();
409 else if (notification_state_ == NOTIFICATION_NONE) 190 else if (notification_state_ == NOTIFICATION_NONE)
410 HideNotificationView(); 191 HideNotificationView();
411 192
412 last_power_supply_status_ = status; 193 usb_charger_was_connected_ = PowerStatus::Get()->IsUsbChargerConnected();
413 } 194 }
414 195
415 void TrayPower::RequestStatusUpdate() const { 196 bool TrayPower::MaybeShowUsbChargerNotification() {
416 PowerStatus::Get()->RequestStatusUpdate();
417 }
418
419 bool TrayPower::MaybeShowUsbChargerNotification(
420 const PowerSupplyStatus& old_status,
421 const PowerSupplyStatus& new_status) {
422 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 197 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
423 const char kNotificationId[] = "usb-charger"; 198 const char kNotificationId[] = "usb-charger";
199 bool usb_charger_is_connected = PowerStatus::Get()->IsUsbChargerConnected();
200
424 // Check for a USB charger being connected. 201 // Check for a USB charger being connected.
425 if (new_status.battery_state == PowerSupplyStatus::CONNECTED_TO_USB && 202 if (usb_charger_is_connected && !usb_charger_was_connected_) {
426 old_status.battery_state != PowerSupplyStatus::CONNECTED_TO_USB) {
427 scoped_ptr<Notification> notification(new Notification( 203 scoped_ptr<Notification> notification(new Notification(
428 message_center::NOTIFICATION_TYPE_SIMPLE, 204 message_center::NOTIFICATION_TYPE_SIMPLE,
429 kNotificationId, 205 kNotificationId,
430 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE), 206 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE),
431 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE), 207 rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE),
432 rb.GetImageNamed(IDR_AURA_NOTIFICATION_LOW_POWER_CHARGER), 208 rb.GetImageNamed(IDR_AURA_NOTIFICATION_LOW_POWER_CHARGER),
433 base::string16(), 209 base::string16(),
434 std::string(), 210 std::string(),
435 message_center::RichNotificationData(), 211 message_center::RichNotificationData(),
436 NULL)); 212 NULL));
437 message_center_->AddNotification(notification.Pass()); 213 message_center_->AddNotification(notification.Pass());
438 return true; 214 return true;
439 } 215 }
440 216
441 // Check for unplug of a USB charger while the USB charger notification is 217 // Check for unplug of a USB charger while the USB charger notification is
442 // showing. 218 // showing.
443 if (new_status.battery_state != PowerSupplyStatus::CONNECTED_TO_USB && 219 if (!usb_charger_is_connected && usb_charger_was_connected_) {
444 old_status.battery_state == PowerSupplyStatus::CONNECTED_TO_USB) {
445 message_center_->RemoveNotification(kNotificationId, false); 220 message_center_->RemoveNotification(kNotificationId, false);
446 return true; 221 return true;
447 } 222 }
448 return false; 223 return false;
449 } 224 }
450 225
451 bool TrayPower::UpdateNotificationState( 226 bool TrayPower::UpdateNotificationState() {
452 const chromeos::PowerSupplyStatus& status) { 227 const PowerStatus& status = *PowerStatus::Get();
453 if (!status.battery_is_present || 228 if (!status.IsBatteryPresent() ||
454 status.is_calculating_battery_time || 229 status.IsBatteryTimeBeingCalculated() ||
455 status.battery_state == PowerSupplyStatus::CHARGING || 230 status.IsMainsChargerConnected()) {
456 status.battery_state ==
457 PowerSupplyStatus::NEITHER_CHARGING_NOR_DISCHARGING) {
458 notification_state_ = NOTIFICATION_NONE; 231 notification_state_ = NOTIFICATION_NONE;
459 return false; 232 return false;
460 } 233 }
461 234
462 if (TrayPower::IsBatteryChargingUnreliable(status)) { 235 return status.IsUsbChargerConnected() ?
463 return UpdateNotificationStateForRemainingPercentage( 236 UpdateNotificationStateForRemainingPercentage() :
464 status.battery_percentage); 237 UpdateNotificationStateForRemainingTime();
465 } else {
466 return UpdateNotificationStateForRemainingTime(
467 status.battery_seconds_to_empty);
468 }
469 } 238 }
470 239
471 bool TrayPower::UpdateNotificationStateForRemainingTime(int remaining_seconds) { 240 bool TrayPower::UpdateNotificationStateForRemainingTime() {
241 const int remaining_seconds =
242 PowerStatus::Get()->GetBatteryTimeToEmpty().InSeconds();
243
472 if (remaining_seconds >= kNoWarningSeconds) { 244 if (remaining_seconds >= kNoWarningSeconds) {
473 notification_state_ = NOTIFICATION_NONE; 245 notification_state_ = NOTIFICATION_NONE;
474 return false; 246 return false;
475 } 247 }
476 248
477 switch (notification_state_) { 249 switch (notification_state_) {
478 case NOTIFICATION_NONE: 250 case NOTIFICATION_NONE:
479 if (remaining_seconds <= kCriticalSeconds) { 251 if (remaining_seconds <= kCriticalSeconds) {
480 notification_state_ = NOTIFICATION_CRITICAL; 252 notification_state_ = NOTIFICATION_CRITICAL;
481 return true; 253 return true;
482 } 254 }
483 if (remaining_seconds <= kLowPowerSeconds) { 255 if (remaining_seconds <= kLowPowerSeconds) {
484 notification_state_ = NOTIFICATION_LOW_POWER; 256 notification_state_ = NOTIFICATION_LOW_POWER;
485 return true; 257 return true;
486 } 258 }
487 return false; 259 return false;
488 case NOTIFICATION_LOW_POWER: 260 case NOTIFICATION_LOW_POWER:
489 if (remaining_seconds <= kCriticalSeconds) { 261 if (remaining_seconds <= kCriticalSeconds) {
490 notification_state_ = NOTIFICATION_CRITICAL; 262 notification_state_ = NOTIFICATION_CRITICAL;
491 return true; 263 return true;
492 } 264 }
493 return false; 265 return false;
494 case NOTIFICATION_CRITICAL: 266 case NOTIFICATION_CRITICAL:
495 return false; 267 return false;
496 } 268 }
497 NOTREACHED(); 269 NOTREACHED();
498 return false; 270 return false;
499 } 271 }
500 272
501 bool TrayPower::UpdateNotificationStateForRemainingPercentage( 273 bool TrayPower::UpdateNotificationStateForRemainingPercentage() {
502 double remaining_percentage) { 274 const double remaining_percentage = PowerStatus::Get()->GetBatteryPercent();
275
503 if (remaining_percentage > kNoWarningPercentage) { 276 if (remaining_percentage > kNoWarningPercentage) {
504 notification_state_ = NOTIFICATION_NONE; 277 notification_state_ = NOTIFICATION_NONE;
505 return false; 278 return false;
506 } 279 }
507 280
508 switch (notification_state_) { 281 switch (notification_state_) {
509 case NOTIFICATION_NONE: 282 case NOTIFICATION_NONE:
510 if (remaining_percentage <= kCriticalPercentage) { 283 if (remaining_percentage <= kCriticalPercentage) {
511 notification_state_ = NOTIFICATION_CRITICAL; 284 notification_state_ = NOTIFICATION_CRITICAL;
512 return true; 285 return true;
(...skipping 11 matching lines...) Expand all
524 return false; 297 return false;
525 case NOTIFICATION_CRITICAL: 298 case NOTIFICATION_CRITICAL:
526 return false; 299 return false;
527 } 300 }
528 NOTREACHED(); 301 NOTREACHED();
529 return false; 302 return false;
530 } 303 }
531 304
532 } // namespace internal 305 } // namespace internal
533 } // namespace ash 306 } // 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