OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome_frame/test/chrome_frame_ui_test_utils.h" | 5 #include "chrome_frame/test/chrome_frame_ui_test_utils.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include <sstream> | 9 #include <sstream> |
10 #include <stack> | 10 #include <stack> |
11 | 11 |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/scoped_bstr_win.h" | 13 #include "base/scoped_bstr_win.h" |
14 #include "base/scoped_ptr.h" | 14 #include "base/scoped_ptr.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 17 #include "gfx/point.h" |
17 #include "gfx/rect.h" | 18 #include "gfx/rect.h" |
18 #include "chrome_frame/test/win_event_receiver.h" | 19 #include "chrome_frame/test/win_event_receiver.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
20 | 21 |
21 namespace chrome_frame_test { | 22 namespace chrome_frame_test { |
22 | 23 |
23 // Timeout for waiting on Chrome to create the accessibility tree for the DOM. | 24 // Timeout for waiting on Chrome to create the accessibility tree for the DOM. |
24 const int kChromeDOMAccessibilityTreeTimeoutMs = 10 * 1000; | 25 const int kChromeDOMAccessibilityTreeTimeoutMs = 10 * 1000; |
25 | 26 |
26 // Timeout for waiting on a menu to popup. | 27 // Timeout for waiting on a menu to popup. |
(...skipping 12 matching lines...) Expand all Loading... |
39 LOG(ERROR) << "AccObject created which refers to full MSAA object using " | 40 LOG(ERROR) << "AccObject created which refers to full MSAA object using " |
40 "parent object and child id. This should NOT be done."; | 41 "parent object and child id. This should NOT be done."; |
41 } | 42 } |
42 DCHECK(result == S_FALSE || result == E_NOINTERFACE); | 43 DCHECK(result == S_FALSE || result == E_NOINTERFACE); |
43 } | 44 } |
44 } | 45 } |
45 | 46 |
46 // static | 47 // static |
47 AccObject* AccObject::CreateFromWindow(HWND hwnd) { | 48 AccObject* AccObject::CreateFromWindow(HWND hwnd) { |
48 ScopedComPtr<IAccessible> accessible; | 49 ScopedComPtr<IAccessible> accessible; |
49 AccessibleObjectFromWindow(hwnd, OBJID_CLIENT, | 50 ::AccessibleObjectFromWindow(hwnd, OBJID_CLIENT, |
50 IID_IAccessible, reinterpret_cast<void**>(accessible.Receive())); | 51 IID_IAccessible, reinterpret_cast<void**>(accessible.Receive())); |
51 if (accessible) | 52 if (accessible) |
52 return new AccObject(accessible); | 53 return new AccObject(accessible); |
53 return NULL; | 54 return NULL; |
54 } | 55 } |
55 | 56 |
56 // static | 57 // static |
57 AccObject* AccObject::CreateFromEvent(HWND hwnd, LONG object_id, | 58 AccObject* AccObject::CreateFromEvent(HWND hwnd, LONG object_id, |
58 LONG child_id) { | 59 LONG child_id) { |
59 ScopedComPtr<IAccessible> accessible; | 60 ScopedComPtr<IAccessible> accessible; |
60 ScopedVariant acc_child_id; | 61 ScopedVariant acc_child_id; |
61 AccessibleObjectFromEvent(hwnd, object_id, child_id, accessible.Receive(), | 62 ::AccessibleObjectFromEvent(hwnd, object_id, child_id, accessible.Receive(), |
62 acc_child_id.Receive()); | 63 acc_child_id.Receive()); |
63 if (accessible && acc_child_id.type() == VT_I4) | 64 if (accessible && acc_child_id.type() == VT_I4) |
64 return new AccObject(accessible, V_I4(&acc_child_id)); | 65 return new AccObject(accessible, V_I4(&acc_child_id)); |
65 return NULL; | 66 return NULL; |
66 } | 67 } |
67 | 68 |
68 // static | 69 // static |
69 AccObject* AccObject::CreateFromDispatch(IDispatch* dispatch) { | 70 AccObject* AccObject::CreateFromDispatch(IDispatch* dispatch) { |
70 if (dispatch) { | 71 if (dispatch) { |
71 ScopedComPtr<IAccessible> accessible; | 72 ScopedComPtr<IAccessible> accessible; |
72 accessible.QueryFrom(dispatch); | 73 accessible.QueryFrom(dispatch); |
73 if (accessible) | 74 if (accessible) |
74 return new AccObject(accessible); | 75 return new AccObject(accessible); |
75 } | 76 } |
76 return NULL; | 77 return NULL; |
77 } | 78 } |
78 | 79 |
79 // static | 80 // static |
80 AccObject* AccObject::CreateFromPoint(int x, int y) { | 81 AccObject* AccObject::CreateFromPoint(int x, int y) { |
81 ScopedComPtr<IAccessible> accessible; | 82 ScopedComPtr<IAccessible> accessible; |
82 ScopedVariant child_id; | 83 ScopedVariant child_id; |
83 POINT point = {x, y}; | 84 POINT point = {x, y}; |
84 AccessibleObjectFromPoint(point, accessible.Receive(), child_id.Receive()); | 85 ::AccessibleObjectFromPoint(point, accessible.Receive(), child_id.Receive()); |
85 if (accessible && child_id.type() == VT_I4) | 86 if (accessible && child_id.type() == VT_I4) |
86 return new AccObject(accessible, V_I4(&child_id)); | 87 return new AccObject(accessible, V_I4(&child_id)); |
87 return NULL; | 88 return NULL; |
88 } | 89 } |
89 | 90 |
90 bool AccObject::DoDefaultAction() { | 91 bool AccObject::DoDefaultAction() { |
| 92 HWND parent_window = NULL; |
| 93 ::WindowFromAccessibleObject(accessible_, &parent_window); |
| 94 if (!parent_window) { |
| 95 DLOG(ERROR) << "Could not get the window containing the given " |
| 96 << "accessibility object: " << GetDescription(); |
| 97 return false; |
| 98 } |
| 99 wchar_t class_name[MAX_PATH]; |
| 100 if (!::GetClassName(parent_window, class_name, arraysize(class_name))) { |
| 101 DLOG(ERROR) << "Could not get class name from accessibily object's window"; |
| 102 return false; |
| 103 } |
| 104 if (std::wstring(class_name) == L"#32768") { |
| 105 // Hack: if the desktop is locked, menu items cannot be selected using |
| 106 // accDoDefaultAction for some unknown reason. Get around this by |
| 107 // sending mouse button messages at the menu item location. Do this |
| 108 // even if the desktop is unlocked for consistency. We do not do this |
| 109 // for all objects because DoDefaultAction is not always equivalent to |
| 110 // a mouse click. |
| 111 gfx::Rect menu_item_rect; |
| 112 if (GetLocation(&menu_item_rect)) { |
| 113 DLOG(WARNING) << "Attempting to click menu item via mouse messages. " |
| 114 << "May not work for all menus"; |
| 115 // WM_LBUTTON* messages supposedly expect relative coordinates to the |
| 116 // client area, which for popup menus seems to be the entire desktop. |
| 117 gfx::Point center = menu_item_rect.CenterPoint(); |
| 118 LPARAM coordinates = (center.y() << 16) | center.x(); |
| 119 ::PostMessage(parent_window, WM_LBUTTONDOWN, (WPARAM)0, coordinates); |
| 120 ::PostMessage(parent_window, WM_LBUTTONUP, (WPARAM)0, coordinates); |
| 121 return true; |
| 122 } |
| 123 // TODO(kkania): Try sending the access key for the menu item to the |
| 124 // menu if the mouse button messages are found to be insufficient |
| 125 // at times. |
| 126 DLOG(ERROR) << "Could not get location of menu item via MSAA. " |
| 127 << "Accessibility object: " << WideToUTF8(this->GetDescription()) |
| 128 << std::endl << "This is necessary to select a menu item since the " |
| 129 << "desktop is locked."; |
| 130 return false; |
| 131 } |
| 132 |
91 HRESULT result = accessible_->accDoDefaultAction(child_id_); | 133 HRESULT result = accessible_->accDoDefaultAction(child_id_); |
92 EXPECT_HRESULT_SUCCEEDED(result) | 134 EXPECT_HRESULT_SUCCEEDED(result) |
93 << "Could not do default action for AccObject: " << GetDescription(); | 135 << "Could not do default action for AccObject: " << GetDescription(); |
94 return SUCCEEDED(result); | 136 return SUCCEEDED(result); |
95 } | 137 } |
96 | 138 |
97 bool AccObject::Focus() { | 139 bool AccObject::Focus() { |
98 EXPECT_HRESULT_SUCCEEDED( | 140 EXPECT_HRESULT_SUCCEEDED( |
99 accessible_->accSelect(SELFLAG_TAKEFOCUS, child_id_)); | 141 accessible_->accSelect(SELFLAG_TAKEFOCUS, child_id_)); |
100 | 142 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 const std::wstring& role_text, | 402 const std::wstring& role_text, |
361 const std::wstring& value) | 403 const std::wstring& value) |
362 : name_(name), role_text_(role_text), value_(value) { | 404 : name_(name), role_text_(role_text), value_(value) { |
363 } | 405 } |
364 | 406 |
365 bool AccObjectMatcher::FindHelper(AccObject* object, | 407 bool AccObjectMatcher::FindHelper(AccObject* object, |
366 scoped_refptr<AccObject>* match) const { | 408 scoped_refptr<AccObject>* match) const { |
367 // Determine if |object| is a match. | 409 // Determine if |object| is a match. |
368 bool does_match = true; | 410 bool does_match = true; |
369 std::wstring name, role_text, value; | 411 std::wstring name, role_text, value; |
370 if (name_.length()) | 412 if (name_.length()) { |
371 does_match = object->GetName(&name) && MatchPatternWide(name, name_); | 413 object->GetName(&name); |
| 414 does_match = MatchPatternWide(name, name_); |
| 415 } |
372 if (does_match && role_text_.length()) { | 416 if (does_match && role_text_.length()) { |
373 does_match = object->GetRoleText(&role_text) && | 417 object->GetRoleText(&role_text); |
374 MatchPatternWide(role_text, role_text_); | 418 does_match = MatchPatternWide(role_text, role_text_); |
375 } | 419 } |
376 if (does_match && value_.length()) | 420 if (does_match && value_.length()) { |
377 does_match = object->GetValue(&value) && MatchPatternWide(value, value_); | 421 object->GetValue(&value); |
378 | 422 does_match = MatchPatternWide(value, value_); |
| 423 } |
379 if (does_match) { | 424 if (does_match) { |
380 *match = object; | 425 *match = object; |
381 } else { | 426 } else { |
382 // Try to match the children of |object|. | 427 // Try to match the children of |object|. |
383 AccObject::RefCountedAccObjectVector children; | 428 AccObject::RefCountedAccObjectVector children; |
384 if (!object->GetChildren(&children)) { | 429 if (!object->GetChildren(&children)) { |
385 LOG(ERROR) << "Could not get children of AccObject"; | 430 LOG(ERROR) << "Could not get children of AccObject"; |
386 return false; | 431 return false; |
387 } | 432 } |
388 for (size_t i = 0; i < children.size(); ++i) { | 433 for (size_t i = 0; i < children.size(); ++i) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 } | 493 } |
449 | 494 |
450 bool IsDesktopUnlocked() { | 495 bool IsDesktopUnlocked() { |
451 HDESK desk = ::OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP); | 496 HDESK desk = ::OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP); |
452 if (desk) | 497 if (desk) |
453 ::CloseDesktop(desk); | 498 ::CloseDesktop(desk); |
454 return desk; | 499 return desk; |
455 } | 500 } |
456 | 501 |
457 } // namespace chrome_frame_test | 502 } // namespace chrome_frame_test |
OLD | NEW |