Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/win/win_util.h" | 5 #include "base/win/win_util.h" |
| 6 | 6 |
| 7 #include <aclapi.h> | 7 #include <aclapi.h> |
| 8 #include <cfgmgr32.h> | 8 #include <cfgmgr32.h> |
| 9 #include <lm.h> | 9 #include <lm.h> |
| 10 #include <powrprof.h> | 10 #include <powrprof.h> |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 | 92 |
| 93 const bool value_; | 93 const bool value_; |
| 94 | 94 |
| 95 DISALLOW_COPY_AND_ASSIGN(LazyIsUser32AndGdi32Available); | 95 DISALLOW_COPY_AND_ASSIGN(LazyIsUser32AndGdi32Available); |
| 96 }; | 96 }; |
| 97 | 97 |
| 98 const wchar_t kWindows8OSKRegPath[] = | 98 const wchar_t kWindows8OSKRegPath[] = |
| 99 L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" | 99 L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" |
| 100 L"\\LocalServer32"; | 100 L"\\LocalServer32"; |
| 101 | 101 |
| 102 // Returns the current platform role. We use the PowerDeterminePlatformRoleEx | |
| 103 // API for that. | |
| 104 POWER_PLATFORM_ROLE GetPlatformRole() { | |
| 105 HMODULE power_prof_module = ::GetModuleHandle(L"powrprof.dll"); | |
|
jschuh
2016/01/07 01:18:40
Skip the dynamic loads and just do a version check
ananta
2016/01/07 22:41:05
Done.
| |
| 106 if (!power_prof_module) | |
| 107 power_prof_module = ::LoadLibrary(L"powrprof.dll"); | |
| 108 | |
| 109 DCHECK(power_prof_module); | |
| 110 if (!power_prof_module) | |
| 111 return PlatformRoleDesktop; | |
| 112 | |
| 113 typedef POWER_PLATFORM_ROLE (WINAPI* DeterminePlatformRoleEx)( | |
| 114 unsigned long version); | |
| 115 DeterminePlatformRoleEx determine_platform_role_ex = | |
| 116 reinterpret_cast<DeterminePlatformRoleEx>(::GetProcAddress( | |
| 117 power_prof_module, "PowerDeterminePlatformRoleEx")); | |
| 118 | |
| 119 DCHECK(determine_platform_role_ex); | |
| 120 | |
| 121 return determine_platform_role_ex ? | |
| 122 determine_platform_role_ex(POWER_PLATFORM_ROLE_V2) : PlatformRoleDesktop; | |
| 123 } | |
| 124 | |
| 102 } // namespace | 125 } // namespace |
| 103 | 126 |
| 104 // Returns true if a physical keyboard is detected on Windows 8 and up. | 127 // Returns true if a physical keyboard is detected on Windows 8 and up. |
| 105 // Uses the Setup APIs to enumerate the attached keyboards and returns true | 128 // Uses the Setup APIs to enumerate the attached keyboards and returns true |
| 106 // if the keyboard count is 1 or more.. While this will work in most cases | 129 // if the keyboard count is 1 or more.. While this will work in most cases |
| 107 // it won't work if there are devices which expose keyboard interfaces which | 130 // it won't work if there are devices which expose keyboard interfaces which |
| 108 // are attached to the machine. | 131 // are attached to the machine. |
| 109 bool IsKeyboardPresentOnSlate(std::string* reason) { | 132 bool IsKeyboardPresentOnSlate(std::string* reason) { |
| 110 bool result = false; | 133 bool result = false; |
| 111 | 134 |
| 112 if (GetVersion() < VERSION_WIN7) { | 135 DCHECK(GetVersion() >= VERSION_WIN8); |
|
jschuh
2016/01/07 01:18:40
Keep the old code here, because it's called from C
ananta
2016/01/07 22:41:05
Done.
| |
| 113 *reason = "Detection not supported"; | |
| 114 return false; | |
| 115 } | |
| 116 | 136 |
| 117 // This function is only supported for Windows 8 and up. | 137 // This function is only supported for Windows 8 and up. |
| 118 if (CommandLine::ForCurrentProcess()->HasSwitch( | 138 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 119 switches::kDisableUsbKeyboardDetect)) { | 139 switches::kDisableUsbKeyboardDetect)) { |
| 120 if (reason) | 140 if (reason) |
| 121 *reason = "Detection disabled"; | 141 *reason = "Detection disabled"; |
| 122 return false; | 142 return false; |
| 123 } | 143 } |
| 124 | 144 |
| 125 // This function should be only invoked for machines with touch screens. | 145 // This function should be only invoked for machines with touch screens. |
| 126 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) | 146 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) |
| 127 != NID_INTEGRATED_TOUCH) { | 147 != NID_INTEGRATED_TOUCH) { |
| 128 if (reason) { | 148 if (reason) { |
| 129 *reason += "NID_INTEGRATED_TOUCH\n"; | 149 *reason += "NID_INTEGRATED_TOUCH\n"; |
| 130 result = true; | 150 result = true; |
| 131 } else { | 151 } else { |
| 132 return true; | 152 return true; |
| 133 } | 153 } |
| 134 } | 154 } |
| 135 | 155 |
| 136 // If the device is docked, the user is treating the device as a PC. | 156 if (IsTabletDevice(reason)) { |
| 137 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) { | 157 if (reason) |
| 158 *reason += "Tablet device.\n"; | |
| 159 return true; | |
| 160 } else { | |
| 138 if (reason) { | 161 if (reason) { |
| 139 *reason += "SM_SYSTEMDOCKED\n"; | 162 *reason += "Not a tablet device"; |
| 140 result = true; | 163 result = true; |
| 141 } else { | 164 } else { |
| 142 return true; | 165 return true; |
| 143 } | 166 } |
| 144 } | 167 } |
| 145 | 168 |
| 146 // To determine whether a keyboard is present on the device, we do the | 169 // To determine whether a keyboard is present on the device, we do the |
| 147 // following:- | 170 // following:- |
| 148 // 1. Check whether the device supports auto rotation. If it does then | 171 // 1. Check whether the device supports auto rotation. If it does then |
| 149 // it possibly supports flipping from laptop to slate mode. If it | 172 // it possibly supports flipping from laptop to slate mode. If it |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 175 if (reason) { | 198 if (reason) { |
| 176 *reason += (auto_rotation_state & AR_NOSENSOR) ? "AR_NOSENSOR\n" : | 199 *reason += (auto_rotation_state & AR_NOSENSOR) ? "AR_NOSENSOR\n" : |
| 177 "AR_NOT_SUPPORTED\n"; | 200 "AR_NOT_SUPPORTED\n"; |
| 178 result = true; | 201 result = true; |
| 179 } else { | 202 } else { |
| 180 return true; | 203 return true; |
| 181 } | 204 } |
| 182 } | 205 } |
| 183 } | 206 } |
| 184 | 207 |
| 185 // Check if the device is being used as a laptop or a tablet. This can be | |
| 186 // checked by first checking the role of the device and then the | |
| 187 // corresponding system metric (SM_CONVERTIBLESLATEMODE). If it is being used | |
| 188 // as a tablet then we want the OSK to show up. | |
| 189 POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); | |
| 190 | |
| 191 if (((role == PlatformRoleMobile) || (role == PlatformRoleSlate)) && | |
| 192 (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0)) { | |
| 193 if (reason) { | |
| 194 *reason += (role == PlatformRoleMobile) ? "PlatformRoleMobile\n" : | |
| 195 "PlatformRoleSlate\n"; | |
| 196 // Don't change result here if it's already true. | |
| 197 } else { | |
| 198 return false; | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 const GUID KEYBOARD_CLASS_GUID = | 208 const GUID KEYBOARD_CLASS_GUID = |
| 203 { 0x4D36E96B, 0xE325, 0x11CE, | 209 { 0x4D36E96B, 0xE325, 0x11CE, |
| 204 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; | 210 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; |
| 205 | 211 |
| 206 // Query for all the keyboard devices. | 212 // Query for all the keyboard devices. |
| 207 HDEVINFO device_info = | 213 HDEVINFO device_info = |
| 208 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); | 214 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); |
| 209 if (device_info == INVALID_HANDLE_VALUE) { | 215 if (device_info == INVALID_HANDLE_VALUE) { |
| 210 if (reason) | 216 if (reason) |
| 211 *reason += "No keyboard info\n"; | 217 *reason += "No keyboard info\n"; |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 // has the sideffect of clearing our exception filter, which means we | 389 // has the sideffect of clearing our exception filter, which means we |
| 384 // don't get any crash. | 390 // don't get any crash. |
| 385 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); | 391 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); |
| 386 | 392 |
| 387 // Set a SIGABRT handler for good measure. We will crash even if the default | 393 // Set a SIGABRT handler for good measure. We will crash even if the default |
| 388 // is left in place, however this allows us to crash earlier. And it also | 394 // is left in place, however this allows us to crash earlier. And it also |
| 389 // lets us crash in response to code which might directly call raise(SIGABRT) | 395 // lets us crash in response to code which might directly call raise(SIGABRT) |
| 390 signal(SIGABRT, ForceCrashOnSigAbort); | 396 signal(SIGABRT, ForceCrashOnSigAbort); |
| 391 } | 397 } |
| 392 | 398 |
| 393 bool IsTabletDevice() { | 399 bool IsTabletDevice(std::string* reason) { |
| 394 if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) | 400 if (GetVersion() < VERSION_WIN8) { |
| 401 if (reason) | |
| 402 *reason = "Tablet device detection not supported below Windows 8\n"; | |
| 395 return false; | 403 return false; |
| 404 } | |
| 396 | 405 |
| 397 Version version = GetVersion(); | 406 if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) { |
| 398 if (version == VERSION_XP) | 407 if (reason) { |
| 399 return (GetSystemMetrics(SM_TABLETPC) != 0); | 408 *reason += "Device does not support touch.\n"; |
| 409 } else { | |
| 410 return false; | |
| 411 } | |
| 412 } | |
| 400 | 413 |
| 401 // If the device is docked, the user is treating the device as a PC. | 414 // If the device is docked, the user is treating the device as a PC. |
| 402 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) | 415 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) { |
| 403 return false; | 416 if (reason) { |
| 417 *reason += "SM_SYSTEMDOCKED\n"; | |
| 418 } else { | |
| 419 return false; | |
| 420 } | |
| 421 } | |
| 404 | 422 |
| 405 // PlatformRoleSlate was only added in Windows 8, but prior to Win8 it is | 423 // PlatformRoleSlate was added in Windows 8+. |
| 406 // still possible to check for a mobile power profile. | 424 POWER_PLATFORM_ROLE role = GetPlatformRole(); |
| 407 POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); | |
| 408 bool mobile_power_profile = (role == PlatformRoleMobile); | 425 bool mobile_power_profile = (role == PlatformRoleMobile); |
| 409 bool slate_power_profile = false; | 426 bool slate_power_profile = (role == PlatformRoleSlate); |
| 410 if (version >= VERSION_WIN8) | |
| 411 slate_power_profile = (role == PlatformRoleSlate); | |
| 412 | 427 |
| 413 if (mobile_power_profile || slate_power_profile) | 428 bool is_tablet = false; |
| 414 return (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0); | |
| 415 | 429 |
| 416 return false; | 430 if (mobile_power_profile || slate_power_profile) { |
| 431 is_tablet = !GetSystemMetrics(SM_CONVERTIBLESLATEMODE); | |
| 432 if (!is_tablet) { | |
| 433 if (reason) { | |
| 434 *reason += "Not in slate mode.\n"; | |
| 435 } else { | |
| 436 return false; | |
| 437 } | |
| 438 } else { | |
| 439 if (reason) { | |
| 440 *reason += (role == PlatformRoleMobile) ? "PlatformRoleMobile\n" : | |
| 441 "PlatformRoleSlate\n"; | |
| 442 } | |
| 443 } | |
| 444 } else { | |
| 445 if (reason) | |
| 446 *reason += "Device role is not mobile or slate.\n"; | |
| 447 } | |
| 448 return is_tablet; | |
| 417 } | 449 } |
| 418 | 450 |
| 419 bool DisplayVirtualKeyboard() { | 451 bool DisplayVirtualKeyboard() { |
| 420 if (GetVersion() < VERSION_WIN8) | 452 if (GetVersion() < VERSION_WIN8) |
| 421 return false; | 453 return false; |
| 422 | 454 |
| 423 if (IsKeyboardPresentOnSlate(nullptr)) | 455 if (IsKeyboardPresentOnSlate(nullptr)) |
| 424 return false; | 456 return false; |
| 425 | 457 |
| 426 static LazyInstance<string16>::Leaky osk_path = LAZY_INSTANCE_INITIALIZER; | 458 static LazyInstance<string16>::Leaky osk_path = LAZY_INSTANCE_INITIALIZER; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 559 } | 591 } |
| 560 | 592 |
| 561 bool IsUser32AndGdi32Available() { | 593 bool IsUser32AndGdi32Available() { |
| 562 static base::LazyInstance<LazyIsUser32AndGdi32Available>::Leaky available = | 594 static base::LazyInstance<LazyIsUser32AndGdi32Available>::Leaky available = |
| 563 LAZY_INSTANCE_INITIALIZER; | 595 LAZY_INSTANCE_INITIALIZER; |
| 564 return available.Get().value(); | 596 return available.Get().value(); |
| 565 } | 597 } |
| 566 | 598 |
| 567 } // namespace win | 599 } // namespace win |
| 568 } // namespace base | 600 } // namespace base |
| OLD | NEW |