diff options
author | siggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 20:40:06 +0000 |
---|---|---|
committer | siggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 20:40:06 +0000 |
commit | 7bf385c831f60fe166f0a9e4370a4542d2d40ff3 (patch) | |
tree | f24ecac3a32c2a7d14969693efdfac1058e2f6a2 /base/win | |
parent | 3a36243cac7dbb5d700b25d3d51736895b4388f0 (diff) | |
download | chromium_src-7bf385c831f60fe166f0a9e4370a4542d2d40ff3.zip chromium_src-7bf385c831f60fe166f0a9e4370a4542d2d40ff3.tar.gz chromium_src-7bf385c831f60fe166f0a9e4370a4542d2d40ff3.tar.bz2 |
Implement base::win::IsMetroProcess.
Change GetMetroModule callers that don't need the HMODULE.
TBR=stevenjb@chromium.org,brettw@chromium.org,mirandac@chromium.org,sky@chromium.org,kalman@chromium.org
BUG=None
TEST=None
Review URL: https://chromiumcodereview.appspot.com/10560015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142801 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/win')
-rw-r--r-- | base/win/metro.cc | 57 | ||||
-rw-r--r-- | base/win/metro.h | 4 |
2 files changed, 60 insertions, 1 deletions
diff --git a/base/win/metro.cc b/base/win/metro.cc index 81e3bda..46476c8 100644 --- a/base/win/metro.cc +++ b/base/win/metro.cc @@ -12,7 +12,62 @@ namespace win { const char kActivateApplication[] = "ActivateApplication"; HMODULE GetMetroModule() { - return GetModuleHandleA("metro_driver.dll"); + const HMODULE kUninitialized = reinterpret_cast<HMODULE>(1); + static HMODULE metro_module = kUninitialized; + + if (metro_module == kUninitialized) { + // Initialize the cache, note that the initialization is idempotent + // under the assumption that metro_driver is never unloaded, so the + // race to this assignment is safe. + metro_module = GetModuleHandleA("metro_driver.dll"); + if (metro_module != NULL) { + // This must be a metro process if the metro_driver is loaded. + DCHECK(IsMetroProcess()); + } + } + + DCHECK(metro_module != kUninitialized); + return metro_module; +} + +bool IsMetroProcess() { + enum ImmersiveState { + kImmersiveUnknown, + kImmersiveTrue, + kImmersiveFalse + }; + typedef BOOL (WINAPI* IsImmersiveProcessFunc)(HANDLE process); + + // The immersive state of a process can never change. + // Look it up once and cache it here. + static ImmersiveState state = kImmersiveUnknown; + + if (state == kImmersiveUnknown) { + // The lookup hasn't been done yet. Note that the code below here is + // idempotent, so it doesn't matter if it races to assignment on multiple + // threads. + HMODULE user32 = ::GetModuleHandleA("user32.dll"); + DCHECK(user32 != NULL); + + IsImmersiveProcessFunc is_immersive_process = + reinterpret_cast<IsImmersiveProcessFunc>( + ::GetProcAddress(user32, "IsImmersiveProcess")); + + if (is_immersive_process != NULL) { + if (is_immersive_process(::GetCurrentProcess())) { + state = kImmersiveTrue; + } else { + state = kImmersiveFalse; + } + } else { + // No "IsImmersiveProcess" export on user32.dll, so this is pre-Windows8 + // and therefore not immersive. + state = kImmersiveFalse; + } + } + DCHECK_NE(kImmersiveUnknown, state); + + return state == kImmersiveTrue; } wchar_t* LocalAllocAndCopyString(const string16& src) { diff --git a/base/win/metro.h b/base/win/metro.h index be13a30..e25c6f4 100644 --- a/base/win/metro.h +++ b/base/win/metro.h @@ -51,6 +51,10 @@ BASE_EXPORT extern const char kActivateApplication[]; // indicates that the metro dll was not loaded in the process. BASE_EXPORT HMODULE GetMetroModule(); +// Returns true if this process is running as an immersive program +// in Windows Metro mode. +BASE_EXPORT bool IsMetroProcess(); + // Allocates and returns the destination string via the LocalAlloc API after // copying the src to it. BASE_EXPORT wchar_t* LocalAllocAndCopyString(const string16& src); |