summaryrefslogtreecommitdiff
path: root/chromium/base
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base')
-rw-r--r--chromium/base/BUILD.gn1
-rw-r--r--chromium/base/base.gyp1
-rw-r--r--chromium/base/win/win_util.cc95
-rw-r--r--chromium/base/win/windows_version.cc105
-rw-r--r--chromium/base/win/windows_version.h23
-rw-r--r--chromium/base/win/windows_version_unittest.cc22
6 files changed, 207 insertions, 40 deletions
diff --git a/chromium/base/BUILD.gn b/chromium/base/BUILD.gn
index 1265df839b5..8f21b5825ca 100644
--- a/chromium/base/BUILD.gn
+++ b/chromium/base/BUILD.gn
@@ -1856,6 +1856,7 @@ test("base_unittests") {
"win/shortcut_unittest.cc",
"win/startup_information_unittest.cc",
"win/win_util_unittest.cc",
+ "win/windows_version_unittest.cc",
"win/wrapped_window_proc_unittest.cc",
]
diff --git a/chromium/base/base.gyp b/chromium/base/base.gyp
index 94a1d492585..dc794be5064 100644
--- a/chromium/base/base.gyp
+++ b/chromium/base/base.gyp
@@ -669,6 +669,7 @@
'win/shortcut_unittest.cc',
'win/startup_information_unittest.cc',
'win/win_util_unittest.cc',
+ 'win/windows_version_unittest.cc',
'win/wrapped_window_proc_unittest.cc',
'<@(trace_event_test_sources)',
],
diff --git a/chromium/base/win/win_util.cc b/chromium/base/win/win_util.cc
index 57bee8a57a7..85612a247dd 100644
--- a/chromium/base/win/win_util.cc
+++ b/chromium/base/win/win_util.cc
@@ -12,13 +12,20 @@
#include <shlobj.h>
#include <shobjidl.h> // Must be before propkey.
#include <initguid.h>
+#include <inspectable.h>
#include <propkey.h>
#include <propvarutil.h>
+#include <psapi.h>
+#include <roapi.h>
#include <sddl.h>
#include <setupapi.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
+#include <uiviewsettingsinterop.h>
+#include <windows.ui.viewmanagement.h>
+#include <winstring.h>
+#include <wrl/wrappers/corewrappers.h>
#include "base/base_switches.h"
#include "base/command_line.h"
@@ -32,6 +39,7 @@
#include "base/threading/thread_restrictions.h"
#include "base/win/registry.h"
#include "base/win/scoped_co_mem.h"
+#include "base/win/scoped_comptr.h"
#include "base/win/scoped_handle.h"
#include "base/win/scoped_propvariant.h"
#include "base/win/windows_version.h"
@@ -106,6 +114,82 @@ POWER_PLATFORM_ROLE GetPlatformRole() {
return PowerDeterminePlatformRoleEx(POWER_PLATFORM_ROLE_V2);
}
+// Uses the Windows 10 WRL API's to query the current system state. The API's
+// we are using in the function below are supported in Win32 apps as per msdn.
+// It looks like the API implementation is buggy at least on Surface 4 causing
+// it to always return UserInteractionMode_Touch which as per documentation
+// indicates tablet mode.
+bool IsWindows10TabletDevice() {
+ if (GetVersion() < VERSION_WIN10)
+ return false;
+
+ using RoGetActivationFactoryFunction = decltype(&RoGetActivationFactory);
+ using WindowsCreateStringFunction = decltype(&WindowsCreateString);
+
+ static RoGetActivationFactoryFunction get_factory = nullptr;
+ static WindowsCreateStringFunction create_string = nullptr;
+
+ if (!get_factory) {
+ DCHECK_EQ(create_string, static_cast<WindowsCreateStringFunction>(
+ nullptr));
+
+ HMODULE combase_dll = ::LoadLibrary(L"combase.dll");
+ if (!combase_dll)
+ return false;
+
+ get_factory = reinterpret_cast<RoGetActivationFactoryFunction>(
+ ::GetProcAddress(combase_dll, "RoGetActivationFactory"));
+ if (!get_factory) {
+ CHECK(false);
+ return false;
+ }
+
+ create_string = reinterpret_cast<WindowsCreateStringFunction>(
+ ::GetProcAddress(combase_dll, "WindowsCreateString"));
+ if (!create_string) {
+ CHECK(false);
+ return false;
+ }
+ }
+
+ HRESULT hr = E_FAIL;
+ // This HSTRING is allocated on the heap and is leaked.
+ static HSTRING view_settings_guid = NULL;
+ if (!view_settings_guid) {
+ hr = create_string(
+ RuntimeClass_Windows_UI_ViewManagement_UIViewSettings,
+ static_cast<UINT32>(
+ wcslen(RuntimeClass_Windows_UI_ViewManagement_UIViewSettings)),
+ &view_settings_guid);
+ if (FAILED(hr))
+ return false;
+ }
+
+ base::win::ScopedComPtr<IUIViewSettingsInterop> view_settings_interop;
+ hr = get_factory(view_settings_guid,
+ __uuidof(IUIViewSettingsInterop),
+ view_settings_interop.ReceiveVoid());
+ if (FAILED(hr))
+ return false;
+
+ base::win::ScopedComPtr<ABI::Windows::UI::ViewManagement::IUIViewSettings>
+ view_settings;
+ // TODO(ananta)
+ // Avoid using GetForegroundWindow here and pass in the HWND of the window
+ // intiating the request to display the keyboard.
+ hr = view_settings_interop->GetForWindow(
+ ::GetForegroundWindow(),
+ __uuidof(ABI::Windows::UI::ViewManagement::IUIViewSettings),
+ view_settings.ReceiveVoid());
+ if (FAILED(hr))
+ return false;
+
+ ABI::Windows::UI::ViewManagement::UserInteractionMode mode =
+ ABI::Windows::UI::ViewManagement::UserInteractionMode_Mouse;
+ view_settings->get_UserInteractionMode(&mode);
+ return mode == ABI::Windows::UI::ViewManagement::UserInteractionMode_Touch;
+}
+
} // namespace
// Returns true if a physical keyboard is detected on Windows 8 and up.
@@ -140,10 +224,11 @@ bool IsKeyboardPresentOnSlate(std::string* reason) {
}
}
+ // If it is a tablet device we assume that there is no keyboard attached.
if (IsTabletDevice(reason)) {
if (reason)
*reason += "Tablet device.\n";
- return true;
+ return false;
} else {
if (reason) {
*reason += "Not a tablet device";
@@ -390,6 +475,9 @@ bool IsTabletDevice(std::string* reason) {
return false;
}
+ if (IsWindows10TabletDevice())
+ return true;
+
if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) {
if (reason) {
*reason += "Device does not support touch.\n";
@@ -413,8 +501,9 @@ bool IsTabletDevice(std::string* reason) {
bool slate_power_profile = (role == PlatformRoleSlate);
bool is_tablet = false;
-
+ bool is_tablet_pc = false;
if (mobile_power_profile || slate_power_profile) {
+ is_tablet_pc = !GetSystemMetrics(SM_TABLETPC);
is_tablet = !GetSystemMetrics(SM_CONVERTIBLESLATEMODE);
if (!is_tablet) {
if (reason) {
@@ -432,7 +521,7 @@ bool IsTabletDevice(std::string* reason) {
if (reason)
*reason += "Device role is not mobile or slate.\n";
}
- return is_tablet;
+ return is_tablet && is_tablet_pc;
}
bool DisplayVirtualKeyboard() {
diff --git a/chromium/base/win/windows_version.cc b/chromium/base/win/windows_version.cc
index 35cdbb3538a..eb3f4993d2c 100644
--- a/chromium/base/win/windows_version.cc
+++ b/chromium/base/win/windows_version.cc
@@ -6,17 +6,80 @@
#include <windows.h>
+#include "base/file_version_info_win.h"
+#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
namespace {
typedef BOOL (WINAPI *GetProductInfoPtr)(DWORD, DWORD, DWORD, DWORD, PDWORD);
-}
+} // namespace
namespace base {
namespace win {
+namespace {
+
+// Helper to map a major.minor.x.build version (e.g. 6.1) to a Windows release.
+Version MajorMinorBuildToVersion(int major, int minor, int build) {
+ if ((major == 5) && (minor > 0)) {
+ // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
+ return (minor == 1) ? VERSION_XP : VERSION_SERVER_2003;
+ } else if (major == 6) {
+ switch (minor) {
+ case 0:
+ // Treat Windows Server 2008 the same as Windows Vista.
+ return VERSION_VISTA;
+ case 1:
+ // Treat Windows Server 2008 R2 the same as Windows 7.
+ return VERSION_WIN7;
+ case 2:
+ // Treat Windows Server 2012 the same as Windows 8.
+ return VERSION_WIN8;
+ default:
+ DCHECK_EQ(minor, 3);
+ return VERSION_WIN8_1;
+ }
+ } else if (major == 10) {
+ if (build < 10586) {
+ return VERSION_WIN10;
+ } else {
+ return VERSION_WIN10_TH2;
+ }
+ } else if (major > 6) {
+ NOTREACHED();
+ return VERSION_WIN_LAST;
+ }
+
+ return VERSION_PRE_XP;
+}
+
+// Retrieve a version from kernel32. This is useful because when running in
+// compatibility mode for a down-level version of the OS, the file version of
+// kernel32 will still be the "real" version.
+Version GetVersionFromKernel32() {
+ scoped_ptr<FileVersionInfoWin> file_version_info(
+ static_cast<FileVersionInfoWin*>(
+ FileVersionInfoWin::CreateFileVersionInfo(
+ base::FilePath(FILE_PATH_LITERAL("kernel32.dll")))));
+ if (file_version_info) {
+ const int major =
+ HIWORD(file_version_info->fixed_file_info()->dwFileVersionMS);
+ const int minor =
+ LOWORD(file_version_info->fixed_file_info()->dwFileVersionMS);
+ const int build =
+ HIWORD(file_version_info->fixed_file_info()->dwFileVersionLS);
+ return MajorMinorBuildToVersion(major, minor, build);
+ }
+
+ NOTREACHED();
+ return VERSION_WIN_LAST;
+}
+
+} // namespace
+
// static
OSInfo* OSInfo::GetInstance() {
// Note: we don't use the Singleton class because it depends on AtExitManager,
@@ -35,6 +98,8 @@ OSInfo* OSInfo::GetInstance() {
OSInfo::OSInfo()
: version_(VERSION_PRE_XP),
+ kernel32_version_(VERSION_PRE_XP),
+ got_kernel32_version_(false),
architecture_(OTHER_ARCHITECTURE),
wow64_status_(GetWOW64StatusForProcess(GetCurrentProcess())) {
OSVERSIONINFOEX version_info = { sizeof version_info };
@@ -42,34 +107,8 @@ OSInfo::OSInfo()
version_number_.major = version_info.dwMajorVersion;
version_number_.minor = version_info.dwMinorVersion;
version_number_.build = version_info.dwBuildNumber;
- if ((version_number_.major == 5) && (version_number_.minor > 0)) {
- // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
- version_ = (version_number_.minor == 1) ? VERSION_XP : VERSION_SERVER_2003;
- } else if (version_number_.major == 6) {
- switch (version_number_.minor) {
- case 0:
- // Treat Windows Server 2008 the same as Windows Vista.
- version_ = VERSION_VISTA;
- break;
- case 1:
- // Treat Windows Server 2008 R2 the same as Windows 7.
- version_ = VERSION_WIN7;
- break;
- case 2:
- // Treat Windows Server 2012 the same as Windows 8.
- version_ = VERSION_WIN8;
- break;
- default:
- DCHECK_EQ(version_number_.minor, 3);
- version_ = VERSION_WIN8_1;
- break;
- }
- } else if (version_number_.major == 10) {
- version_ = VERSION_WIN10;
- } else if (version_number_.major > 6) {
- NOTREACHED();
- version_ = VERSION_WIN_LAST;
- }
+ version_ = MajorMinorBuildToVersion(
+ version_number_.major, version_number_.minor, version_number_.build);
service_pack_.major = version_info.wServicePackMajor;
service_pack_.minor = version_info.wServicePackMinor;
@@ -145,6 +184,14 @@ OSInfo::OSInfo()
OSInfo::~OSInfo() {
}
+Version OSInfo::Kernel32Version() const {
+ if (!got_kernel32_version_) {
+ kernel32_version_ = GetVersionFromKernel32();
+ got_kernel32_version_ = true;
+ }
+ return kernel32_version_;
+}
+
std::string OSInfo::processor_model_name() {
if (processor_model_name_.empty()) {
const wchar_t kProcessorNameString[] =
diff --git a/chromium/base/win/windows_version.h b/chromium/base/win/windows_version.h
index c9bbd4f3eb7..7bc8b6fe560 100644
--- a/chromium/base/win/windows_version.h
+++ b/chromium/base/win/windows_version.h
@@ -21,16 +21,20 @@ namespace win {
// syntactic sugar reasons; see the declaration of GetVersion() below.
// NOTE: Keep these in order so callers can do things like
// "if (base::win::GetVersion() >= base::win::VERSION_VISTA) ...".
+//
+// This enum is used in metrics histograms, so they shouldn't be reordered or
+// removed. New values can be added before VERSION_WIN_LAST.
enum Version {
VERSION_PRE_XP = 0, // Not supported.
- VERSION_XP,
- VERSION_SERVER_2003, // Also includes XP Pro x64 and Server 2003 R2.
- VERSION_VISTA, // Also includes Windows Server 2008.
- VERSION_WIN7, // Also includes Windows Server 2008 R2.
- VERSION_WIN8, // Also includes Windows Server 2012.
- VERSION_WIN8_1, // Also includes Windows Server 2012 R2.
- VERSION_WIN10, // Also includes Windows 10 Server.
- VERSION_WIN_LAST, // Indicates error condition.
+ VERSION_XP = 1,
+ VERSION_SERVER_2003 = 2, // Also includes XP Pro x64 and Server 2003 R2.
+ VERSION_VISTA = 3, // Also includes Windows Server 2008.
+ VERSION_WIN7 = 4, // Also includes Windows Server 2008 R2.
+ VERSION_WIN8 = 5, // Also includes Windows Server 2012.
+ VERSION_WIN8_1 = 6, // Also includes Windows Server 2012 R2.
+ VERSION_WIN10 = 7, // Also includes Windows 10 Server.
+ VERSION_WIN10_TH2 = 8, // Threshold 2: Version 1511, Build 10586.
+ VERSION_WIN_LAST, // Indicates error condition.
};
// A rough bucketing of the available types of versions of Windows. This is used
@@ -85,6 +89,7 @@ class BASE_EXPORT OSInfo {
static OSInfo* GetInstance();
Version version() const { return version_; }
+ Version Kernel32Version() const;
// The next two functions return arrays of values, [major, minor(, build)].
VersionNumber version_number() const { return version_number_; }
VersionType version_type() const { return version_type_; }
@@ -104,6 +109,8 @@ class BASE_EXPORT OSInfo {
~OSInfo();
Version version_;
+ mutable Version kernel32_version_;
+ mutable bool got_kernel32_version_;
VersionNumber version_number_;
VersionType version_type_;
ServicePack service_pack_;
diff --git a/chromium/base/win/windows_version_unittest.cc b/chromium/base/win/windows_version_unittest.cc
new file mode 100644
index 00000000000..f0d6d9660d7
--- /dev/null
+++ b/chromium/base/win/windows_version_unittest.cc
@@ -0,0 +1,22 @@
+// Copyright 2016 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/windows_version.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace win {
+namespace {
+
+TEST(WindowsVersion, GetVersionExAndKernelVersionMatch) {
+ // If this fails, we're running in compatibility mode, or need to update the
+ // application manifest.
+ EXPECT_EQ(OSInfo::GetInstance()->version(),
+ OSInfo::GetInstance()->Kernel32Version());
+}
+
+} // namespace
+} // namespace win
+} // namespace base