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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 bool IsKeyboardPresentOnSlate() { | 63 bool IsKeyboardPresentOnSlate() { |
64 // This function is only supported for Windows 8 and up. | 64 // This function is only supported for Windows 8 and up. |
65 DCHECK(base::win::GetVersion() >= base::win::VERSION_WIN8); | 65 DCHECK(base::win::GetVersion() >= base::win::VERSION_WIN8); |
66 | 66 |
67 // This function should be only invoked for machines with touch screens. | 67 // This function should be only invoked for machines with touch screens. |
68 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) | 68 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) |
69 != NID_INTEGRATED_TOUCH) { | 69 != NID_INTEGRATED_TOUCH) { |
70 return true; | 70 return true; |
71 } | 71 } |
72 | 72 |
| 73 // If the device is docked, the user is treating the device as a PC. |
| 74 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) |
| 75 return true; |
| 76 |
| 77 // To determine whether a keyboard is present on the device, we do the |
| 78 // following:- |
| 79 // 1. Check whether the device supports auto rotation. If it does then |
| 80 // it possibly supports flipping from laptop to slate mode. If it |
| 81 // does not support auto rotation, then we assume it is a desktop |
| 82 // or a normal laptop and assume that there is a keyboard. |
| 83 |
| 84 // 2. If the device supports auto rotation, then we get its platform role |
| 85 // and check the system metric SM_CONVERTIBLESLATEMODE to see if it is |
| 86 // being used in slate mode. If yes then we return false here to ensure |
| 87 // that the OSK is displayed. |
| 88 |
| 89 // 3. If step 1 and 2 fail then we check attached keyboards and return true |
| 90 // if we find ACPI\* or HID\VID* keyboards. |
| 91 |
| 92 typedef BOOL (WINAPI* GetAutoRotationState)(PAR_STATE state); |
| 93 |
| 94 GetAutoRotationState get_rotation_state = |
| 95 reinterpret_cast<GetAutoRotationState>(::GetProcAddress( |
| 96 GetModuleHandle(L"user32.dll"), "GetAutoRotationState")); |
| 97 |
| 98 if (get_rotation_state) { |
| 99 AR_STATE auto_rotation_state = AR_ENABLED; |
| 100 get_rotation_state(&auto_rotation_state); |
| 101 if ((auto_rotation_state & AR_NOSENSOR) || |
| 102 (auto_rotation_state & AR_NOT_SUPPORTED)) { |
| 103 // If there is no auto rotation sensor or rotation is not supported in |
| 104 // the current configuration, then we can assume that this is a desktop |
| 105 // or a traditional laptop. |
| 106 return true; |
| 107 } |
| 108 } |
| 109 |
| 110 // Check if the device is being used as a laptop or a tablet. This can be |
| 111 // checked by first checking the role of the device and then the |
| 112 // corresponding system metric (SM_CONVERTIBLESLATEMODE). If it is being used |
| 113 // as a tablet then we want the OSK to show up. |
| 114 POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); |
| 115 |
| 116 if (((role == PlatformRoleMobile) || (role == PlatformRoleSlate)) && |
| 117 (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0)) |
| 118 return false; |
| 119 |
73 const GUID KEYBOARD_CLASS_GUID = | 120 const GUID KEYBOARD_CLASS_GUID = |
74 { 0x4D36E96B, 0xE325, 0x11CE, | 121 { 0x4D36E96B, 0xE325, 0x11CE, |
75 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; | 122 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; |
76 | 123 |
77 // Query for all the keyboard devices. | 124 // Query for all the keyboard devices. |
78 HDEVINFO device_info = | 125 HDEVINFO device_info = |
79 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); | 126 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); |
80 if (device_info == INVALID_HANDLE_VALUE) | 127 if (device_info == INVALID_HANDLE_VALUE) |
81 return false; | 128 return false; |
82 | 129 |
83 // Enumerate all keyboards and look for ACPI\PNP and HID\VID devices. If | 130 // Enumerate all keyboards and look for ACPI\PNP and HID\VID devices. If |
84 // the count is more than 1 we assume that a keyboard is present. This is | 131 // the count is more than 1 we assume that a keyboard is present. This is |
85 // under the assumption that there will always be one keyboard device. | 132 // under the assumption that there will always be one keyboard device. |
86 int keyboard_count = 0; | 133 int keyboard_count = 0; |
87 for (DWORD i = 0;; ++i) { | 134 for (DWORD i = 0;; ++i) { |
88 SP_DEVINFO_DATA device_info_data = { 0 }; | 135 SP_DEVINFO_DATA device_info_data = { 0 }; |
89 device_info_data.cbSize = sizeof(device_info_data); | 136 device_info_data.cbSize = sizeof(device_info_data); |
90 if (!SetupDiEnumDeviceInfo(device_info, i, &device_info_data)) | 137 if (!SetupDiEnumDeviceInfo(device_info, i, &device_info_data)) |
91 break; | 138 break; |
92 | 139 |
93 // Get the device ID. | 140 // Get the device ID. |
94 wchar_t device_id[MAX_DEVICE_ID_LEN]; | 141 wchar_t device_id[MAX_DEVICE_ID_LEN]; |
95 CONFIGRET status = CM_Get_Device_ID(device_info_data.DevInst, | 142 CONFIGRET status = CM_Get_Device_ID(device_info_data.DevInst, |
96 device_id, | 143 device_id, |
97 MAX_DEVICE_ID_LEN, | 144 MAX_DEVICE_ID_LEN, |
98 0); | 145 0); |
99 if (status == CR_SUCCESS) { | 146 if (status == CR_SUCCESS) { |
100 // To reduce the scope of the hack we only look for PNP, MSF and HID | 147 // To reduce the scope of the hack we only look for ACPI and HID\\VID |
101 // keyboards. | 148 // prefixes in the keyboard device ids. |
102 if (StartsWith(device_id, L"ACPI\\PNP", false) || | 149 if (StartsWith(device_id, L"ACPI", false) || |
103 StartsWith(device_id, L"ACPI\\MSF", false) || | |
104 StartsWith(device_id, L"HID\\VID", false)) { | 150 StartsWith(device_id, L"HID\\VID", false)) { |
105 keyboard_count++; | 151 keyboard_count++; |
106 } | 152 } |
107 } | 153 } |
108 } | 154 } |
109 // The heuristic we are using is to check the count of keyboards and return | 155 // The heuristic we are using is to check the count of keyboards and return |
110 // true if the API's report one or more keyboards. Please note that this | 156 // true if the API's report one or more keyboards. Please note that this |
111 // will break for non keyboard devices which expose a keyboard PDO. | 157 // will break for non keyboard devices which expose a keyboard PDO. |
112 return keyboard_count >= 1; | 158 return keyboard_count >= 1; |
113 } | 159 } |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 // deployed. | 487 // deployed. |
442 if (os_info->version() == base::win::VERSION_SERVER_2003) | 488 if (os_info->version() == base::win::VERSION_SERVER_2003) |
443 return false; | 489 return false; |
444 | 490 |
445 DCHECK(os_info->version() >= base::win::VERSION_VISTA); | 491 DCHECK(os_info->version() >= base::win::VERSION_VISTA); |
446 return true; // New enough to have SHA-256 support. | 492 return true; // New enough to have SHA-256 support. |
447 } | 493 } |
448 | 494 |
449 } // namespace win | 495 } // namespace win |
450 } // namespace base | 496 } // namespace base |
OLD | NEW |