blob: 10bd7e7acad0be85f7ce8bb5c5da932136680dbe [file] [log] [blame]
// Copyright (c) 2012 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 "base/system_monitor/system_monitor.h"
#include "base/file_path.h"
#include "base/message_loop.h"
#include "base/test/mock_devices_changed_observer.h"
#include "base/utf_string_conversions.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace {
class PowerTest : public SystemMonitor::PowerObserver {
public:
PowerTest()
: power_state_changes_(0),
suspends_(0),
resumes_(0) {
}
// PowerObserver callbacks.
virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE {
power_state_changes_++;
}
virtual void OnSuspend() OVERRIDE {
suspends_++;
}
virtual void OnResume() OVERRIDE {
resumes_++;
}
// Test status counts.
int power_state_changes() { return power_state_changes_; }
int suspends() { return suspends_; }
int resumes() { return resumes_; }
private:
int power_state_changes_; // Count of OnPowerStateChange notifications.
int suspends_; // Count of OnSuspend notifications.
int resumes_; // Count of OnResume notifications.
};
class SystemMonitorTest : public testing::Test {
protected:
SystemMonitorTest() {
#if defined(OS_MACOSX)
// This needs to happen before SystemMonitor's ctor.
SystemMonitor::AllocateSystemIOPorts();
#endif
system_monitor_.reset(new SystemMonitor);
}
virtual ~SystemMonitorTest() {}
MessageLoop message_loop_;
scoped_ptr<SystemMonitor> system_monitor_;
DISALLOW_COPY_AND_ASSIGN(SystemMonitorTest);
};
TEST_F(SystemMonitorTest, PowerNotifications) {
const int kObservers = 5;
PowerTest test[kObservers];
for (int index = 0; index < kObservers; ++index)
system_monitor_->AddPowerObserver(&test[index]);
// Send a bunch of power changes. Since the battery power hasn't
// actually changed, we shouldn't get notifications.
for (int index = 0; index < 5; index++) {
system_monitor_->ProcessPowerMessage(SystemMonitor::POWER_STATE_EVENT);
EXPECT_EQ(test[0].power_state_changes(), 0);
}
// Sending resume when not suspended should have no effect.
system_monitor_->ProcessPowerMessage(SystemMonitor::RESUME_EVENT);
message_loop_.RunUntilIdle();
EXPECT_EQ(test[0].resumes(), 0);
// Pretend we suspended.
system_monitor_->ProcessPowerMessage(SystemMonitor::SUSPEND_EVENT);
message_loop_.RunUntilIdle();
EXPECT_EQ(test[0].suspends(), 1);
// Send a second suspend notification. This should be suppressed.
system_monitor_->ProcessPowerMessage(SystemMonitor::SUSPEND_EVENT);
message_loop_.RunUntilIdle();
EXPECT_EQ(test[0].suspends(), 1);
// Pretend we were awakened.
system_monitor_->ProcessPowerMessage(SystemMonitor::RESUME_EVENT);
message_loop_.RunUntilIdle();
EXPECT_EQ(test[0].resumes(), 1);
// Send a duplicate resume notification. This should be suppressed.
system_monitor_->ProcessPowerMessage(SystemMonitor::RESUME_EVENT);
message_loop_.RunUntilIdle();
EXPECT_EQ(test[0].resumes(), 1);
}
TEST_F(SystemMonitorTest, DeviceChangeNotifications) {
const int kObservers = 5;
const string16 kDeviceName = ASCIIToUTF16("media device");
const std::string kDeviceId1 = "1";
const std::string kDeviceId2 = "2";
testing::Sequence mock_sequencer[kObservers];
MockDevicesChangedObserver observers[kObservers];
for (int index = 0; index < kObservers; ++index) {
system_monitor_->AddDevicesChangedObserver(&observers[index]);
EXPECT_CALL(observers[index],
OnDevicesChanged(SystemMonitor::DEVTYPE_UNKNOWN))
.Times(3)
.InSequence(mock_sequencer[index]);
EXPECT_CALL(observers[index], OnRemovableStorageAttached(kDeviceId1,
kDeviceName,
testing::_))
.InSequence(mock_sequencer[index]);
EXPECT_CALL(observers[index], OnRemovableStorageDetached(kDeviceId1))
.InSequence(mock_sequencer[index]);
EXPECT_CALL(observers[index], OnRemovableStorageDetached(kDeviceId2))
.Times(0).InSequence(mock_sequencer[index]);
}
system_monitor_->ProcessDevicesChanged(SystemMonitor::DEVTYPE_UNKNOWN);
message_loop_.RunUntilIdle();
system_monitor_->ProcessDevicesChanged(SystemMonitor::DEVTYPE_UNKNOWN);
system_monitor_->ProcessDevicesChanged(SystemMonitor::DEVTYPE_UNKNOWN);
message_loop_.RunUntilIdle();
system_monitor_->ProcessRemovableStorageAttached(kDeviceId1,
kDeviceName,
FILE_PATH_LITERAL("path"));
message_loop_.RunUntilIdle();
system_monitor_->ProcessRemovableStorageDetached(kDeviceId1);
system_monitor_->ProcessRemovableStorageDetached(kDeviceId2);
message_loop_.RunUntilIdle();
}
TEST_F(SystemMonitorTest, GetAttachedRemovableStorageEmpty) {
std::vector<SystemMonitor::RemovableStorageInfo> devices =
system_monitor_->GetAttachedRemovableStorage();
EXPECT_EQ(0U, devices.size());
}
TEST_F(SystemMonitorTest, GetAttachedRemovableStorageAttachDetach) {
const std::string kDeviceId1 = "42";
const string16 kDeviceName1 = ASCIIToUTF16("test");
const FilePath kDevicePath1(FILE_PATH_LITERAL("/testfoo"));
system_monitor_->ProcessRemovableStorageAttached(kDeviceId1,
kDeviceName1,
kDevicePath1.value());
message_loop_.RunUntilIdle();
std::vector<SystemMonitor::RemovableStorageInfo> devices =
system_monitor_->GetAttachedRemovableStorage();
ASSERT_EQ(1U, devices.size());
EXPECT_EQ(kDeviceId1, devices[0].device_id);
EXPECT_EQ(kDeviceName1, devices[0].name);
EXPECT_EQ(kDevicePath1.value(), devices[0].location);
const std::string kDeviceId2 = "44";
const string16 kDeviceName2 = ASCIIToUTF16("test2");
const FilePath kDevicePath2(FILE_PATH_LITERAL("/testbar"));
system_monitor_->ProcessRemovableStorageAttached(kDeviceId2,
kDeviceName2,
kDevicePath2.value());
message_loop_.RunUntilIdle();
devices = system_monitor_->GetAttachedRemovableStorage();
ASSERT_EQ(2U, devices.size());
EXPECT_EQ(kDeviceId1, devices[0].device_id);
EXPECT_EQ(kDeviceName1, devices[0].name);
EXPECT_EQ(kDevicePath1.value(), devices[0].location);
EXPECT_EQ(kDeviceId2, devices[1].device_id);
EXPECT_EQ(kDeviceName2, devices[1].name);
EXPECT_EQ(kDevicePath2.value(), devices[1].location);
system_monitor_->ProcessRemovableStorageDetached(kDeviceId1);
message_loop_.RunUntilIdle();
devices = system_monitor_->GetAttachedRemovableStorage();
ASSERT_EQ(1U, devices.size());
EXPECT_EQ(kDeviceId2, devices[0].device_id);
EXPECT_EQ(kDeviceName2, devices[0].name);
EXPECT_EQ(kDevicePath2.value(), devices[0].location);
system_monitor_->ProcessRemovableStorageDetached(kDeviceId2);
message_loop_.RunUntilIdle();
devices = system_monitor_->GetAttachedRemovableStorage();
EXPECT_EQ(0U, devices.size());
}
} // namespace
} // namespace base