root/ash/system/chromeos/power/tray_power_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. remove_count_
  2. add_count
  3. remove_count
  4. AddNotification
  5. RemoveNotification
  6. message_center
  7. tray_power
  8. SetUp
  9. TearDown
  10. notification_state
  11. MaybeShowUsbChargerNotification
  12. UpdateNotificationState
  13. SetUsbChargerConnected
  14. DefaultPowerSupplyProperties
  15. TEST_F
  16. TEST_F

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/chromeos/power/tray_power.h"

#include "ash/ash_switches.h"
#include "ash/test/ash_test_base.h"
#include "base/memory/scoped_ptr.h"
#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
#include "ui/message_center/fake_message_center.h"

using message_center::Notification;
using power_manager::PowerSupplyProperties;

namespace {

class MockMessageCenter : public message_center::FakeMessageCenter {
 public:
  MockMessageCenter() : add_count_(0), remove_count_(0) {}
  virtual ~MockMessageCenter() {}

  int add_count() const { return add_count_; }
  int remove_count() const { return remove_count_; }

  // message_center::FakeMessageCenter overrides:
  virtual void AddNotification(scoped_ptr<Notification> notification) OVERRIDE {
    add_count_++;
  }
  virtual void RemoveNotification(const std::string& id, bool by_user)
      OVERRIDE {
    remove_count_++;
  }

 private:
  int add_count_;
  int remove_count_;

  DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
};

}  // namespace

namespace ash {

class TrayPowerTest : public test::AshTestBase {
 public:
  TrayPowerTest() {}
  virtual ~TrayPowerTest() {}

  MockMessageCenter* message_center() { return message_center_.get(); }
  TrayPower* tray_power() { return tray_power_.get(); }

  // test::AshTestBase::SetUp() overrides:
  virtual void SetUp() OVERRIDE {
    test::AshTestBase::SetUp();
    message_center_.reset(new MockMessageCenter());
    tray_power_.reset(new TrayPower(NULL, message_center_.get()));
  }

  virtual void TearDown() OVERRIDE {
    tray_power_.reset();
    message_center_.reset();
    test::AshTestBase::TearDown();
  }

  TrayPower::NotificationState notification_state() const {
    return tray_power_->notification_state_;
  }

  bool MaybeShowUsbChargerNotification(const PowerSupplyProperties& proto) {
    PowerStatus::Get()->SetProtoForTesting(proto);
    return tray_power_->MaybeShowUsbChargerNotification();
  }

  bool UpdateNotificationState(const PowerSupplyProperties& proto) {
    PowerStatus::Get()->SetProtoForTesting(proto);
    return tray_power_->UpdateNotificationState();
  }

  void SetUsbChargerConnected(bool connected) {
    tray_power_->usb_charger_was_connected_ = connected;
   }

  // Returns a discharging PowerSupplyProperties more appropriate for testing.
  static PowerSupplyProperties DefaultPowerSupplyProperties() {
    PowerSupplyProperties proto;
    proto.set_external_power(
        power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED);
    proto.set_battery_state(
        power_manager::PowerSupplyProperties_BatteryState_DISCHARGING);
    proto.set_battery_percent(50.0);
    proto.set_battery_time_to_empty_sec(3 * 60 * 60);
    proto.set_battery_time_to_full_sec(2 * 60 * 60);
    proto.set_is_calculating_battery_time(false);
    return proto;
  }

 private:
  scoped_ptr<MockMessageCenter> message_center_;
  scoped_ptr<TrayPower> tray_power_;

  DISALLOW_COPY_AND_ASSIGN(TrayPowerTest);
};

TEST_F(TrayPowerTest, MaybeShowUsbChargerNotification) {
  PowerSupplyProperties discharging = DefaultPowerSupplyProperties();
  EXPECT_FALSE(MaybeShowUsbChargerNotification(discharging));
  EXPECT_EQ(0, message_center()->add_count());
  EXPECT_EQ(0, message_center()->remove_count());

  // Notification shows when connecting a USB charger.
  PowerSupplyProperties usb_connected = DefaultPowerSupplyProperties();
  usb_connected.set_external_power(
      power_manager::PowerSupplyProperties_ExternalPower_USB);
  EXPECT_TRUE(MaybeShowUsbChargerNotification(usb_connected));
  EXPECT_EQ(1, message_center()->add_count());
  EXPECT_EQ(0, message_center()->remove_count());

  // Change in charge does not trigger the notification again.
  PowerSupplyProperties more_charge = DefaultPowerSupplyProperties();
  more_charge.set_external_power(
      power_manager::PowerSupplyProperties_ExternalPower_USB);
  more_charge.set_battery_time_to_full_sec(60 * 60);
  more_charge.set_battery_percent(75.0);
  SetUsbChargerConnected(true);
  EXPECT_FALSE(MaybeShowUsbChargerNotification(more_charge));
  EXPECT_EQ(1, message_center()->add_count());
  EXPECT_EQ(0, message_center()->remove_count());

  // Disconnecting a USB charger with the notification showing should close
  // the notification.
  EXPECT_TRUE(MaybeShowUsbChargerNotification(discharging));
  EXPECT_EQ(1, message_center()->add_count());
  EXPECT_EQ(1, message_center()->remove_count());
}

TEST_F(TrayPowerTest, UpdateNotificationState) {
  // No notifications when no battery present.
  PowerSupplyProperties no_battery = DefaultPowerSupplyProperties();
  no_battery.set_external_power(
      power_manager::PowerSupplyProperties_ExternalPower_AC);
  no_battery.set_battery_state(
      power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT);
  EXPECT_FALSE(UpdateNotificationState(no_battery));
  EXPECT_EQ(TrayPower::NOTIFICATION_NONE, notification_state());

  // No notification when calculating remaining battery time.
  PowerSupplyProperties calculating = DefaultPowerSupplyProperties();
  calculating.set_is_calculating_battery_time(true);
  EXPECT_FALSE(UpdateNotificationState(calculating));
  EXPECT_EQ(TrayPower::NOTIFICATION_NONE, notification_state());

  // No notification when charging.
  PowerSupplyProperties charging = DefaultPowerSupplyProperties();
  charging.set_external_power(
      power_manager::PowerSupplyProperties_ExternalPower_AC);
  charging.set_battery_state(
      power_manager::PowerSupplyProperties_BatteryState_CHARGING);
  EXPECT_FALSE(UpdateNotificationState(charging));
  EXPECT_EQ(TrayPower::NOTIFICATION_NONE, notification_state());

  // When the rounded minutes-to-empty are above the threshold, no notification
  // should be shown.
  PowerSupplyProperties low = DefaultPowerSupplyProperties();
  low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 + 30);
  EXPECT_FALSE(UpdateNotificationState(low));
  EXPECT_EQ(TrayPower::NOTIFICATION_NONE, notification_state());

  // When the rounded value matches the threshold, the notification should
  // appear.
  low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 + 29);
  EXPECT_TRUE(UpdateNotificationState(low));
  EXPECT_EQ(TrayPower::NOTIFICATION_LOW_POWER, notification_state());

  // It should persist at lower values.
  low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 - 20);
  EXPECT_FALSE(UpdateNotificationState(low));
  EXPECT_EQ(TrayPower::NOTIFICATION_LOW_POWER, notification_state());

  // The critical low battery notification should be shown when the rounded
  // value is at the lower threshold.
  PowerSupplyProperties critical = DefaultPowerSupplyProperties();
  critical.set_battery_time_to_empty_sec(TrayPower::kCriticalMinutes * 60 + 29);
  EXPECT_TRUE(UpdateNotificationState(critical));
  EXPECT_EQ(TrayPower::NOTIFICATION_CRITICAL, notification_state());

  // The notification should be dismissed when the no-warning threshold is
  // reached.
  PowerSupplyProperties safe = DefaultPowerSupplyProperties();
  safe.set_battery_time_to_empty_sec(TrayPower::kNoWarningMinutes * 60 - 29);
  EXPECT_FALSE(UpdateNotificationState(safe));
  EXPECT_EQ(TrayPower::NOTIFICATION_NONE, notification_state());

  // Test that rounded percentages are used when a USB charger is connected.
  PowerSupplyProperties low_usb = DefaultPowerSupplyProperties();
  low_usb.set_external_power(
      power_manager::PowerSupplyProperties_ExternalPower_USB);
  low_usb.set_battery_percent(TrayPower::kLowPowerPercentage + 0.5);
  EXPECT_FALSE(UpdateNotificationState(low_usb));
  EXPECT_EQ(TrayPower::NOTIFICATION_NONE, notification_state());

  low_usb.set_battery_percent(TrayPower::kLowPowerPercentage + 0.49);
  EXPECT_TRUE(UpdateNotificationState(low_usb));
  EXPECT_EQ(TrayPower::NOTIFICATION_LOW_POWER, notification_state());

  PowerSupplyProperties critical_usb = DefaultPowerSupplyProperties();
  critical_usb.set_external_power(
      power_manager::PowerSupplyProperties_ExternalPower_USB);
  critical_usb.set_battery_percent(TrayPower::kCriticalPercentage + 0.2);
  EXPECT_TRUE(UpdateNotificationState(critical_usb));
  EXPECT_EQ(TrayPower::NOTIFICATION_CRITICAL, notification_state());

  PowerSupplyProperties safe_usb = DefaultPowerSupplyProperties();
  safe_usb.set_external_power(
      power_manager::PowerSupplyProperties_ExternalPower_USB);
  safe_usb.set_battery_percent(TrayPower::kNoWarningPercentage - 0.1);
  EXPECT_FALSE(UpdateNotificationState(safe_usb));
  EXPECT_EQ(TrayPower::NOTIFICATION_NONE, notification_state());

  // A notification shouldn't be shown when we're in the full state with an
  // original Spring charger connected: http://crbug.com/338376
  PowerSupplyProperties spring = DefaultPowerSupplyProperties();
  spring.set_external_power(power_manager::
      PowerSupplyProperties_ExternalPower_ORIGINAL_SPRING_CHARGER);
  spring.set_battery_state(
      power_manager::PowerSupplyProperties_BatteryState_FULL);
  spring.set_battery_time_to_empty_sec(0);
  spring.set_battery_time_to_full_sec(0);
  EXPECT_FALSE(UpdateNotificationState(spring));
  EXPECT_EQ(TrayPower::NOTIFICATION_NONE, notification_state());
}

}  // namespace ash

/* [<][>][^][v][top][bottom][index][help] */