| 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 "content/browser/accessibility/browser_accessibility_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_win.h" |
| 6 | 6 |
| 7 #include <UIAutomationClient.h> | 7 #include <UIAutomationClient.h> |
| 8 #include <UIAutomationCoreApi.h> | 8 #include <UIAutomationCoreApi.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 UMA_API_UNSELECT_ROW = 157, | 196 UMA_API_UNSELECT_ROW = 157, |
| 197 | 197 |
| 198 // This must always be the last enum. It's okay for its value to | 198 // This must always be the last enum. It's okay for its value to |
| 199 // increase, but none of the other enum values may change. | 199 // increase, but none of the other enum values may change. |
| 200 UMA_API_MAX | 200 UMA_API_MAX |
| 201 }; | 201 }; |
| 202 | 202 |
| 203 #define WIN_ACCESSIBILITY_API_HISTOGRAM(enum_value) \ | 203 #define WIN_ACCESSIBILITY_API_HISTOGRAM(enum_value) \ |
| 204 UMA_HISTOGRAM_ENUMERATION("Accessibility.WinAPIs", enum_value, UMA_API_MAX) | 204 UMA_HISTOGRAM_ENUMERATION("Accessibility.WinAPIs", enum_value, UMA_API_MAX) |
| 205 | 205 |
| 206 const WCHAR *const IA2_RELATION_DETAILS = L"details"; |
| 207 const WCHAR *const IA2_RELATION_DETAILS_FOR = L"detailsFor"; |
| 208 const WCHAR *const IA2_RELATION_ERROR_MESSAGE = L"errorMessage"; |
| 209 |
| 206 } // namespace | 210 } // namespace |
| 207 | 211 |
| 208 namespace content { | 212 namespace content { |
| 209 | 213 |
| 210 // These nonstandard GUIDs are taken directly from the Mozilla sources | 214 // These nonstandard GUIDs are taken directly from the Mozilla sources |
| 211 // (accessible/src/msaa/nsAccessNodeWrap.cpp); some documentation is here: | 215 // (accessible/src/msaa/nsAccessNodeWrap.cpp); some documentation is here: |
| 212 // http://developer.mozilla.org/en/Accessibility/AT-APIs/ImplementationFeatures/
MSAA | 216 // http://developer.mozilla.org/en/Accessibility/AT-APIs/ImplementationFeatures/
MSAA |
| 213 const GUID GUID_ISimpleDOM = {0x0c539790, | 217 const GUID GUID_ISimpleDOM = {0x0c539790, |
| 214 0x12e4, | 218 0x12e4, |
| 215 0x11cf, | 219 0x11cf, |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 if (!instance_active()) | 652 if (!instance_active()) |
| 649 return E_FAIL; | 653 return E_FAIL; |
| 650 | 654 |
| 651 if (!acc_key) | 655 if (!acc_key) |
| 652 return E_INVALIDARG; | 656 return E_INVALIDARG; |
| 653 | 657 |
| 654 BrowserAccessibilityWin* target = GetTargetFromChildID(var_id); | 658 BrowserAccessibilityWin* target = GetTargetFromChildID(var_id); |
| 655 if (!target) | 659 if (!target) |
| 656 return E_INVALIDARG; | 660 return E_INVALIDARG; |
| 657 | 661 |
| 662 if (target->HasStringAttribute(ui::AX_ATTR_KEY_SHORTCUTS)) { |
| 663 return target->GetStringAttributeAsBstr( |
| 664 ui::AX_ATTR_KEY_SHORTCUTS, acc_key); |
| 665 } |
| 666 |
| 658 return target->GetStringAttributeAsBstr( | 667 return target->GetStringAttributeAsBstr( |
| 659 ui::AX_ATTR_SHORTCUT, acc_key); | 668 ui::AX_ATTR_SHORTCUT, acc_key); |
| 660 } | 669 } |
| 661 | 670 |
| 662 STDMETHODIMP BrowserAccessibilityWin::get_accName(VARIANT var_id, BSTR* name) { | 671 STDMETHODIMP BrowserAccessibilityWin::get_accName(VARIANT var_id, BSTR* name) { |
| 663 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_NAME); | 672 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_NAME); |
| 664 if (!instance_active()) | 673 if (!instance_active()) |
| 665 return E_FAIL; | 674 return E_FAIL; |
| 666 | 675 |
| 667 if (!name) | 676 if (!name) |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1115 | 1124 |
| 1116 *group_level = GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL); | 1125 *group_level = GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL); |
| 1117 *similar_items_in_group = GetIntAttribute(ui::AX_ATTR_SET_SIZE); | 1126 *similar_items_in_group = GetIntAttribute(ui::AX_ATTR_SET_SIZE); |
| 1118 *position_in_group = GetIntAttribute(ui::AX_ATTR_POS_IN_SET); | 1127 *position_in_group = GetIntAttribute(ui::AX_ATTR_POS_IN_SET); |
| 1119 | 1128 |
| 1120 if (*group_level == *similar_items_in_group == *position_in_group == 0) | 1129 if (*group_level == *similar_items_in_group == *position_in_group == 0) |
| 1121 return S_FALSE; | 1130 return S_FALSE; |
| 1122 return S_OK; | 1131 return S_OK; |
| 1123 } | 1132 } |
| 1124 | 1133 |
| 1134 STDMETHODIMP |
| 1135 BrowserAccessibilityWin::get_localizedExtendedRole( |
| 1136 BSTR* localized_extended_role) { |
| 1137 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_LOCALIZED_EXTENDED_ROLE); |
| 1138 AddAccessibilityModeFlags(ACCESSIBILITY_MODE_FLAG_SCREEN_READER); |
| 1139 |
| 1140 if (!instance_active()) |
| 1141 return E_FAIL; |
| 1142 |
| 1143 if (!localized_extended_role) |
| 1144 return E_INVALIDARG; |
| 1145 |
| 1146 return GetStringAttributeAsBstr( |
| 1147 ui::AX_ATTR_ROLE_DESCRIPTION, localized_extended_role); |
| 1148 } |
| 1149 |
| 1125 // | 1150 // |
| 1126 // IAccessibleEx methods not implemented. | 1151 // IAccessible2 methods not implemented. |
| 1127 // | 1152 // |
| 1128 | 1153 |
| 1129 STDMETHODIMP BrowserAccessibilityWin::get_extendedRole(BSTR* extended_role) { | 1154 STDMETHODIMP BrowserAccessibilityWin::get_extendedRole(BSTR* extended_role) { |
| 1130 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_EXTENDED_ROLE); | 1155 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_EXTENDED_ROLE); |
| 1131 AddAccessibilityModeFlags(ACCESSIBILITY_MODE_FLAG_SCREEN_READER); | 1156 AddAccessibilityModeFlags(ACCESSIBILITY_MODE_FLAG_SCREEN_READER); |
| 1132 return E_NOTIMPL; | 1157 return E_NOTIMPL; |
| 1133 } | 1158 } |
| 1134 STDMETHODIMP | 1159 STDMETHODIMP |
| 1135 BrowserAccessibilityWin::get_localizedExtendedRole( | |
| 1136 BSTR* localized_extended_role) { | |
| 1137 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_LOCALIZED_EXTENDED_ROLE); | |
| 1138 AddAccessibilityModeFlags(ACCESSIBILITY_MODE_FLAG_SCREEN_READER); | |
| 1139 return E_NOTIMPL; | |
| 1140 } | |
| 1141 STDMETHODIMP | |
| 1142 BrowserAccessibilityWin::get_nExtendedStates(LONG* n_extended_states) { | 1160 BrowserAccessibilityWin::get_nExtendedStates(LONG* n_extended_states) { |
| 1143 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_EXTENDED_STATES); | 1161 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_N_EXTENDED_STATES); |
| 1144 AddAccessibilityModeFlags(ACCESSIBILITY_MODE_FLAG_SCREEN_READER); | 1162 AddAccessibilityModeFlags(ACCESSIBILITY_MODE_FLAG_SCREEN_READER); |
| 1145 return E_NOTIMPL; | 1163 return E_NOTIMPL; |
| 1146 } | 1164 } |
| 1147 STDMETHODIMP | 1165 STDMETHODIMP |
| 1148 BrowserAccessibilityWin::get_extendedStates(LONG max_extended_states, | 1166 BrowserAccessibilityWin::get_extendedStates(LONG max_extended_states, |
| 1149 BSTR** extended_states, | 1167 BSTR** extended_states, |
| 1150 LONG* n_extended_states) { | 1168 LONG* n_extended_states) { |
| 1151 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_EXTENDED_STATES); | 1169 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_EXTENDED_STATES); |
| (...skipping 2713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3865 // Swap win_attributes_ to old_win_attributes_, allowing us to see | 3883 // Swap win_attributes_ to old_win_attributes_, allowing us to see |
| 3866 // exactly what changed and fire appropriate events. Note that | 3884 // exactly what changed and fire appropriate events. Note that |
| 3867 // old_win_attributes_ is cleared at the end of UpdateStep3FireEvents. | 3885 // old_win_attributes_ is cleared at the end of UpdateStep3FireEvents. |
| 3868 old_win_attributes_.swap(win_attributes_); | 3886 old_win_attributes_.swap(win_attributes_); |
| 3869 win_attributes_.reset(new WinAttributes()); | 3887 win_attributes_.reset(new WinAttributes()); |
| 3870 | 3888 |
| 3871 InitRoleAndState(); | 3889 InitRoleAndState(); |
| 3872 | 3890 |
| 3873 win_attributes_->ia2_attributes.clear(); | 3891 win_attributes_->ia2_attributes.clear(); |
| 3874 | 3892 |
| 3875 // Expose autocomplete attribute for combobox and textbox. | 3893 // Expose some HTLM and ARIA attributes in the IAccessible2 attributes string. |
| 3876 StringAttributeToIA2(ui::AX_ATTR_AUTO_COMPLETE, "autocomplete"); | 3894 // "display", "tag", and "xml-roles" have somewhat unusual names for |
| 3877 | 3895 // historical reasons. Aside from that virtually every ARIA attribute |
| 3878 // Expose the "display" and "tag" attributes. | 3896 // is exposed in a really straightforward way, i.e. "aria-foo" is exposed |
| 3897 // as "foo". |
| 3879 StringAttributeToIA2(ui::AX_ATTR_DISPLAY, "display"); | 3898 StringAttributeToIA2(ui::AX_ATTR_DISPLAY, "display"); |
| 3880 StringAttributeToIA2(ui::AX_ATTR_HTML_TAG, "tag"); | 3899 StringAttributeToIA2(ui::AX_ATTR_HTML_TAG, "tag"); |
| 3881 StringAttributeToIA2(ui::AX_ATTR_ROLE, "xml-roles"); | 3900 StringAttributeToIA2(ui::AX_ATTR_ROLE, "xml-roles"); |
| 3882 | 3901 |
| 3902 StringAttributeToIA2(ui::AX_ATTR_AUTO_COMPLETE, "autocomplete"); |
| 3903 StringAttributeToIA2(ui::AX_ATTR_ROLE_DESCRIPTION, "roledescription"); |
| 3904 StringAttributeToIA2(ui::AX_ATTR_KEY_SHORTCUTS, "keyshortcuts"); |
| 3905 |
| 3883 IntAttributeToIA2(ui::AX_ATTR_HIERARCHICAL_LEVEL, "level"); | 3906 IntAttributeToIA2(ui::AX_ATTR_HIERARCHICAL_LEVEL, "level"); |
| 3884 IntAttributeToIA2(ui::AX_ATTR_SET_SIZE, "setsize"); | 3907 IntAttributeToIA2(ui::AX_ATTR_SET_SIZE, "setsize"); |
| 3885 IntAttributeToIA2(ui::AX_ATTR_POS_IN_SET, "posinset"); | 3908 IntAttributeToIA2(ui::AX_ATTR_POS_IN_SET, "posinset"); |
| 3886 | 3909 |
| 3887 if (ia_role() == ROLE_SYSTEM_CHECKBUTTON || | 3910 if (ia_role() == ROLE_SYSTEM_CHECKBUTTON || |
| 3888 ia_role() == ROLE_SYSTEM_RADIOBUTTON || | 3911 ia_role() == ROLE_SYSTEM_RADIOBUTTON || |
| 3889 ia2_role() == IA2_ROLE_CHECK_MENU_ITEM || | 3912 ia2_role() == IA2_ROLE_CHECK_MENU_ITEM || |
| 3890 ia2_role() == IA2_ROLE_RADIO_MENU_ITEM || | 3913 ia2_role() == IA2_ROLE_RADIO_MENU_ITEM || |
| 3891 ia2_role() == IA2_ROLE_TOGGLE_BUTTON) { | 3914 ia2_role() == IA2_ROLE_TOGGLE_BUTTON) { |
| 3892 win_attributes_->ia2_attributes.push_back(L"checkable:true"); | 3915 win_attributes_->ia2_attributes.push_back(L"checkable:true"); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4018 AddBidirectionalRelations(IA2_RELATION_CONTROLLER_FOR, | 4041 AddBidirectionalRelations(IA2_RELATION_CONTROLLER_FOR, |
| 4019 IA2_RELATION_CONTROLLED_BY, | 4042 IA2_RELATION_CONTROLLED_BY, |
| 4020 ui::AX_ATTR_CONTROLS_IDS); | 4043 ui::AX_ATTR_CONTROLS_IDS); |
| 4021 AddBidirectionalRelations(IA2_RELATION_DESCRIBED_BY, | 4044 AddBidirectionalRelations(IA2_RELATION_DESCRIBED_BY, |
| 4022 IA2_RELATION_DESCRIPTION_FOR, | 4045 IA2_RELATION_DESCRIPTION_FOR, |
| 4023 ui::AX_ATTR_DESCRIBEDBY_IDS); | 4046 ui::AX_ATTR_DESCRIBEDBY_IDS); |
| 4024 AddBidirectionalRelations(IA2_RELATION_FLOWS_TO, IA2_RELATION_FLOWS_FROM, | 4047 AddBidirectionalRelations(IA2_RELATION_FLOWS_TO, IA2_RELATION_FLOWS_FROM, |
| 4025 ui::AX_ATTR_FLOWTO_IDS); | 4048 ui::AX_ATTR_FLOWTO_IDS); |
| 4026 AddBidirectionalRelations(IA2_RELATION_LABELLED_BY, IA2_RELATION_LABEL_FOR, | 4049 AddBidirectionalRelations(IA2_RELATION_LABELLED_BY, IA2_RELATION_LABEL_FOR, |
| 4027 ui::AX_ATTR_LABELLEDBY_IDS); | 4050 ui::AX_ATTR_LABELLEDBY_IDS); |
| 4051 AddBidirectionalRelations(IA2_RELATION_DETAILS, IA2_RELATION_DETAILS_FOR, |
| 4052 ui::AX_ATTR_DETAILS_IDS); |
| 4028 | 4053 |
| 4029 int member_of_id; | 4054 int member_of_id; |
| 4030 if (GetIntAttribute(ui::AX_ATTR_MEMBER_OF_ID, &member_of_id)) | 4055 if (GetIntAttribute(ui::AX_ATTR_MEMBER_OF_ID, &member_of_id)) |
| 4031 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); | 4056 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); |
| 4032 | 4057 |
| 4058 int error_message_id; |
| 4059 if (GetIntAttribute(ui::AX_ATTR_ERRORMESSAGE_ID, &error_message_id)) |
| 4060 AddRelation(IA2_RELATION_ERROR_MESSAGE, error_message_id); |
| 4061 |
| 4033 // Expose slider value. | 4062 // Expose slider value. |
| 4034 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || | 4063 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || |
| 4035 ia_role() == ROLE_SYSTEM_SCROLLBAR || | 4064 ia_role() == ROLE_SYSTEM_SCROLLBAR || |
| 4036 ia_role() == ROLE_SYSTEM_SLIDER) { | 4065 ia_role() == ROLE_SYSTEM_SLIDER) { |
| 4037 base::string16 value_text = GetValueText(); | 4066 base::string16 value_text = GetValueText(); |
| 4038 SanitizeStringAttributeForIA2(value_text, &value_text); | 4067 SanitizeStringAttributeForIA2(value_text, &value_text); |
| 4039 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); | 4068 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); |
| 4040 } | 4069 } |
| 4041 | 4070 |
| 4042 UpdateRequiredAttributes(); | 4071 UpdateRequiredAttributes(); |
| (...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5198 | 5227 |
| 5199 if (GetBoolAttribute(ui::AX_ATTR_STATE_MIXED)) | 5228 if (GetBoolAttribute(ui::AX_ATTR_STATE_MIXED)) |
| 5200 ia_state |= STATE_SYSTEM_MIXED; | 5229 ia_state |= STATE_SYSTEM_MIXED; |
| 5201 | 5230 |
| 5202 if (GetBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE)) | 5231 if (GetBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE)) |
| 5203 ia2_state |= IA2_STATE_EDITABLE; | 5232 ia2_state |= IA2_STATE_EDITABLE; |
| 5204 | 5233 |
| 5205 if (!GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) | 5234 if (!GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) |
| 5206 ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; | 5235 ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; |
| 5207 | 5236 |
| 5237 if (GetBoolAttribute(ui::AX_ATTR_MODAL)) |
| 5238 ia2_state |= IA2_STATE_MODAL; |
| 5239 |
| 5208 base::string16 html_tag = GetString16Attribute( | 5240 base::string16 html_tag = GetString16Attribute( |
| 5209 ui::AX_ATTR_HTML_TAG); | 5241 ui::AX_ATTR_HTML_TAG); |
| 5210 switch (GetRole()) { | 5242 switch (GetRole()) { |
| 5211 case ui::AX_ROLE_ALERT: | 5243 case ui::AX_ROLE_ALERT: |
| 5212 ia_role = ROLE_SYSTEM_ALERT; | 5244 ia_role = ROLE_SYSTEM_ALERT; |
| 5213 break; | 5245 break; |
| 5214 case ui::AX_ROLE_ALERT_DIALOG: | 5246 case ui::AX_ROLE_ALERT_DIALOG: |
| 5215 ia_role = ROLE_SYSTEM_DIALOG; | 5247 ia_role = ROLE_SYSTEM_DIALOG; |
| 5216 break; | 5248 break; |
| 5217 case ui::AX_ROLE_APPLICATION: | 5249 case ui::AX_ROLE_APPLICATION: |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5707 return static_cast<BrowserAccessibilityWin*>(obj); | 5739 return static_cast<BrowserAccessibilityWin*>(obj); |
| 5708 } | 5740 } |
| 5709 | 5741 |
| 5710 const BrowserAccessibilityWin* | 5742 const BrowserAccessibilityWin* |
| 5711 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { | 5743 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { |
| 5712 DCHECK(!obj || obj->IsNative()); | 5744 DCHECK(!obj || obj->IsNative()); |
| 5713 return static_cast<const BrowserAccessibilityWin*>(obj); | 5745 return static_cast<const BrowserAccessibilityWin*>(obj); |
| 5714 } | 5746 } |
| 5715 | 5747 |
| 5716 } // namespace content | 5748 } // namespace content |
| OLD | NEW |