• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <string>
6 
7 #include "base/message_loop.h"
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/extensions/extension_accessibility_api.h"
11 #include "chrome/browser/ui/views/accessibility_event_router_views.h"
12 #include "chrome/test/testing_profile.h"
13 #include "content/common/notification_registrar.h"
14 #include "content/common/notification_service.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "views/controls/button/native_button.h"
17 #include "views/layout/grid_layout.h"
18 #include "views/views_delegate.h"
19 #include "views/widget/native_widget.h"
20 #include "views/widget/root_view.h"
21 #include "views/widget/widget.h"
22 #include "views/window/window.h"
23 #include "views/window/window_delegate.h"
24 
25 #if defined(TOOLKIT_VIEWS)
26 
27 class AccessibilityViewsDelegate : public views::ViewsDelegate {
28  public:
AccessibilityViewsDelegate()29   AccessibilityViewsDelegate() {}
~AccessibilityViewsDelegate()30   virtual ~AccessibilityViewsDelegate() {}
31 
32   // Overridden from views::ViewsDelegate:
GetClipboard() const33   virtual ui::Clipboard* GetClipboard() const { return NULL; }
SaveWindowPlacement(views::Window * window,const std::wstring & window_name,const gfx::Rect & bounds,bool maximized)34   virtual void SaveWindowPlacement(views::Window* window,
35                                    const std::wstring& window_name,
36                                    const gfx::Rect& bounds,
37                                    bool maximized) {
38   }
GetSavedWindowBounds(views::Window * window,const std::wstring & window_name,gfx::Rect * bounds) const39   virtual bool GetSavedWindowBounds(views::Window* window,
40                                     const std::wstring& window_name,
41                                     gfx::Rect* bounds) const {
42     return false;
43   }
GetSavedMaximizedState(views::Window * window,const std::wstring & window_name,bool * maximized) const44   virtual bool GetSavedMaximizedState(views::Window* window,
45                                       const std::wstring& window_name,
46                                       bool* maximized) const {
47     return false;
48   }
NotifyAccessibilityEvent(views::View * view,ui::AccessibilityTypes::Event event_type)49   virtual void NotifyAccessibilityEvent(
50       views::View* view, ui::AccessibilityTypes::Event event_type) {
51     AccessibilityEventRouterViews::GetInstance()->HandleAccessibilityEvent(
52         view, event_type);
53   }
NotifyMenuItemFocused(const std::wstring & menu_name,const std::wstring & menu_item_name,int item_index,int item_count,bool has_submenu)54   virtual void NotifyMenuItemFocused(
55       const std::wstring& menu_name,
56       const std::wstring& menu_item_name,
57       int item_index,
58       int item_count,
59       bool has_submenu) {}
60 #if defined(OS_WIN)
GetDefaultWindowIcon() const61   virtual HICON GetDefaultWindowIcon() const {
62     return NULL;
63   }
64 #endif
AddRef()65   virtual void AddRef() {}
ReleaseRef()66   virtual void ReleaseRef() {}
67 
68   DISALLOW_COPY_AND_ASSIGN(AccessibilityViewsDelegate);
69 };
70 
71 class AccessibilityWindowDelegate : public views::WindowDelegate {
72  public:
AccessibilityWindowDelegate(views::View * contents)73   explicit AccessibilityWindowDelegate(views::View* contents)
74       : contents_(contents) { }
75 
DeleteDelegate()76   virtual void DeleteDelegate() { delete this; }
77 
GetContentsView()78   virtual views::View* GetContentsView() { return contents_; }
79 
80  private:
81   views::View* contents_;
82 };
83 
84 class AccessibilityEventRouterViewsTest
85     : public testing::Test,
86       public NotificationObserver {
87  public:
SetUp()88   virtual void SetUp() {
89     views::ViewsDelegate::views_delegate = new AccessibilityViewsDelegate();
90     window_delegate_ = NULL;
91   }
92 
TearDown()93   virtual void TearDown() {
94     delete views::ViewsDelegate::views_delegate;
95     views::ViewsDelegate::views_delegate = NULL;
96     if (window_delegate_)
97       delete window_delegate_;
98   }
99 
CreateWindowWithContents(views::View * contents)100   views::Window* CreateWindowWithContents(views::View* contents) {
101     window_delegate_ = new AccessibilityWindowDelegate(contents);
102     return views::Window::CreateChromeWindow(
103         NULL, gfx::Rect(0, 0, 500, 500), window_delegate_);
104   }
105 
106  protected:
107   // Implement NotificationObserver::Observe and store information about a
108   // ACCESSIBILITY_CONTROL_FOCUSED event.
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)109   virtual void Observe(NotificationType type,
110                        const NotificationSource& source,
111                        const NotificationDetails& details) {
112     ASSERT_EQ(type.value, NotificationType::ACCESSIBILITY_CONTROL_FOCUSED);
113     const AccessibilityControlInfo* info =
114         Details<const AccessibilityControlInfo>(details).ptr();
115     focus_event_count_++;
116     last_control_name_ = info->name();
117   }
118 
119   MessageLoopForUI message_loop_;
120   int focus_event_count_;
121   std::string last_control_name_;
122   AccessibilityWindowDelegate* window_delegate_;
123 };
124 
TEST_F(AccessibilityEventRouterViewsTest,TestFocusNotification)125 TEST_F(AccessibilityEventRouterViewsTest, TestFocusNotification) {
126   const char kButton1ASCII[] = "Button1";
127   const char kButton2ASCII[] = "Button2";
128   const char kButton3ASCII[] = "Button3";
129   const char kButton3NewASCII[] = "Button3New";
130 
131   // Create a contents view with 3 buttons.
132   views::View* contents = new views::View();
133   views::NativeButton* button1 = new views::NativeButton(
134       NULL, ASCIIToWide(kButton1ASCII));
135   contents->AddChildView(button1);
136   views::NativeButton* button2 = new views::NativeButton(
137       NULL, ASCIIToWide(kButton2ASCII));
138   contents->AddChildView(button2);
139   views::NativeButton* button3 = new views::NativeButton(
140       NULL, ASCIIToWide(kButton3ASCII));
141   contents->AddChildView(button3);
142 
143   // Put the view in a window.
144   views::Window* window = CreateWindowWithContents(contents);
145 
146   // Set focus to the first button initially.
147   button1->RequestFocus();
148 
149   // Start listening to ACCESSIBILITY_CONTROL_FOCUSED notifications.
150   NotificationRegistrar registrar;
151   registrar.Add(this,
152                 NotificationType::ACCESSIBILITY_CONTROL_FOCUSED,
153                 NotificationService::AllSources());
154 
155   // Switch on accessibility event notifications.
156   ExtensionAccessibilityEventRouter* accessibility_event_router =
157       ExtensionAccessibilityEventRouter::GetInstance();
158   accessibility_event_router->SetAccessibilityEnabled(true);
159 
160   // Create a profile and associate it with this window.
161   TestingProfile profile;
162   window->AsWidget()->native_widget()->SetNativeWindowProperty(
163       Profile::kProfileKey, &profile);
164 
165   // Change the accessible name of button3.
166   button3->SetAccessibleName(ASCIIToUTF16(kButton3NewASCII));
167 
168   // Advance focus to the next button and test that we got the
169   // expected notification with the name of button 2.
170   views::FocusManager* focus_manager = contents->GetWidget()->GetFocusManager();
171   focus_event_count_ = 0;
172   focus_manager->AdvanceFocus(false);
173   EXPECT_EQ(1, focus_event_count_);
174   EXPECT_EQ(kButton2ASCII, last_control_name_);
175 
176   // Advance to button 3. Expect the new accessible name we assigned.
177   focus_manager->AdvanceFocus(false);
178   EXPECT_EQ(2, focus_event_count_);
179   EXPECT_EQ(kButton3NewASCII, last_control_name_);
180 
181   // Advance to button 1 and check the notification.
182   focus_manager->AdvanceFocus(false);
183   EXPECT_EQ(3, focus_event_count_);
184   EXPECT_EQ(kButton1ASCII, last_control_name_);
185 }
186 
187 #endif  // defined(TOOLKIT_VIEWS)
188