tray_power.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/shell_delegate.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/system/chromeos/power/power_status_view.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/date/date_view.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_notification_view.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/system/tray/tray_utils.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chromeos/dbus/power_supply_status.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/icu/public/i18n/unicode/fieldpos.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/icu/public/i18n/unicode/fmtable.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkRect.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/button.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using chromeos::PowerManagerHandler; 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using chromeos::PowerSupplyStatus; 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Width and height of battery images. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBatteryImageHeight = 25; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBatteryImageWidth = 25; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Number of different power states. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNumPowerImages = 15; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Top/bottom padding of the text items. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPaddingVertical = 10; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specify min width of status label for layout. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLabelMinWidth = 120; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Notification times. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCriticalSeconds = 5 * 60; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLowPowerSeconds = 15 * 60; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNoWarningSeconds = 30 * 60; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Minimum battery percentage rendered in UI. 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMinBatteryPercent = 1; 63a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Notification in battery percentage. 64a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const double kCriticalPercentage = 5.0; 65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const double kLowPowerPercentage = 10.0; 66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const double kNoWarningPercentage = 15.0; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 GetBatteryTimeAccessibilityString(int hour, int min) { 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(hour || min); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (hour && !min) { 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Shell::GetInstance()->delegate()->GetTimeDurationLongString( 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta::FromHours(hour)); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (min && !hour) { 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Shell::GetInstance()->delegate()->GetTimeDurationLongString( 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta::FromMinutes(min)); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return l10n_util::GetStringFUTF16( 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_TIME_ACCESSIBLE, 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Shell::GetInstance()->delegate()->GetTimeDurationLongString( 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta::FromHours(hour)), 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Shell::GetInstance()->delegate()->GetTimeDurationLongString( 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta::FromMinutes(min))); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tray { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This view is used only for the tray. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PowerTrayView : public views::ImageView { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PowerTrayView() 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : battery_icon_index_(-1), 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_offset_(0), 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_charging_unreliable_(false) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateImage(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~PowerTrayView() { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overriden from views::View. 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE { 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state->name = accessible_name_; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void UpdatePowerStatus(const PowerSupplyStatus& status, 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool battery_alert) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) supply_status_ = status; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanitize. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (supply_status_.battery_is_full) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) supply_status_.battery_percentage = 100.0; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateImage(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetVisible(status.battery_is_present); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (battery_alert) { 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) accessible_name_ = TrayPower::GetAccessibleNameString(status); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateImage() { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = TrayPower::GetBatteryImageIndex(supply_status_); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int offset = TrayPower::GetBatteryImageOffset(supply_status_); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool charging_unreliable = 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TrayPower::IsBatteryChargingUnreliable(supply_status_); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (battery_icon_index_ != index || 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_offset_ != offset || 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_charging_unreliable_ != charging_unreliable) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) battery_icon_index_ = index; 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_offset_ = offset; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_charging_unreliable_ = charging_unreliable; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (battery_icon_index_ != -1) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetImage(TrayPower::GetBatteryImage(battery_icon_index_, 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_offset_, 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_charging_unreliable_, 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ICON_LIGHT)); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PowerSupplyStatus supply_status_; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 accessible_name_; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Index of the current icon in the icon array image, or -1 if unknown. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int battery_icon_index_; 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int battery_icon_offset_; 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool battery_charging_unreliable_; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PowerTrayView); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PowerNotificationView : public TrayNotificationView { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit PowerNotificationView(TrayPower* owner) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : TrayNotificationView(owner, 0), 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_index_(-1), 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_offset_(0), 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_charging_unreliable_(false) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_status_view_ = 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new PowerStatusView(PowerStatusView::VIEW_NOTIFICATION, true); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitView(power_status_view_); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdatePowerStatus(const PowerSupplyStatus& status) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = TrayPower::GetBatteryImageIndex(status); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int offset = TrayPower::GetBatteryImageOffset(status); 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool charging_unreliable = TrayPower::IsBatteryChargingUnreliable(status); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (battery_icon_index_ != index || 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_offset_ != offset || 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_charging_unreliable_ != charging_unreliable) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) battery_icon_index_ = index; 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_offset_ = offset; 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_charging_unreliable_ = charging_unreliable; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (battery_icon_index_ != -1) { 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetIconImage(TrayPower::GetBatteryImage( 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_index_, 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_icon_offset_, 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_charging_unreliable_, 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ICON_DARK)); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_status_view_->UpdatePowerStatus(status); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PowerStatusView* power_status_view_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Index of the current icon in the icon array image, or -1 if unknown. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int battery_icon_index_; 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int battery_icon_offset_; 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool battery_charging_unreliable_; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PowerNotificationView); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace tray 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using tray::PowerNotificationView; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TrayPower::TrayPower(SystemTray* system_tray) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : SystemTrayItem(system_tray), 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_tray_(NULL), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_view_(NULL), 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_state_(NOTIFICATION_NONE) { 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PowerManagerHandler::Get()->AddObserver(this); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrayPower::~TrayPower() { 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (PowerManagerHandler::IsInitialized()) 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PowerManagerHandler::Get()->RemoveObserver(this); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool TrayPower::IsBatteryChargingUnreliable( 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chromeos::PowerSupplyStatus& supply_status) { 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) supply_status.battery_state == 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PowerSupplyStatus::NEITHER_CHARGING_NOR_DISCHARGING || 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) supply_status.battery_state == 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PowerSupplyStatus::CONNECTED_TO_USB; 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int TrayPower::GetBatteryImageIndex( 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chromeos::PowerSupplyStatus& supply_status) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_index = 0; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (supply_status.battery_percentage >= 100) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_index = kNumPowerImages - 1; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!supply_status.battery_is_present) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_index = kNumPowerImages; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_index = static_cast<int>(supply_status.battery_percentage / 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 100.0 * (kNumPowerImages - 1)); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_index = std::max(std::min(image_index, kNumPowerImages - 2), 0); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return image_index; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int TrayPower::GetBatteryImageOffset( 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chromeos::PowerSupplyStatus& supply_status) { 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsBatteryChargingUnreliable(supply_status) || 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !supply_status.line_power_on) 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 1; 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::ImageSkia TrayPower::GetBatteryImage(int image_index, 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int image_offset, 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool charging_unreliable, 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IconSet icon_set) { 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Image all; 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (charging_unreliable) { 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) all = ui::ResourceBundle::GetSharedInstance().GetImageNamed( 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) icon_set == ICON_DARK ? 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK : 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) all = ui::ResourceBundle::GetSharedInstance().GetImageNamed( 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) icon_set == ICON_DARK ? 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDR_AURA_UBER_TRAY_POWER_SMALL_DARK : IDR_AURA_UBER_TRAY_POWER_SMALL); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect region( 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) image_offset * kBatteryImageWidth, 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) image_index * kBatteryImageHeight, 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kBatteryImageWidth, kBatteryImageHeight); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 TrayPower::GetAccessibleNameString( 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chromeos::PowerSupplyStatus& supply_status) { 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (supply_status.line_power_on && supply_status.battery_is_full) { 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return rb.GetLocalizedString( 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_FULL_CHARGE_ACCESSIBLE); 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool charging_unreliable = 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IsBatteryChargingUnreliable(supply_status); 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (supply_status.battery_percentage < 0.0f) { 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (charging_unreliable) { 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return rb.GetLocalizedString( 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE_ACCESSIBLE); 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return rb.GetLocalizedString( 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE); 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 battery_percentage_accessbile = l10n_util::GetStringFUTF16( 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) supply_status.line_power_on ? 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_CHARGING_ACCESSIBLE: 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_ACCESSIBLE , 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::IntToString16(GetRoundedBatteryPercentage( 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) supply_status.battery_percentage))); 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 battery_time_accessible = base::string16(); 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (charging_unreliable) { 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_time_accessible = rb.GetLocalizedString( 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE_ACCESSIBLE); 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (supply_status.is_calculating_battery_time) { 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_time_accessible = rb.GetLocalizedString( 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING_ACCESSIBLE); 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta time = base::TimeDelta::FromSeconds( 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) supply_status.line_power_on ? 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) supply_status.battery_seconds_to_full : 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) supply_status.battery_seconds_to_empty); 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int hour = time.InHours(); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int min = (time - base::TimeDelta::FromHours(hour)).InMinutes(); 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (hour || min) { 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 minute = min < 10 ? 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASCIIToUTF16("0") + base::IntToString16(min) : 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::IntToString16(min); 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_time_accessible = 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) l10n_util::GetStringFUTF16( 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) supply_status.line_power_on ? 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL_ACCESSIBLE : 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_ACCESSIBLE, 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetBatteryTimeAccessibilityString(hour, min)); 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return battery_time_accessible.empty() ? 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_percentage_accessbile : 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) battery_percentage_accessbile + ASCIIToUTF16(". ") 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) + battery_time_accessible; 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int TrayPower::GetRoundedBatteryPercentage(double battery_percentage) { 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(battery_percentage >= 0.0); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::max(kMinBatteryPercent, 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<int>(battery_percentage + 0.5)); 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateTrayView(user::LoginStatus status) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There may not be enough information when this is created about whether 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there is a battery or not. So always create this, and adjust visibility as 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessary. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PowerSupplyStatus power_status = 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PowerManagerHandler::Get()->GetPowerSupplyStatus(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(power_tray_ == NULL); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_tray_ = new tray::PowerTrayView(); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) power_tray_->UpdatePowerStatus(power_status, false); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return power_tray_; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateDefaultView(user::LoginStatus status) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure icon status is up-to-date. (Also triggers stub activation). 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RequestStatusUpdate(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateNotificationView(user::LoginStatus status) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(notification_view_ == NULL); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PowerSupplyStatus power_status = 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PowerManagerHandler::Get()->GetPowerSupplyStatus(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!power_status.battery_is_present) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_view_ = new PowerNotificationView(this); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_view_->UpdatePowerStatus(power_status); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return notification_view_; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyTrayView() { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_tray_ = NULL; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyDefaultView() { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyNotificationView() { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_view_ = NULL; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::UpdateAfterLoginStatusChange(user::LoginStatus status) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetTrayImageItemBorder(power_tray_, alignment); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TrayPower::OnPowerStatusChanged( 39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chromeos::PowerSupplyStatus& status) { 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool battery_alert = UpdateNotificationState(status); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (power_tray_) 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) power_tray_->UpdatePowerStatus(status, battery_alert); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (notification_view_) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_view_->UpdatePowerStatus(status); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (battery_alert) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowNotificationView(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (notification_state_ == NOTIFICATION_NONE) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HideNotificationView(); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TrayPower::RequestStatusUpdate() const { 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PowerManagerHandler::Get()->RequestStatusUpdate(); 40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool TrayPower::UpdateNotificationState( 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chromeos::PowerSupplyStatus& status) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!status.battery_is_present || 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status.is_calculating_battery_time || 411a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) status.battery_state == PowerSupplyStatus::CHARGING) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_state_ = NOTIFICATION_NONE; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 416a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (TrayPower::IsBatteryChargingUnreliable(status)) { 417a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return UpdateNotificationStateForRemainingPercentage( 418a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) status.battery_percentage); 419a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } else { 420a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return UpdateNotificationStateForRemainingTime( 421a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) status.battery_seconds_to_empty); 422a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 423a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 424a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 425a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool TrayPower::UpdateNotificationStateForRemainingTime(int remaining_seconds) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remaining_seconds >= kNoWarningSeconds) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_state_ = NOTIFICATION_NONE; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (notification_state_) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NOTIFICATION_NONE: 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remaining_seconds <= kCriticalSeconds) { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_state_ = NOTIFICATION_CRITICAL; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (remaining_seconds <= kLowPowerSeconds) { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_state_ = NOTIFICATION_LOW_POWER; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NOTIFICATION_LOW_POWER: 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remaining_seconds <= kCriticalSeconds) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_state_ = NOTIFICATION_CRITICAL; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NOTIFICATION_CRITICAL: 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 454a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool TrayPower::UpdateNotificationStateForRemainingPercentage( 455a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) double remaining_percentage) { 456a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (remaining_percentage > kNoWarningPercentage) { 457a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) notification_state_ = NOTIFICATION_NONE; 458a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 459a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 460a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 461a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) switch (notification_state_) { 462a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) case NOTIFICATION_NONE: 463a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (remaining_percentage <= kCriticalPercentage) { 464a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) notification_state_ = NOTIFICATION_CRITICAL; 465a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return true; 466a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 467a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (remaining_percentage <= kLowPowerPercentage) { 468a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) notification_state_ = NOTIFICATION_LOW_POWER; 469a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return true; 470a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 471a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 472a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) case NOTIFICATION_LOW_POWER: 473a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (remaining_percentage <= kCriticalPercentage) { 474a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) notification_state_ = NOTIFICATION_CRITICAL; 475a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return true; 476a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 477a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 478a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) case NOTIFICATION_CRITICAL: 479a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 480a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 481a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) NOTREACHED(); 482a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 483a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 484a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 487