Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3737)

Unified Diff: base/system_monitor/system_monitor_win.cc

Issue 10389227: Base: Add power requirements to the System monitor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/system_monitor/system_monitor_unittest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/system_monitor/system_monitor_win.cc
===================================================================
--- base/system_monitor/system_monitor_win.cc (revision 138003)
+++ base/system_monitor/system_monitor_win.cc (working copy)
@@ -1,9 +1,111 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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/utf_string_conversions.h"
+#include "base/win/windows_version.h"
+namespace {
+
+// Maps a request's reason to the handle and requests count.
+typedef std::map<std::string, std::pair<HANDLE, int> > HandleMap;
+
+#if _WIN32_WINNT <= _WIN32_WINNT_WIN7
+POWER_REQUEST_TYPE PowerRequestExecutionRequired =
+ static_cast<POWER_REQUEST_TYPE>(PowerRequestAwayModeRequired + 1);
+#endif
+
+POWER_REQUEST_TYPE PowerRequestTestRequired =
+ static_cast<POWER_REQUEST_TYPE>(PowerRequestExecutionRequired + 10);
+
+POWER_REQUEST_TYPE PowerRequirementToType(
+ base::SystemMonitor::PowerRequirement requirement) {
+ switch (requirement) {
+ case base::SystemMonitor::DISPLAY_REQUIRED:
+ return PowerRequestDisplayRequired;
+ case base::SystemMonitor::SYSTEM_REQUIRED:
+ return PowerRequestSystemRequired;
+ case base::SystemMonitor::CPU_REQUIRED:
+ return PowerRequestExecutionRequired;
+ case base::SystemMonitor::TEST_REQUIRED:
+ return PowerRequestTestRequired;
+ }
+ NOTREACHED();
+ return PowerRequestTestRequired;
+}
+
+HANDLE CreatePowerRequest(POWER_REQUEST_TYPE type, const std::string& reason) {
+ typedef HANDLE (WINAPI* PowerCreateRequestPtr)(PREASON_CONTEXT);
+ typedef BOOL (WINAPI* PowerSetRequestPtr)(HANDLE, POWER_REQUEST_TYPE);
+
+ if (type == PowerRequestTestRequired)
+ return NULL;
+
+ if (type == PowerRequestExecutionRequired &&
+ base::win::GetVersion() < base::win::VERSION_WIN8) {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ static PowerCreateRequestPtr PowerCreateRequestFn = NULL;
+ static PowerSetRequestPtr PowerSetRequestFn = NULL;
+
+ if (!PowerCreateRequestFn || !PowerSetRequestFn) {
+ HMODULE module = GetModuleHandle(L"kernel32.dll");
+ PowerCreateRequestFn = reinterpret_cast<PowerCreateRequestPtr>(
+ GetProcAddress(module, "PowerCreateRequest"));
+ PowerSetRequestFn = reinterpret_cast<PowerSetRequestPtr>(
+ GetProcAddress(module, "PowerSetRequest"));
+
+ if (!PowerCreateRequestFn || !PowerSetRequestFn)
+ return INVALID_HANDLE_VALUE;
+ }
+ string16 wide_reason = ASCIIToUTF16(reason);
+ REASON_CONTEXT context = {0};
+ context.Version = POWER_REQUEST_CONTEXT_VERSION;
+ context.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
+ context.Reason.SimpleReasonString = const_cast<wchar_t*>(wide_reason.c_str());
+
+ base::win::ScopedHandle handle(PowerCreateRequestFn(&context));
+ if (!handle.IsValid())
+ return INVALID_HANDLE_VALUE;
+
+ if (PowerSetRequestFn(handle, type))
+ return handle.Take();
+
+ // Something went wrong.
+ return INVALID_HANDLE_VALUE;
+}
+
+// Takes ownership of the |handle|.
+void DeletePowerRequest(POWER_REQUEST_TYPE type, HANDLE handle) {
+ if (type == PowerRequestTestRequired)
+ return;
+
+ base::win::ScopedHandle request_handle(handle);
+ if (!request_handle.IsValid())
+ return;
+
+ if (type == PowerRequestExecutionRequired &&
+ base::win::GetVersion() < base::win::VERSION_WIN8) {
+ return;
+ }
+
+ typedef BOOL (WINAPI* PowerClearRequestPtr)(HANDLE, POWER_REQUEST_TYPE);
+ HMODULE module = GetModuleHandle(L"kernel32.dll");
+ PowerClearRequestPtr PowerClearRequestFn =
+ reinterpret_cast<PowerClearRequestPtr>(
+ GetProcAddress(module, "PowerClearRequest"));
+
+ if (!PowerClearRequestFn)
+ return;
+
+ BOOL success = PowerClearRequestFn(request_handle, type);
+ DCHECK(success);
+}
+
+} // namespace.
+
namespace base {
void SystemMonitor::ProcessWmPowerBroadcastMessage(int event_id) {
@@ -36,6 +138,50 @@
ProcessPowerMessage(power_event);
}
+void SystemMonitor::BeginPowerRequirement(PowerRequirement requirement,
+ const std::string& reason) {
+ thread_checker_.CalledOnValidThread();
+
+ HandleMap::iterator i = handles_.find(reason);
+ if (i != handles_.end()) {
+ // This is not the first request, just increase the requests count.
+ i->second.second++;
+ DCHECK_GT(i->second.second, 1);
+ return;
+ }
+
+ HANDLE handle = CreatePowerRequest(PowerRequirementToType(requirement),
+ reason);
+
+ if (handle != INVALID_HANDLE_VALUE)
+ handles_[reason] = std::pair<HANDLE, int>(handle, 1);
+}
+
+void SystemMonitor::EndPowerRequirement(PowerRequirement requirement,
+ const std::string& reason) {
+ thread_checker_.CalledOnValidThread();
+
+ HandleMap::iterator i = handles_.find(reason);
+ if (i == handles_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ // Decrease the requests count and see if this the last request.
+ i->second.second--;
+ DCHECK_GE(i->second.second, 0);
+
+ if (i->second.second)
+ return;
+
+ DeletePowerRequest(PowerRequirementToType(requirement), i->second.first);
+ handles_.erase(i);
+}
+
+size_t SystemMonitor::GetPowerRequirementsCountForTest() const {
+ return handles_.size();
+}
+
// Function to query the system to see if it is currently running on
// battery power. Returns true if running on battery.
bool SystemMonitor::IsBatteryPower() {
« no previous file with comments | « base/system_monitor/system_monitor_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698