summaryrefslogtreecommitdiffstats
path: root/chromeos
diff options
context:
space:
mode:
Diffstat (limited to 'chromeos')
-rw-r--r--chromeos/chromeos.gyp45
-rw-r--r--chromeos/power/power_state_override.cc80
-rw-r--r--chromeos/power/power_state_override.h59
-rw-r--r--chromeos/power/power_state_override_unittest.cc76
4 files changed, 239 insertions, 21 deletions
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index 48014f4..dbecc2b 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -124,6 +124,8 @@
'display/output_configurator.h',
'network/network_sms_handler.cc',
'network/network_sms_handler.h',
+ 'power/power_state_override.cc',
+ 'power/power_state_override.h',
],
'link_settings': {
'libraries': [
@@ -209,27 +211,27 @@
],
},
{
- 'target_name': 'chromeos_test_support_without_gmock',
- 'type': 'static_library',
- 'dependencies': [
- '../build/linux/system.gyp:dbus',
- 'chromeos',
- ],
- 'sources': [
- 'dbus/mock_dbus_thread_manager_without_gmock.cc',
- 'dbus/mock_dbus_thread_manager_without_gmock.h',
- 'dbus/ibus/mock_ibus_client.cc',
- 'dbus/ibus/mock_ibus_client.h',
- 'dbus/ibus/mock_ibus_input_context_client.cc',
- 'dbus/ibus/mock_ibus_input_context_client.h',
- 'dbus/ibus/mock_ibus_engine_factory_service.cc',
- 'dbus/ibus/mock_ibus_engine_factory_service.h',
- 'dbus/ibus/mock_ibus_engine_service.cc',
- 'dbus/ibus/mock_ibus_engine_service.h',
- ],
- 'include_dirs': [
- '..',
- ],
+ 'target_name': 'chromeos_test_support_without_gmock',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../build/linux/system.gyp:dbus',
+ 'chromeos',
+ ],
+ 'sources': [
+ 'dbus/mock_dbus_thread_manager_without_gmock.cc',
+ 'dbus/mock_dbus_thread_manager_without_gmock.h',
+ 'dbus/ibus/mock_ibus_client.cc',
+ 'dbus/ibus/mock_ibus_client.h',
+ 'dbus/ibus/mock_ibus_input_context_client.cc',
+ 'dbus/ibus/mock_ibus_input_context_client.h',
+ 'dbus/ibus/mock_ibus_engine_factory_service.cc',
+ 'dbus/ibus/mock_ibus_engine_factory_service.h',
+ 'dbus/ibus/mock_ibus_engine_service.cc',
+ 'dbus/ibus/mock_ibus_engine_service.h',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
},
{
'target_name': 'chromeos_unittests',
@@ -267,6 +269,7 @@
'dbus/introspectable_client_unittest.cc',
'dbus/modem_messaging_client_unittest.cc',
'network/network_sms_handler_unittest.cc',
+ 'power/power_state_override_unittest.cc',
],
'include_dirs': [
'..',
diff --git a/chromeos/power/power_state_override.cc b/chromeos/power/power_state_override.cc
new file mode 100644
index 0000000..20582ca
--- /dev/null
+++ b/chromeos/power/power_state_override.cc
@@ -0,0 +1,80 @@
+// 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 "chromeos/power/power_state_override.h"
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/time.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/power_manager_client.h"
+
+namespace {
+
+// Frequency with which overrides are renewed.
+const int kHeartbeatTimeInSecs = 300;
+
+// Duration beyond |kHeartbeatTimeInSecs| for which overrides are requested.
+// This should be long enough that we're able to renew the request before it
+// expires, but short enough that the power manager won't end up honoring a
+// stale request for a long time if Chrome crashes and orphans its requests.
+const int kRequestSlackInSecs = 15;
+
+} // namespace
+
+namespace chromeos {
+
+PowerStateOverride::PowerStateOverride(Mode mode)
+ : override_types_(0),
+ request_id_(0),
+ weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ switch (mode) {
+ case BLOCK_DISPLAY_SLEEP:
+ override_types_ |= (PowerManagerClient::DISABLE_IDLE_DIM |
+ PowerManagerClient::DISABLE_IDLE_BLANK);
+ // fallthrough
+ case BLOCK_SYSTEM_SUSPEND:
+ override_types_ |= (PowerManagerClient::DISABLE_IDLE_SUSPEND |
+ PowerManagerClient::DISABLE_IDLE_LID_SUSPEND);
+ break;
+ default:
+ NOTREACHED() << "Unhandled mode " << mode;
+ }
+
+ // request_id_ = 0 will create a new override request.
+ CallRequestPowerStateOverrides();
+
+ heartbeat_.Start(FROM_HERE,
+ base::TimeDelta::FromSeconds(kHeartbeatTimeInSecs),
+ weak_ptr_factory_.GetWeakPtr(),
+ &PowerStateOverride::CallRequestPowerStateOverrides);
+}
+
+PowerStateOverride::~PowerStateOverride() {
+ heartbeat_.Stop();
+
+ PowerManagerClient* power_manager =
+ DBusThreadManager::Get()->GetPowerManagerClient();
+ if (power_manager)
+ power_manager->CancelPowerStateOverrides(request_id_);
+}
+
+void PowerStateOverride::SetRequestId(uint32 request_id) {
+ request_id_ = request_id;
+}
+
+void PowerStateOverride::CallRequestPowerStateOverrides() {
+ PowerManagerClient* power_manager =
+ DBusThreadManager::Get()->GetPowerManagerClient();
+ if (power_manager) {
+ power_manager->RequestPowerStateOverrides(
+ request_id_,
+ kHeartbeatTimeInSecs + kRequestSlackInSecs,
+ override_types_,
+ base::Bind(&PowerStateOverride::SetRequestId,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+}
+
+} // namespace chromeos
diff --git a/chromeos/power/power_state_override.h b/chromeos/power/power_state_override.h
new file mode 100644
index 0000000..4e2fab9
--- /dev/null
+++ b/chromeos/power/power_state_override.h
@@ -0,0 +1,59 @@
+// 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.
+
+#ifndef CHROMEOS_POWER_POWER_STATE_OVERRIDE_H_
+#define CHROMEOS_POWER_POWER_STATE_OVERRIDE_H_
+
+#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
+#include "base/timer.h"
+#include "chromeos/chromeos_export.h"
+
+namespace chromeos {
+
+// This class overrides the current power state on the machine, disabling
+// a set of power management features.
+class CHROMEOS_EXPORT PowerStateOverride {
+ public:
+ enum Mode {
+ // Blocks the screen from being dimmed or blanked due to user inactivity.
+ // Also implies BLOCK_SYSTEM_SUSPEND.
+ BLOCK_DISPLAY_SLEEP,
+
+ // Blocks the system from being suspended due to user inactivity or (in the
+ // case of a laptop) the lid being closed.
+ BLOCK_SYSTEM_SUSPEND,
+ };
+
+ explicit PowerStateOverride(Mode mode);
+ ~PowerStateOverride();
+
+ private:
+ // Callback from RequestPowerStateOverride which receives our request_id.
+ void SetRequestId(uint32 request_id);
+
+ // Actually make a call to power manager; we need this to be able to post a
+ // delayed task since we cannot call back into power manager from Heartbeat
+ // since the last request has just been completed at that point.
+ void CallRequestPowerStateOverrides();
+
+ // Bitmap containing requested override types from
+ // PowerManagerClient::PowerStateOverrideType.
+ uint32 override_types_;
+
+ // Outstanding override request ID, or 0 if there is no outstanding request.
+ uint32 request_id_;
+
+ // Periodically invokes CallRequestPowerStateOverrides() to refresh the
+ // override.
+ base::RepeatingTimer<PowerStateOverride> heartbeat_;
+
+ base::WeakPtrFactory<PowerStateOverride> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerStateOverride);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_POWER_POWER_STATE_OVERRIDE_H_
diff --git a/chromeos/power/power_state_override_unittest.cc b/chromeos/power/power_state_override_unittest.cc
new file mode 100644
index 0000000..3deaab9
--- /dev/null
+++ b/chromeos/power/power_state_override_unittest.cc
@@ -0,0 +1,76 @@
+// 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 "chromeos/power/power_state_override.h"
+
+#include "base/message_loop.h"
+#include "chromeos/dbus/mock_power_manager_client.h"
+#include "chromeos/dbus/mock_dbus_thread_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::Mock;
+using ::testing::SaveArg;
+
+namespace chromeos {
+
+class PowerStateOverrideTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ MockDBusThreadManager* dbus_manager = new MockDBusThreadManager;
+ DBusThreadManager::InitializeForTesting(dbus_manager);
+ power_manager_client_ = dbus_manager->mock_power_manager_client();
+ }
+
+ virtual void TearDown() {
+ DBusThreadManager::Shutdown();
+ }
+
+ protected:
+ // Needed for PowerStateOverride's timer.
+ MessageLoop message_loop_;
+
+ MockPowerManagerClient* power_manager_client_; // not owned
+};
+
+TEST_F(PowerStateOverrideTest, AddAndRemoveOverrides) {
+ // An arbitrary ID to return in response to a request with ID 0.
+ const uint32 kRequestId = 10;
+
+ // Override bitmaps corresponding to different modes.
+ const uint32 kDisplayOverrides =
+ PowerManagerClient::DISABLE_IDLE_DIM |
+ PowerManagerClient::DISABLE_IDLE_BLANK |
+ PowerManagerClient::DISABLE_IDLE_SUSPEND |
+ PowerManagerClient::DISABLE_IDLE_LID_SUSPEND;
+ const uint32 kSystemOverrides =
+ PowerManagerClient::DISABLE_IDLE_SUSPEND |
+ PowerManagerClient::DISABLE_IDLE_LID_SUSPEND;
+
+ // Block display sleep and pass a request ID to the callback.
+ chromeos::PowerStateRequestIdCallback request_id_callback;
+ EXPECT_CALL(*power_manager_client_,
+ RequestPowerStateOverrides(0, _, kDisplayOverrides, _))
+ .WillOnce(SaveArg<3>(&request_id_callback));
+ scoped_ptr<PowerStateOverride> override(
+ new PowerStateOverride(PowerStateOverride::BLOCK_DISPLAY_SLEEP));
+ request_id_callback.Run(kRequestId);
+
+ // The request should be canceled when the PowerStateOverride is destroyed.
+ EXPECT_CALL(*power_manager_client_, CancelPowerStateOverrides(kRequestId));
+ override.reset();
+
+ // Now send a request to just block the system from suspending.
+ Mock::VerifyAndClearExpectations(power_manager_client_);
+ EXPECT_CALL(*power_manager_client_,
+ RequestPowerStateOverrides(0, _, kSystemOverrides, _))
+ .WillOnce(SaveArg<3>(&request_id_callback));
+ override.reset(
+ new PowerStateOverride(PowerStateOverride::BLOCK_SYSTEM_SUSPEND));
+ request_id_callback.Run(kRequestId);
+ EXPECT_CALL(*power_manager_client_, CancelPowerStateOverrides(kRequestId));
+ override.reset();
+}
+
+} // namespace chromeos