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 |