| 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 return PowerDeterminePlatformRoleEx(POWER_PLATFORM_ROLE_V2); |
| 106 } |
| 107 |
| 102 } // namespace | 108 } // namespace |
| 103 | 109 |
| 104 // Returns true if a physical keyboard is detected on Windows 8 and up. | 110 // 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 | 111 // 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 | 112 // 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 | 113 // it won't work if there are devices which expose keyboard interfaces which |
| 108 // are attached to the machine. | 114 // are attached to the machine. |
| 109 bool IsKeyboardPresentOnSlate(std::string* reason) { | 115 bool IsKeyboardPresentOnSlate(std::string* reason) { |
| 110 bool result = false; | 116 bool result = false; |
| 111 | 117 |
| 112 if (GetVersion() < VERSION_WIN7) { | 118 if (GetVersion() < VERSION_WIN8) { |
| 113 *reason = "Detection not supported"; | 119 *reason = "Detection not supported"; |
| 114 return false; | 120 return false; |
| 115 } | 121 } |
| 116 | 122 |
| 117 // This function is only supported for Windows 8 and up. | 123 // This function is only supported for Windows 8 and up. |
| 118 if (CommandLine::ForCurrentProcess()->HasSwitch( | 124 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 119 switches::kDisableUsbKeyboardDetect)) { | 125 switches::kDisableUsbKeyboardDetect)) { |
| 120 if (reason) | 126 if (reason) |
| 121 *reason = "Detection disabled"; | 127 *reason = "Detection disabled"; |
| 122 return false; | 128 return false; |
| 123 } | 129 } |
| 124 | 130 |
| 125 // This function should be only invoked for machines with touch screens. | 131 // This function should be only invoked for machines with touch screens. |
| 126 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) | 132 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) |
| 127 != NID_INTEGRATED_TOUCH) { | 133 != NID_INTEGRATED_TOUCH) { |
| 128 if (reason) { | 134 if (reason) { |
| 129 *reason += "NID_INTEGRATED_TOUCH\n"; | 135 *reason += "NID_INTEGRATED_TOUCH\n"; |
| 130 result = true; | 136 result = true; |
| 131 } else { | 137 } else { |
| 132 return true; | 138 return true; |
| 133 } | 139 } |
| 134 } | 140 } |
| 135 | 141 |
| 136 // If the device is docked, the user is treating the device as a PC. | 142 if (IsTabletDevice(reason)) { |
| 137 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) { | 143 if (reason) |
| 144 *reason += "Tablet device.\n"; |
| 145 return true; |
| 146 } else { |
| 138 if (reason) { | 147 if (reason) { |
| 139 *reason += "SM_SYSTEMDOCKED\n"; | 148 *reason += "Not a tablet device"; |
| 140 result = true; | 149 result = true; |
| 141 } else { | 150 } else { |
| 142 return true; | 151 return true; |
| 143 } | 152 } |
| 144 } | 153 } |
| 145 | 154 |
| 146 // To determine whether a keyboard is present on the device, we do the | 155 // To determine whether a keyboard is present on the device, we do the |
| 147 // following:- | 156 // following:- |
| 148 // 1. Check whether the device supports auto rotation. If it does then | 157 // 1. Check whether the device supports auto rotation. If it does then |
| 149 // it possibly supports flipping from laptop to slate mode. If it | 158 // it possibly supports flipping from laptop to slate mode. If it |
| (...skipping 25 matching lines...) Expand all Loading... |
| 175 if (reason) { | 184 if (reason) { |
| 176 *reason += (auto_rotation_state & AR_NOSENSOR) ? "AR_NOSENSOR\n" : | 185 *reason += (auto_rotation_state & AR_NOSENSOR) ? "AR_NOSENSOR\n" : |
| 177 "AR_NOT_SUPPORTED\n"; | 186 "AR_NOT_SUPPORTED\n"; |
| 178 result = true; | 187 result = true; |
| 179 } else { | 188 } else { |
| 180 return true; | 189 return true; |
| 181 } | 190 } |
| 182 } | 191 } |
| 183 } | 192 } |
| 184 | 193 |
| 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 = | 194 const GUID KEYBOARD_CLASS_GUID = |
| 203 { 0x4D36E96B, 0xE325, 0x11CE, | 195 { 0x4D36E96B, 0xE325, 0x11CE, |
| 204 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; | 196 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; |
| 205 | 197 |
| 206 // Query for all the keyboard devices. | 198 // Query for all the keyboard devices. |
| 207 HDEVINFO device_info = | 199 HDEVINFO device_info = |
| 208 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); | 200 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); |
| 209 if (device_info == INVALID_HANDLE_VALUE) { | 201 if (device_info == INVALID_HANDLE_VALUE) { |
| 210 if (reason) | 202 if (reason) |
| 211 *reason += "No keyboard info\n"; | 203 *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 | 375 // has the sideffect of clearing our exception filter, which means we |
| 384 // don't get any crash. | 376 // don't get any crash. |
| 385 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); | 377 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); |
| 386 | 378 |
| 387 // Set a SIGABRT handler for good measure. We will crash even if the default | 379 // 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 | 380 // 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) | 381 // lets us crash in response to code which might directly call raise(SIGABRT) |
| 390 signal(SIGABRT, ForceCrashOnSigAbort); | 382 signal(SIGABRT, ForceCrashOnSigAbort); |
| 391 } | 383 } |
| 392 | 384 |
| 393 bool IsTabletDevice() { | 385 bool IsTabletDevice(std::string* reason) { |
| 394 if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) | 386 if (GetVersion() < VERSION_WIN8) { |
| 387 if (reason) |
| 388 *reason = "Tablet device detection not supported below Windows 8\n"; |
| 395 return false; | 389 return false; |
| 390 } |
| 396 | 391 |
| 397 Version version = GetVersion(); | 392 if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) { |
| 398 if (version == VERSION_XP) | 393 if (reason) { |
| 399 return (GetSystemMetrics(SM_TABLETPC) != 0); | 394 *reason += "Device does not support touch.\n"; |
| 395 } else { |
| 396 return false; |
| 397 } |
| 398 } |
| 400 | 399 |
| 401 // If the device is docked, the user is treating the device as a PC. | 400 // If the device is docked, the user is treating the device as a PC. |
| 402 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) | 401 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) { |
| 403 return false; | 402 if (reason) { |
| 403 *reason += "SM_SYSTEMDOCKED\n"; |
| 404 } else { |
| 405 return false; |
| 406 } |
| 407 } |
| 404 | 408 |
| 405 // PlatformRoleSlate was only added in Windows 8, but prior to Win8 it is | 409 // PlatformRoleSlate was added in Windows 8+. |
| 406 // still possible to check for a mobile power profile. | 410 POWER_PLATFORM_ROLE role = GetPlatformRole(); |
| 407 POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); | |
| 408 bool mobile_power_profile = (role == PlatformRoleMobile); | 411 bool mobile_power_profile = (role == PlatformRoleMobile); |
| 409 bool slate_power_profile = false; | 412 bool slate_power_profile = (role == PlatformRoleSlate); |
| 410 if (version >= VERSION_WIN8) | |
| 411 slate_power_profile = (role == PlatformRoleSlate); | |
| 412 | 413 |
| 413 if (mobile_power_profile || slate_power_profile) | 414 bool is_tablet = false; |
| 414 return (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0); | |
| 415 | 415 |
| 416 return false; | 416 if (mobile_power_profile || slate_power_profile) { |
| 417 is_tablet = !GetSystemMetrics(SM_CONVERTIBLESLATEMODE); |
| 418 if (!is_tablet) { |
| 419 if (reason) { |
| 420 *reason += "Not in slate mode.\n"; |
| 421 } else { |
| 422 return false; |
| 423 } |
| 424 } else { |
| 425 if (reason) { |
| 426 *reason += (role == PlatformRoleMobile) ? "PlatformRoleMobile\n" : |
| 427 "PlatformRoleSlate\n"; |
| 428 } |
| 429 } |
| 430 } else { |
| 431 if (reason) |
| 432 *reason += "Device role is not mobile or slate.\n"; |
| 433 } |
| 434 return is_tablet; |
| 417 } | 435 } |
| 418 | 436 |
| 419 bool DisplayVirtualKeyboard() { | 437 bool DisplayVirtualKeyboard() { |
| 420 if (GetVersion() < VERSION_WIN8) | 438 if (GetVersion() < VERSION_WIN8) |
| 421 return false; | 439 return false; |
| 422 | 440 |
| 423 if (IsKeyboardPresentOnSlate(nullptr)) | 441 if (IsKeyboardPresentOnSlate(nullptr)) |
| 424 return false; | 442 return false; |
| 425 | 443 |
| 426 static LazyInstance<string16>::Leaky osk_path = LAZY_INSTANCE_INITIALIZER; | 444 static LazyInstance<string16>::Leaky osk_path = LAZY_INSTANCE_INITIALIZER; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 } | 577 } |
| 560 | 578 |
| 561 bool IsUser32AndGdi32Available() { | 579 bool IsUser32AndGdi32Available() { |
| 562 static base::LazyInstance<LazyIsUser32AndGdi32Available>::Leaky available = | 580 static base::LazyInstance<LazyIsUser32AndGdi32Available>::Leaky available = |
| 563 LAZY_INSTANCE_INITIALIZER; | 581 LAZY_INSTANCE_INITIALIZER; |
| 564 return available.Get().value(); | 582 return available.Get().value(); |
| 565 } | 583 } |
| 566 | 584 |
| 567 } // namespace win | 585 } // namespace win |
| 568 } // namespace base | 586 } // namespace base |
| OLD | NEW |