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 |