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

Unified Diff: content/browser/power_save_blocker_win.cc

Issue 10538013: Content: Implement PowerSaveBlocker2 for windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/power_save_blocker_win.cc
===================================================================
--- content/browser/power_save_blocker_win.cc (revision 139838)
+++ content/browser/power_save_blocker_win.cc (working copy)
@@ -7,6 +7,9 @@
#include <windows.h>
#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "base/win/scoped_handle.h"
+#include "base/win/windows_version.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
@@ -31,3 +34,170 @@
SetThreadExecutionState(flags);
}
+
+// TODO(rvargas): Remove after the old interface goes away.
+#define PowerSaveBlocker PowerSaveBlocker2
+
+namespace {
+
+int g_blocker_count[2];
+
+#if _WIN32_WINNT <= _WIN32_WINNT_WIN7
+POWER_REQUEST_TYPE PowerRequestExecutionRequired =
+ static_cast<POWER_REQUEST_TYPE>(PowerRequestAwayModeRequired + 1);
+#endif
+
+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 == 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) {
+ 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);
+}
+
+void ApplySimpleBlock(content::PowerSaveBlocker::PowerSaveBlockerType type,
+ int delta) {
+ g_blocker_count[type] += delta;
+ DCHECK_GE(g_blocker_count[type], 0);
+
+ if (g_blocker_count[type] > 1)
+ return;
+
+ DWORD this_flag = 0;
+ if (type == content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension)
+ this_flag |= ES_SYSTEM_REQUIRED;
+ else
+ this_flag |= ES_DISPLAY_REQUIRED;
+
+ DCHECK(this_flag);
+
+ static DWORD flags = ES_CONTINUOUS;
+ if (!g_blocker_count[type])
+ flags &= ~this_flag;
+ else
+ flags |= this_flag;
+
+ SetThreadExecutionState(flags);
+}
+
+} // namespace.
+
+namespace content {
+
+class PowerSaveBlocker::Delegate
+ : public base::RefCountedThreadSafe<PowerSaveBlocker::Delegate> {
+ public:
+ Delegate(PowerSaveBlockerType type, const std::string& reason)
+ : type_(type), reason_(reason) {}
+
+ // Does the actual work to apply or remove the desired power save block.
+ void ApplyBlock();
+ void RemoveBlock();
+
+ // Returns the equivalent POWER_REQUEST_TYPE for this request.
+ POWER_REQUEST_TYPE RequestType();
+
+ private:
+ friend class base::RefCountedThreadSafe<PowerSaveBlocker::Delegate>;
+ ~Delegate() {}
+
+ PowerSaveBlockerType type_;
+ const std::string reason_;
Avi (use Gerrit) 2012/06/05 19:03:29 why is this const?
rvargas (doing something else) 2012/06/05 19:06:05 no particular reason, but there's no need to be ab
+ base::win::ScopedHandle handle_;
+};
cpu_(ooo_6.6-7.5) 2012/06/05 23:26:22 disallow copy and assign?
rvargas (doing something else) 2012/06/05 23:52:13 Done.
+
+void PowerSaveBlocker::Delegate::ApplyBlock() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::win::Version os_version = base::win::GetVersion();
+ if (os_version < base::win::VERSION_WIN7)
+ return ApplySimpleBlock(type_, 1);
+
+ handle_.Set(CreatePowerRequest(RequestType(), reason_));
+}
+
+void PowerSaveBlocker::Delegate::RemoveBlock() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::win::Version os_version = base::win::GetVersion();
+ if (os_version < base::win::VERSION_WIN7)
+ return ApplySimpleBlock(type_, -1);
+
+ DeletePowerRequest(RequestType(), handle_.Take());
+}
+
+POWER_REQUEST_TYPE PowerSaveBlocker::Delegate::RequestType() {
+ if (type_ == kPowerSaveBlockPreventDisplaySleep)
+ return PowerRequestDisplayRequired;
+
+ return PowerRequestExecutionRequired;
+}
+
+PowerSaveBlocker::PowerSaveBlocker(PowerSaveBlockerType type,
+ const std::string& reason)
+ : delegate_(new Delegate(type, reason)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&Delegate::ApplyBlock, delegate_));
+}
+
+PowerSaveBlocker::~PowerSaveBlocker() {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&Delegate::RemoveBlock, delegate_));
+}
+
+} // namespace content
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698