Merge from Chromium at DEPS revision r167172
This commit was generated by merge_to_master.py.
Change-Id: Ib8d56fd5ae39a2d7e8c91dcd76cc6d13f25f2aab
diff --git a/base/win/metro.cc b/base/win/metro.cc
new file mode 100644
index 0000000..22bc5e8
--- /dev/null
+++ b/base/win/metro.cc
@@ -0,0 +1,189 @@
+// 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/win/metro.h"
+
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/win/scoped_comptr.h"
+#include "base/win/windows_version.h"
+
+namespace base {
+namespace win {
+
+namespace {
+bool g_should_tsf_aware_required = false;
+}
+
+HMODULE GetMetroModule() {
+ 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
+ };
+ // The immersive state of a process can never change.
+ // Look it up once and cache it here.
+ static ImmersiveState state = kImmersiveUnknown;
+
+ if (state == kImmersiveUnknown) {
+ if (IsProcessImmersive(::GetCurrentProcess())) {
+ state = kImmersiveTrue;
+ } else {
+ state = kImmersiveFalse;
+ }
+ }
+ DCHECK_NE(kImmersiveUnknown, state);
+ return state == kImmersiveTrue;
+}
+
+bool IsProcessImmersive(HANDLE process) {
+ typedef BOOL (WINAPI* IsImmersiveProcessFunc)(HANDLE process);
+ HMODULE user32 = ::GetModuleHandleA("user32.dll");
+ DCHECK(user32 != NULL);
+
+ IsImmersiveProcessFunc is_immersive_process =
+ reinterpret_cast<IsImmersiveProcessFunc>(
+ ::GetProcAddress(user32, "IsImmersiveProcess"));
+
+ if (is_immersive_process)
+ return is_immersive_process(process) ? true: false;
+ return false;
+}
+
+bool IsTSFAwareRequired() {
+ // Although this function is equal to IsMetroProcess at this moment,
+ // Chrome for Win7 and Vista may support TSF in the future.
+ return g_should_tsf_aware_required || IsMetroProcess();
+}
+
+void SetForceToUseTSF() {
+ g_should_tsf_aware_required = true;
+
+ // Since Windows 8 Metro mode disables CUAS (Cicero Unaware Application
+ // Support) via ImmDisableLegacyIME API, Chrome must be fully TSF-aware on
+ // Metro mode. For debugging purposes, explicitly call ImmDisableLegacyIME so
+ // that one can test TSF functionality even on Windows 8 desktop mode. Note
+ // that CUAS cannot be disabled on Windows Vista/7 where ImmDisableLegacyIME
+ // is not available.
+ typedef BOOL (* ImmDisableLegacyIMEFunc)();
+ HMODULE imm32 = ::GetModuleHandleA("imm32.dll");
+ if (imm32 == NULL)
+ return;
+
+ ImmDisableLegacyIMEFunc imm_disable_legacy_ime =
+ reinterpret_cast<ImmDisableLegacyIMEFunc>(
+ ::GetProcAddress(imm32, "ImmDisableLegacyIME"));
+
+ if (imm_disable_legacy_ime == NULL) {
+ // Unsupported API, just do nothing.
+ return;
+ }
+
+ if (!imm_disable_legacy_ime()) {
+ DVLOG(1) << "Failed to disable legacy IME.";
+ }
+}
+
+wchar_t* LocalAllocAndCopyString(const string16& src) {
+ size_t dest_size = (src.length() + 1) * sizeof(wchar_t);
+ wchar_t* dest = reinterpret_cast<wchar_t*>(LocalAlloc(LPTR, dest_size));
+ base::wcslcpy(dest, src.c_str(), dest_size);
+ return dest;
+}
+
+bool IsTouchEnabled() {
+ int value = GetSystemMetrics(SM_DIGITIZER);
+ return (value & (NID_READY | NID_INTEGRATED_TOUCH)) ==
+ (NID_READY | NID_INTEGRATED_TOUCH);
+}
+
+bool IsParentalControlActivityLoggingOn() {
+ // Query this info on Windows Vista and above.
+ if (base::win::GetVersion() < base::win::VERSION_VISTA)
+ return false;
+
+ static bool parental_control_logging_required = false;
+ static bool parental_control_status_determined = false;
+
+ if (parental_control_status_determined)
+ return parental_control_logging_required;
+
+ parental_control_status_determined = true;
+
+ ScopedComPtr<IWindowsParentalControlsCore> parent_controls;
+ HRESULT hr = parent_controls.CreateInstance(
+ __uuidof(WindowsParentalControls));
+ if (FAILED(hr))
+ return false;
+
+ ScopedComPtr<IWPCSettings> settings;
+ hr = parent_controls->GetUserSettings(NULL, settings.Receive());
+ if (FAILED(hr))
+ return false;
+
+ unsigned long restrictions = 0;
+ settings->GetRestrictions(&restrictions);
+
+ parental_control_logging_required =
+ (restrictions & WPCFLAG_LOGGING_REQUIRED) == WPCFLAG_LOGGING_REQUIRED;
+ return parental_control_logging_required;
+}
+
+// Metro driver exports for getting the launch type, initial url, initial
+// search term, etc.
+extern "C" {
+typedef const wchar_t* (*GetInitialUrl)();
+typedef const wchar_t* (*GetInitialSearchString)();
+typedef base::win::MetroLaunchType (*GetLaunchType)(
+ base::win::MetroPreviousExecutionState* previous_state);
+}
+
+MetroLaunchType GetMetroLaunchParams(string16* params) {
+ HMODULE metro = base::win::GetMetroModule();
+ if (!metro)
+ return base::win::METRO_LAUNCH_ERROR;
+
+ GetLaunchType get_launch_type = reinterpret_cast<GetLaunchType>(
+ ::GetProcAddress(metro, "GetLaunchType"));
+ DCHECK(get_launch_type);
+
+ base::win::MetroLaunchType launch_type = get_launch_type(NULL);
+
+ if ((launch_type == base::win::METRO_PROTOCOL) ||
+ (launch_type == base::win::METRO_LAUNCH)) {
+ GetInitialUrl initial_metro_url = reinterpret_cast<GetInitialUrl>(
+ ::GetProcAddress(metro, "GetInitialUrl"));
+ DCHECK(initial_metro_url);
+ *params = initial_metro_url();
+ } else if (launch_type == base::win::METRO_SEARCH) {
+ GetInitialSearchString initial_search_string =
+ reinterpret_cast<GetInitialSearchString>(
+ ::GetProcAddress(metro, "GetInitialSearchString"));
+ DCHECK(initial_search_string);
+ *params = initial_search_string();
+ }
+ return launch_type;
+}
+
+} // namespace win
+} // namespace base