tray_power.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/accessibility_delegate.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/ash_switches.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ash/system/chromeos/power/power_status_view.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/date/date_view.h"
12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/system/system_notifier.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_constants.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/tray_notification_view.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/system/tray/tray_utils.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/time.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/i18n/unicode/fieldpos.h"
23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/i18n/unicode/fmtable.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/message_center/message_center.h"
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/message_center/notification.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/button.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing message_center::MessageCenter;
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing message_center::Notification;
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tray {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kMaxSpringChargerAccessibilityNotifyCount = 3;
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kSpringChargerAccessibilityTimerFirstTimeNotifyInSeconds = 30;
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kSpringChargerAccessibilityTimerRepeatInMinutes = 5;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This view is used only for the tray.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PowerTrayView : public views::ImageView {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PowerTrayView()
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : spring_charger_spoken_notification_count_(0) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateImage();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PowerTrayView() {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overriden from views::View.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state->name = accessible_name_;
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void UpdateStatus(bool battery_alert) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateImage();
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SetVisible(PowerStatus::Get()->IsBatteryPresent());
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (battery_alert) {
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      accessible_name_ = PowerStatus::Get()->GetAccessibleNameString();
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetupNotifyBadCharger() {
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Poll with a shorter duration timer to notify the charger issue
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // for the first time after the charger dialog is displayed.
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    spring_charger_accessility_timer_.Start(
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE, base::TimeDelta::FromSeconds(
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            kSpringChargerAccessibilityTimerFirstTimeNotifyInSeconds),
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        this, &PowerTrayView::NotifyChargerIssue);
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateImage() {
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SetImage(PowerStatus::Get()->GetBatteryImage(PowerStatus::ICON_LIGHT));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void NotifyChargerIssue() {
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!Shell::GetInstance()->accessibility_delegate()->
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            IsSpokenFeedbackEnabled())
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!Shell::GetInstance()->system_tray_delegate()->
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            IsSpringChargerReplacementDialogVisible()) {
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      spring_charger_accessility_timer_.Stop();
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    accessible_name_ =  ui::ResourceBundle::GetSharedInstance().
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        GetLocalizedString(IDS_CHARGER_REPLACEMENT_ACCESSIBILTY_NOTIFICATION);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ++spring_charger_spoken_notification_count_;
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (spring_charger_spoken_notification_count_ == 1) {
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // After notify the charger issue for the first time, repeat the
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // notification with a longer duration timer.
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      spring_charger_accessility_timer_.Stop();
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      spring_charger_accessility_timer_.Start(
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          FROM_HERE, base::TimeDelta::FromMinutes(
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              kSpringChargerAccessibilityTimerRepeatInMinutes),
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          this, &PowerTrayView::NotifyChargerIssue);
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (spring_charger_spoken_notification_count_ >=
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        kMaxSpringChargerAccessibilityNotifyCount) {
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      spring_charger_accessility_timer_.Stop();
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 accessible_name_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tracks how many times the original spring charger accessibility
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // notification has been spoken.
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int spring_charger_spoken_notification_count_;
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RepeatingTimer<PowerTrayView> spring_charger_accessility_timer_;
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PowerNotificationView : public TrayNotificationView {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit PowerNotificationView(TrayPower* owner)
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : TrayNotificationView(owner, 0) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    power_status_view_ =
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new PowerStatusView(PowerStatusView::VIEW_NOTIFICATION, true);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitView(power_status_view_);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void UpdateStatus() {
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SetIconImage(PowerStatus::Get()->GetBatteryImage(PowerStatus::ICON_DARK));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PowerStatusView* power_status_view_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PowerNotificationView);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace tray
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using tray::PowerNotificationView;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int TrayPower::kCriticalMinutes = 5;
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int TrayPower::kLowPowerMinutes = 15;
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int TrayPower::kNoWarningMinutes = 30;
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int TrayPower::kCriticalPercentage = 5;
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int TrayPower::kLowPowerPercentage = 10;
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int TrayPower::kNoWarningPercentage = 15;
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTrayPower::TrayPower(SystemTray* system_tray, MessageCenter* message_center)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SystemTrayItem(system_tray),
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      message_center_(message_center),
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      power_tray_(NULL),
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notification_view_(NULL),
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      notification_state_(NOTIFICATION_NONE),
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      usb_charger_was_connected_(false),
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      line_power_was_connected_(false) {
172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PowerStatus::Get()->AddObserver(this);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrayPower::~TrayPower() {
176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PowerStatus::Get()->RemoveObserver(this);
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateTrayView(user::LoginStatus status) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There may not be enough information when this is created about whether
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there is a battery or not. So always create this, and adjust visibility as
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // necessary.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(power_tray_ == NULL);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  power_tray_ = new tray::PowerTrayView();
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  power_tray_->UpdateStatus(false);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return power_tray_;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateDefaultView(user::LoginStatus status) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure icon status is up-to-date. (Also triggers stub activation).
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PowerStatus::Get()->RequestStatusUpdate();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TrayPower::CreateNotificationView(user::LoginStatus status) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(notification_view_ == NULL);
197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!PowerStatus::Get()->IsBatteryPresent())
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_view_ = new PowerNotificationView(this);
201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  notification_view_->UpdateStatus();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return notification_view_;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyTrayView() {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  power_tray_ = NULL;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyDefaultView() {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::DestroyNotificationView() {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_view_ = NULL;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::UpdateAfterLoginStatusChange(user::LoginStatus status) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrayPower::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetTrayImageItemBorder(power_tray_, alignment);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid TrayPower::OnPowerStatusChanged() {
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RecordChargerType();
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (PowerStatus::Get()->IsOriginalSpringChargerConnected()) {
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ash::Shell::GetInstance()->system_tray_delegate()->
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            ShowSpringChargerReplacementDialog()) {
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      power_tray_->SetupNotifyBadCharger();
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool battery_alert = UpdateNotificationState();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (power_tray_)
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    power_tray_->UpdateStatus(battery_alert);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (notification_view_)
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    notification_view_->UpdateStatus();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Factory testing may place the battery into unusual states.
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          ash::switches::kAshHideNotificationsForFactory))
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (ash::switches::UseUsbChargerNotification())
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MaybeShowUsbChargerNotification();
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (battery_alert)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShowNotificationView();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (notification_state_ == NOTIFICATION_NONE)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HideNotificationView();
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  usb_charger_was_connected_ = PowerStatus::Get()->IsUsbChargerConnected();
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  line_power_was_connected_ = PowerStatus::Get()->IsLinePowerConnected();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TrayPower::MaybeShowUsbChargerNotification() {
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char kNotificationId[] = "usb-charger";
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool usb_charger_is_connected = PowerStatus::Get()->IsUsbChargerConnected();
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for a USB charger being connected.
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (usb_charger_is_connected && !usb_charger_was_connected_) {
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_ptr<Notification> notification(new Notification(
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        message_center::NOTIFICATION_TYPE_SIMPLE,
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kNotificationId,
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE),
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        rb.GetLocalizedString(
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE_SHORT),
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        rb.GetImageNamed(IDR_AURA_NOTIFICATION_LOW_POWER_CHARGER),
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        base::string16(),
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        message_center::NotifierId(
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            message_center::NotifierId::SYSTEM_COMPONENT,
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            system_notifier::kNotifierPower),
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        message_center::RichNotificationData(),
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        NULL));
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_center_->AddNotification(notification.Pass());
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for unplug of a USB charger while the USB charger notification is
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // showing.
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!usb_charger_is_connected && usb_charger_was_connected_) {
284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_center_->RemoveNotification(kNotificationId, false);
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return false;
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TrayPower::UpdateNotificationState() {
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const PowerStatus& status = *PowerStatus::Get();
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!status.IsBatteryPresent() ||
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      status.IsBatteryTimeBeingCalculated() ||
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      status.IsMainsChargerConnected() ||
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      status.IsOriginalSpringChargerConnected()) {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notification_state_ = NOTIFICATION_NONE;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return status.IsUsbChargerConnected() ?
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      UpdateNotificationStateForRemainingPercentage() :
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      UpdateNotificationStateForRemainingTime();
303a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
304a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TrayPower::UpdateNotificationStateForRemainingTime() {
3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The notification includes a rounded minutes value, so round the estimate
3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // received from the power manager to match.
3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int remaining_minutes = static_cast<int>(
3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      PowerStatus::Get()->GetBatteryTimeToEmpty().InSecondsF() / 60.0 + 0.5);
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (remaining_minutes >= kNoWarningMinutes ||
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PowerStatus::Get()->IsBatteryFull()) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notification_state_ = NOTIFICATION_NONE;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (notification_state_) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NOTIFICATION_NONE:
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (remaining_minutes <= kCriticalMinutes) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notification_state_ = NOTIFICATION_CRITICAL;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (remaining_minutes <= kLowPowerMinutes) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notification_state_ = NOTIFICATION_LOW_POWER;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NOTIFICATION_LOW_POWER:
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      if (remaining_minutes <= kCriticalMinutes) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notification_state_ = NOTIFICATION_CRITICAL;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NOTIFICATION_CRITICAL:
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TrayPower::UpdateNotificationStateForRemainingPercentage() {
3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The notification includes a rounded percentage, so round the value received
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // from the power manager to match.
3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int remaining_percentage =
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      PowerStatus::Get()->GetRoundedBatteryPercent();
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (remaining_percentage >= kNoWarningPercentage ||
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PowerStatus::Get()->IsBatteryFull()) {
349a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    notification_state_ = NOTIFICATION_NONE;
350a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return false;
351a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
352a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
353a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  switch (notification_state_) {
354a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    case NOTIFICATION_NONE:
355a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (remaining_percentage <= kCriticalPercentage) {
356a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        notification_state_ = NOTIFICATION_CRITICAL;
357a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return true;
358a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      }
359a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (remaining_percentage <= kLowPowerPercentage) {
360a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        notification_state_ = NOTIFICATION_LOW_POWER;
361a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return true;
362a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      }
363a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return false;
364a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    case NOTIFICATION_LOW_POWER:
365a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (remaining_percentage <= kCriticalPercentage) {
366a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        notification_state_ = NOTIFICATION_CRITICAL;
367a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return true;
368a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      }
369a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return false;
370a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    case NOTIFICATION_CRITICAL:
371a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return false;
372a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
373a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  NOTREACHED();
374a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return false;
375a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
376a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TrayPower::RecordChargerType() {
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!PowerStatus::Get()->IsLinePowerConnected() ||
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      line_power_was_connected_)
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ChargerType current_charger = UNKNOWN_CHARGER;
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (PowerStatus::Get()->IsMainsChargerConnected()) {
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    current_charger = MAINS_CHARGER;
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (PowerStatus::Get()->IsUsbChargerConnected()) {
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    current_charger = USB_CHARGER;
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (PowerStatus::Get()->IsOriginalSpringChargerConnected()) {
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    current_charger =
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ash::Shell::GetInstance()->system_tray_delegate()->
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            HasUserConfirmedSafeSpringCharger() ?
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SAFE_SPRING_CHARGER : UNCONFIRMED_SPRING_CHARGER;
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (current_charger != UNKNOWN_CHARGER) {
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Power.ChargerType",
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              current_charger,
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              CHARGER_TYPE_COUNT);
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
403