summaryrefslogtreecommitdiffstats
path: root/base/win
diff options
context:
space:
mode:
authorsiggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-18 20:40:06 +0000
committersiggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-18 20:40:06 +0000
commit7bf385c831f60fe166f0a9e4370a4542d2d40ff3 (patch)
treef24ecac3a32c2a7d14969693efdfac1058e2f6a2 /base/win
parent3a36243cac7dbb5d700b25d3d51736895b4388f0 (diff)
downloadchromium_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.cc57
-rw-r--r--base/win/metro.h4
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);