| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/accessibility_event_recorder.h" | 5 #include "content/browser/accessibility/accessibility_event_recorder.h" |
| 6 | 6 |
| 7 #include <oleacc.h> | 7 #include <oleacc.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 return base::UTF16ToUTF8(IAccessibleRoleToString(V_I4(role.ptr()))); | 32 return base::UTF16ToUTF8(IAccessibleRoleToString(V_I4(role.ptr()))); |
| 33 } else if (role.type() == VT_BSTR) { | 33 } else if (role.type() == VT_BSTR) { |
| 34 return base::UTF16ToUTF8( | 34 return base::UTF16ToUTF8( |
| 35 base::string16(V_BSTR(role.ptr()), SysStringLen(V_BSTR(role.ptr())))); | 35 base::string16(V_BSTR(role.ptr()), SysStringLen(V_BSTR(role.ptr())))); |
| 36 } | 36 } |
| 37 return std::string(); | 37 return std::string(); |
| 38 } | 38 } |
| 39 | 39 |
| 40 HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) { | 40 HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) { |
| 41 base::win::ScopedComPtr<IServiceProvider> service_provider; | 41 base::win::ScopedComPtr<IServiceProvider> service_provider; |
| 42 HRESULT hr = accessible->QueryInterface(service_provider.Receive()); | 42 HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf()); |
| 43 return SUCCEEDED(hr) ? | 43 return SUCCEEDED(hr) ? |
| 44 service_provider->QueryService(IID_IAccessible2, accessible2) : hr; | 44 service_provider->QueryService(IID_IAccessible2, accessible2) : hr; |
| 45 } | 45 } |
| 46 | 46 |
| 47 HRESULT QueryIAccessibleText(IAccessible* accessible, | 47 HRESULT QueryIAccessibleText(IAccessible* accessible, |
| 48 IAccessibleText** accessible_text) { | 48 IAccessibleText** accessible_text) { |
| 49 base::win::ScopedComPtr<IServiceProvider> service_provider; | 49 base::win::ScopedComPtr<IServiceProvider> service_provider; |
| 50 HRESULT hr = accessible->QueryInterface(service_provider.Receive()); | 50 HRESULT hr = accessible->QueryInterface(service_provider.GetAddressOf()); |
| 51 return SUCCEEDED(hr) ? | 51 return SUCCEEDED(hr) ? |
| 52 service_provider->QueryService(IID_IAccessibleText, accessible_text) : hr; | 52 service_provider->QueryService(IID_IAccessibleText, accessible_text) : hr; |
| 53 } | 53 } |
| 54 | 54 |
| 55 std::string BstrToUTF8(BSTR bstr) { | 55 std::string BstrToUTF8(BSTR bstr) { |
| 56 base::string16 str16(bstr, SysStringLen(bstr)); | 56 base::string16 str16(bstr, SysStringLen(bstr)); |
| 57 | 57 |
| 58 // IAccessibleText returns the text you get by appending all static text | 58 // IAccessibleText returns the text you get by appending all static text |
| 59 // children, with an "embedded object character" for each non-text child. | 59 // children, with an "embedded object character" for each non-text child. |
| 60 // Pretty-print the embedded object character as <obj> so that test output | 60 // Pretty-print the embedded object character as <obj> so that test output |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 void AccessibilityEventRecorderWin::OnWinEventHook( | 158 void AccessibilityEventRecorderWin::OnWinEventHook( |
| 159 HWINEVENTHOOK handle, | 159 HWINEVENTHOOK handle, |
| 160 DWORD event, | 160 DWORD event, |
| 161 HWND hwnd, | 161 HWND hwnd, |
| 162 LONG obj_id, | 162 LONG obj_id, |
| 163 LONG child_id, | 163 LONG child_id, |
| 164 DWORD event_thread, | 164 DWORD event_thread, |
| 165 DWORD event_time) { | 165 DWORD event_time) { |
| 166 base::win::ScopedComPtr<IAccessible> browser_accessible; | 166 base::win::ScopedComPtr<IAccessible> browser_accessible; |
| 167 HRESULT hr = AccessibleObjectFromWindowWrapper( | 167 HRESULT hr = AccessibleObjectFromWindowWrapper( |
| 168 hwnd, | 168 hwnd, obj_id, IID_IAccessible, |
| 169 obj_id, | 169 reinterpret_cast<void**>(browser_accessible.GetAddressOf())); |
| 170 IID_IAccessible, | |
| 171 reinterpret_cast<void**>(browser_accessible.Receive())); | |
| 172 if (!SUCCEEDED(hr)) { | 170 if (!SUCCEEDED(hr)) { |
| 173 // Note: our event hook will pick up some superfluous events we | 171 // Note: our event hook will pick up some superfluous events we |
| 174 // don't care about, so it's safe to just ignore these failures. | 172 // don't care about, so it's safe to just ignore these failures. |
| 175 // Same below for other HRESULT checks. | 173 // Same below for other HRESULT checks. |
| 176 VLOG(1) << "Ignoring result " << hr << " from AccessibleObjectFromWindow"; | 174 VLOG(1) << "Ignoring result " << hr << " from AccessibleObjectFromWindow"; |
| 177 return; | 175 return; |
| 178 } | 176 } |
| 179 | 177 |
| 180 base::win::ScopedVariant childid_variant(child_id); | 178 base::win::ScopedVariant childid_variant(child_id); |
| 181 base::win::ScopedComPtr<IDispatch> dispatch; | 179 base::win::ScopedComPtr<IDispatch> dispatch; |
| 182 hr = browser_accessible->get_accChild(childid_variant, dispatch.Receive()); | 180 hr = browser_accessible->get_accChild(childid_variant, |
| 181 dispatch.GetAddressOf()); |
| 183 if (!SUCCEEDED(hr) || !dispatch) { | 182 if (!SUCCEEDED(hr) || !dispatch) { |
| 184 VLOG(1) << "Ignoring result " << hr << " and result " << dispatch | 183 VLOG(1) << "Ignoring result " << hr << " and result " << dispatch |
| 185 << " from get_accChild"; | 184 << " from get_accChild"; |
| 186 return; | 185 return; |
| 187 } | 186 } |
| 188 | 187 |
| 189 base::win::ScopedComPtr<IAccessible> iaccessible; | 188 base::win::ScopedComPtr<IAccessible> iaccessible; |
| 190 hr = dispatch.CopyTo(iaccessible.Receive()); | 189 hr = dispatch.CopyTo(iaccessible.GetAddressOf()); |
| 191 if (!SUCCEEDED(hr)) { | 190 if (!SUCCEEDED(hr)) { |
| 192 VLOG(1) << "Ignoring result " << hr << " from QueryInterface"; | 191 VLOG(1) << "Ignoring result " << hr << " from QueryInterface"; |
| 193 return; | 192 return; |
| 194 } | 193 } |
| 195 | 194 |
| 196 std::string event_str = AccessibilityEventToStringUTF8(event); | 195 std::string event_str = AccessibilityEventToStringUTF8(event); |
| 197 if (event_str.empty()) { | 196 if (event_str.empty()) { |
| 198 VLOG(1) << "Ignoring event " << event; | 197 VLOG(1) << "Ignoring event " << event; |
| 199 return; | 198 return; |
| 200 } | 199 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 221 // window is frontmost or not, and "hottracked" depends on whether the | 220 // window is frontmost or not, and "hottracked" depends on whether the |
| 222 // mouse cursor happens to be over the element. | 221 // mouse cursor happens to be over the element. |
| 223 ia_state &= (~STATE_SYSTEM_OFFSCREEN & ~STATE_SYSTEM_HOTTRACKED); | 222 ia_state &= (~STATE_SYSTEM_OFFSCREEN & ~STATE_SYSTEM_HOTTRACKED); |
| 224 | 223 |
| 225 // The "readonly" state is set on almost every node and doesn't typically | 224 // The "readonly" state is set on almost every node and doesn't typically |
| 226 // change, so filter it out to keep the output less verbose. | 225 // change, so filter it out to keep the output less verbose. |
| 227 ia_state &= ~STATE_SYSTEM_READONLY; | 226 ia_state &= ~STATE_SYSTEM_READONLY; |
| 228 | 227 |
| 229 AccessibleStates ia2_state = 0; | 228 AccessibleStates ia2_state = 0; |
| 230 base::win::ScopedComPtr<IAccessible2> iaccessible2; | 229 base::win::ScopedComPtr<IAccessible2> iaccessible2; |
| 231 hr = QueryIAccessible2(iaccessible.Get(), iaccessible2.Receive()); | 230 hr = QueryIAccessible2(iaccessible.Get(), iaccessible2.GetAddressOf()); |
| 232 if (SUCCEEDED(hr)) | 231 if (SUCCEEDED(hr)) |
| 233 iaccessible2->get_states(&ia2_state); | 232 iaccessible2->get_states(&ia2_state); |
| 234 | 233 |
| 235 std::string log = base::StringPrintf( | 234 std::string log = base::StringPrintf( |
| 236 "%s on role=%s", event_str.c_str(), RoleVariantToString(role).c_str()); | 235 "%s on role=%s", event_str.c_str(), RoleVariantToString(role).c_str()); |
| 237 if (name_bstr.Length() > 0) | 236 if (name_bstr.Length() > 0) |
| 238 log += base::StringPrintf(" name=\"%s\"", BstrToUTF8(name_bstr).c_str()); | 237 log += base::StringPrintf(" name=\"%s\"", BstrToUTF8(name_bstr).c_str()); |
| 239 if (value_bstr.Length() > 0) | 238 if (value_bstr.Length() > 0) |
| 240 log += base::StringPrintf(" value=\"%s\"", BstrToUTF8(value_bstr).c_str()); | 239 log += base::StringPrintf(" value=\"%s\"", BstrToUTF8(value_bstr).c_str()); |
| 241 log += " "; | 240 log += " "; |
| 242 log += base::UTF16ToUTF8(IAccessibleStateToString(ia_state)); | 241 log += base::UTF16ToUTF8(IAccessibleStateToString(ia_state)); |
| 243 log += " "; | 242 log += " "; |
| 244 log += base::UTF16ToUTF8(IAccessible2StateToString(ia2_state)); | 243 log += base::UTF16ToUTF8(IAccessible2StateToString(ia2_state)); |
| 245 | 244 |
| 246 // For TEXT_REMOVED and TEXT_INSERTED events, query the text that was | 245 // For TEXT_REMOVED and TEXT_INSERTED events, query the text that was |
| 247 // inserted or removed and include that in the log. | 246 // inserted or removed and include that in the log. |
| 248 base::win::ScopedComPtr<IAccessibleText> accessible_text; | 247 base::win::ScopedComPtr<IAccessibleText> accessible_text; |
| 249 hr = QueryIAccessibleText(iaccessible.Get(), accessible_text.Receive()); | 248 hr = QueryIAccessibleText(iaccessible.Get(), accessible_text.GetAddressOf()); |
| 250 if (SUCCEEDED(hr)) { | 249 if (SUCCEEDED(hr)) { |
| 251 if (event == IA2_EVENT_TEXT_REMOVED) { | 250 if (event == IA2_EVENT_TEXT_REMOVED) { |
| 252 IA2TextSegment old_text; | 251 IA2TextSegment old_text; |
| 253 if (SUCCEEDED(accessible_text->get_oldText(&old_text))) { | 252 if (SUCCEEDED(accessible_text->get_oldText(&old_text))) { |
| 254 log += base::StringPrintf(" old_text={'%s' start=%d end=%d}", | 253 log += base::StringPrintf(" old_text={'%s' start=%d end=%d}", |
| 255 BstrToUTF8(old_text.text).c_str(), | 254 BstrToUTF8(old_text.text).c_str(), |
| 256 old_text.start, | 255 old_text.start, |
| 257 old_text.end); | 256 old_text.end); |
| 258 } | 257 } |
| 259 } | 258 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 287 if (accessibility_hwnd != hwnd) | 286 if (accessibility_hwnd != hwnd) |
| 288 return E_FAIL; | 287 return E_FAIL; |
| 289 | 288 |
| 290 IAccessible* obj = ToBrowserAccessibilityComWin(manager_->GetRoot()); | 289 IAccessible* obj = ToBrowserAccessibilityComWin(manager_->GetRoot()); |
| 291 obj->AddRef(); | 290 obj->AddRef(); |
| 292 *ppv_object = obj; | 291 *ppv_object = obj; |
| 293 return S_OK; | 292 return S_OK; |
| 294 } | 293 } |
| 295 | 294 |
| 296 } // namespace content | 295 } // namespace content |
| OLD | NEW |