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 |