Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / braille_display_private / braille_display_private_apitest.cc
1 // Copyright 2013 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 #ifndef USE_BRLAPI
6 #error This test requires brlapi.
7 #endif
8
9 #include <deque>
10
11 #include "base/bind.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
14 #include "chrome/browser/chromeos/login/screen_locker.h"
15 #include "chrome/browser/chromeos/login/screen_locker_tester.h"
16 #include "chrome/browser/chromeos/login/user_manager.h"
17 #include "chrome/browser/chromeos/profiles/profile_helper.h"
18 #include "chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.h"
19 #include "chrome/browser/extensions/api/braille_display_private/braille_display_private_api.h"
20 #include "chrome/browser/extensions/api/braille_display_private/brlapi_connection.h"
21 #include "chrome/browser/extensions/api/braille_display_private/stub_braille_controller.h"
22 #include "chrome/browser/extensions/extension_apitest.h"
23 #include "chrome/browser/profiles/profile_manager.h"
24 #include "chrome/test/base/testing_profile.h"
25 #include "chromeos/chromeos_switches.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/notification_service.h"
28 #include "content/public/test/test_utils.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30
31 using chromeos::ProfileHelper;
32 using chromeos::ScreenLocker;
33 using chromeos::UserManager;
34 using chromeos::test::ScreenLockerTester;
35 using content::BrowserThread;
36
37 namespace extensions {
38 namespace api {
39 namespace braille_display_private {
40
41 namespace {
42
43 const char kTestUserName[] = "owner@invalid.domain";
44
45 }  // namespace
46
47 // Data maintained by the mock BrlapiConnection.  This data lives throughout
48 // a test, while the api implementation takes ownership of the connection
49 // itself.
50 struct MockBrlapiConnectionData {
51   bool connected;
52   size_t display_size;
53   brlapi_error_t error;
54   std::vector<std::string> written_content;
55   // List of brlapi key codes.  A negative number makes the connection mock
56   // return an error from ReadKey.
57   std::deque<brlapi_keyCode_t> pending_keys;
58   // Causes a new display to appear to appear on disconnect, that is the
59   // display size doubles and the controller gets notified of a brltty
60   // restart.
61   bool reappear_on_disconnect;
62 };
63
64 class MockBrlapiConnection : public BrlapiConnection {
65  public:
66   explicit MockBrlapiConnection(MockBrlapiConnectionData* data)
67       : data_(data) {}
68   virtual ConnectResult Connect(const OnDataReadyCallback& on_data_ready)
69       OVERRIDE {
70     data_->connected = true;
71     on_data_ready_ = on_data_ready;
72     if (!data_->pending_keys.empty()) {
73       BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
74                               base::Bind(&MockBrlapiConnection::NotifyDataReady,
75                                         base::Unretained(this)));
76     }
77     return CONNECT_SUCCESS;
78   }
79
80   virtual void Disconnect() OVERRIDE {
81     data_->connected = false;
82     if (data_->reappear_on_disconnect) {
83       data_->display_size *= 2;
84       BrowserThread::PostTask(
85           BrowserThread::IO, FROM_HERE,
86           base::Bind(&BrailleControllerImpl::PokeSocketDirForTesting,
87                      base::Unretained(BrailleControllerImpl::GetInstance())));
88     }
89   }
90
91   virtual bool Connected() OVERRIDE {
92     return data_->connected;
93   }
94
95   virtual brlapi_error_t* BrlapiError() OVERRIDE {
96     return &data_->error;
97   }
98
99   virtual std::string BrlapiStrError() OVERRIDE {
100     return data_->error.brlerrno != BRLAPI_ERROR_SUCCESS ? "Error" : "Success";
101   }
102
103   virtual bool GetDisplaySize(size_t* size) OVERRIDE {
104     *size = data_->display_size;
105     return true;
106   }
107
108   virtual bool WriteDots(const unsigned char* cells) OVERRIDE {
109     std::string written(reinterpret_cast<const char*>(cells),
110                         data_->display_size);
111     data_->written_content.push_back(written);
112     return true;
113   }
114
115   virtual int ReadKey(brlapi_keyCode_t* key_code) OVERRIDE {
116     if (!data_->pending_keys.empty()) {
117       int queued_key_code = data_->pending_keys.front();
118       data_->pending_keys.pop_front();
119       if (queued_key_code < 0) {
120         data_->error.brlerrno = BRLAPI_ERROR_EOF;
121         return -1;  // Signal error.
122       }
123       *key_code = queued_key_code;
124       return 1;
125     } else {
126       return 0;
127     }
128   }
129
130  private:
131
132   void NotifyDataReady() {
133     on_data_ready_.Run();
134     if (!data_->pending_keys.empty()) {
135       BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
136                               base::Bind(&MockBrlapiConnection::NotifyDataReady,
137                                         base::Unretained(this)));
138     }
139   }
140
141   MockBrlapiConnectionData* data_;
142   OnDataReadyCallback on_data_ready_;
143 };
144
145 class BrailleDisplayPrivateApiTest : public ExtensionApiTest {
146  public:
147   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
148     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
149     connection_data_.connected = false;
150     connection_data_.display_size = 0;
151     connection_data_.error.brlerrno = BRLAPI_ERROR_SUCCESS;
152     connection_data_.reappear_on_disconnect = false;
153     BrailleControllerImpl::GetInstance()->SetCreateBrlapiConnectionForTesting(
154         base::Bind(
155             &BrailleDisplayPrivateApiTest::CreateBrlapiConnection,
156             base::Unretained(this)));
157     DisableAccessibilityManagerBraille();
158   }
159
160  protected:
161   MockBrlapiConnectionData connection_data_;
162
163   // By default, don't let the accessibility manager interfere and
164   // steal events.  Some tests override this to keep the normal behaviour
165   // of the accessibility manager.
166   virtual void DisableAccessibilityManagerBraille() {
167     chromeos::AccessibilityManager::SetBrailleControllerForTest(
168         &stub_braille_controller_);
169   }
170
171  private:
172   scoped_ptr<BrlapiConnection> CreateBrlapiConnection() {
173     return scoped_ptr<BrlapiConnection>(
174         new MockBrlapiConnection(&connection_data_));
175   }
176
177   StubBrailleController stub_braille_controller_;
178 };
179
180 IN_PROC_BROWSER_TEST_F(BrailleDisplayPrivateApiTest, WriteDots) {
181   connection_data_.display_size = 11;
182   ASSERT_TRUE(RunComponentExtensionTest("braille_display_private/write_dots"))
183       << message_;
184   ASSERT_EQ(3U, connection_data_.written_content.size());
185   const std::string expected_content(connection_data_.display_size, '\0');
186   for (size_t i = 0; i < connection_data_.written_content.size(); ++i) {
187     ASSERT_EQ(std::string(
188         connection_data_.display_size,
189         static_cast<char>(i)),
190                  connection_data_.written_content[i])
191         << "String " << i << " doesn't match";
192   }
193 }
194
195 IN_PROC_BROWSER_TEST_F(BrailleDisplayPrivateApiTest, KeyEvents) {
196   connection_data_.display_size = 11;
197   connection_data_.pending_keys.push_back(BRLAPI_KEY_TYPE_CMD |
198                                           BRLAPI_KEY_CMD_LNUP);
199   connection_data_.pending_keys.push_back(BRLAPI_KEY_TYPE_CMD |
200                                           BRLAPI_KEY_CMD_LNDN);
201   connection_data_.pending_keys.push_back(BRLAPI_KEY_TYPE_CMD |
202                                           BRLAPI_KEY_CMD_FWINLT);
203   connection_data_.pending_keys.push_back(BRLAPI_KEY_TYPE_CMD |
204                                           BRLAPI_KEY_CMD_FWINRT);
205   connection_data_.pending_keys.push_back(BRLAPI_KEY_TYPE_CMD |
206                                           BRLAPI_KEY_CMD_TOP);
207   connection_data_.pending_keys.push_back(BRLAPI_KEY_TYPE_CMD |
208                                           BRLAPI_KEY_CMD_BOT);
209   connection_data_.pending_keys.push_back(BRLAPI_KEY_TYPE_CMD |
210                                           BRLAPI_KEY_CMD_ROUTE | 5);
211   // Space (0) and all combinations of dots.
212   for (int i = 0; i < 256; ++i) {
213     connection_data_.pending_keys.push_back(BRLAPI_KEY_TYPE_CMD |
214                                             BRLAPI_KEY_CMD_PASSDOTS | i);
215   }
216   ASSERT_TRUE(RunComponentExtensionTest("braille_display_private/key_events"));
217 }
218
219 IN_PROC_BROWSER_TEST_F(BrailleDisplayPrivateApiTest, DisplayStateChanges) {
220   connection_data_.display_size = 11;
221   connection_data_.pending_keys.push_back(-1);
222   connection_data_.reappear_on_disconnect = true;
223   ASSERT_TRUE(RunComponentExtensionTest(
224       "braille_display_private/display_state_changes"));
225 }
226
227 class BrailleDisplayPrivateAPIUserTest : public BrailleDisplayPrivateApiTest {
228  public:
229   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
230     command_line->AppendSwitch(chromeos::switches::kLoginManager);
231     command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
232                                     TestingProfile::kTestUserProfileDir);
233   }
234
235   class MockEventDelegate : public BrailleDisplayPrivateAPI::EventDelegate {
236    public:
237     MockEventDelegate() : event_count_(0) {}
238
239     int GetEventCount() { return event_count_; }
240
241     virtual void BroadcastEvent(scoped_ptr<Event> event) OVERRIDE {
242       ++event_count_;
243     }
244     virtual bool HasListener() OVERRIDE { return true; }
245
246    private:
247     int event_count_;
248   };
249
250   MockEventDelegate* SetMockEventDelegate(BrailleDisplayPrivateAPI* api) {
251     MockEventDelegate* delegate = new MockEventDelegate();
252     api->SetEventDelegateForTest(
253         scoped_ptr<BrailleDisplayPrivateAPI::EventDelegate>(delegate).Pass());
254     return delegate;
255   }
256
257   void LockScreen(ScreenLockerTester* tester) {
258     ScreenLocker::Show();
259     tester->EmulateWindowManagerReady();
260     content::WindowedNotificationObserver lock_state_observer(
261         chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
262         content::NotificationService::AllSources());
263     if (!tester->IsLocked())
264       lock_state_observer.Wait();
265     ASSERT_TRUE(tester->IsLocked());
266   }
267
268   void DismissLockScreen(ScreenLockerTester* tester) {
269     ScreenLocker::Hide();
270     content::WindowedNotificationObserver lock_state_observer(
271         chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
272         content::NotificationService::AllSources());
273     if (tester->IsLocked())
274       lock_state_observer.Wait();
275     ASSERT_FALSE(tester->IsLocked());
276   }
277
278  protected:
279   virtual void DisableAccessibilityManagerBraille() OVERRIDE {
280     // Let the accessibility manager behave as usual for these tests.
281   }
282 };
283
284 IN_PROC_BROWSER_TEST_F(BrailleDisplayPrivateAPIUserTest,
285                        KeyEventOnLockScreen) {
286   scoped_ptr<ScreenLockerTester> tester(ScreenLocker::GetTester());
287   // Log in.
288   UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
289   UserManager::Get()->SessionStarted();
290   Profile* profile = ProfileManager::GetActiveUserProfile();
291   ASSERT_FALSE(
292       ProfileHelper::GetSigninProfile()->IsSameProfile(profile))
293       << ProfileHelper::GetSigninProfile()->GetDebugName() << " vs. "
294       << profile->GetDebugName();
295
296   // Create API and event delegate for sign in profile.
297   BrailleDisplayPrivateAPI signin_api(ProfileHelper::GetSigninProfile());
298   MockEventDelegate* signin_delegate = SetMockEventDelegate(&signin_api);
299   EXPECT_EQ(0, signin_delegate->GetEventCount());
300   // Create api and delegate for the logged in user.
301   BrailleDisplayPrivateAPI user_api(profile);
302   MockEventDelegate* user_delegate = SetMockEventDelegate(&user_api);
303
304   // Send key event to both profiles.
305   KeyEvent key_event;
306   key_event.command = KEY_COMMAND_LINE_UP;
307   signin_api.OnKeyEvent(key_event);
308   user_api.OnKeyEvent(key_event);
309   EXPECT_EQ(0, signin_delegate->GetEventCount());
310   EXPECT_EQ(1, user_delegate->GetEventCount());
311
312   // Lock screen, and make sure that the key event goes to the
313   // signin profile.
314   LockScreen(tester.get());
315   signin_api.OnKeyEvent(key_event);
316   user_api.OnKeyEvent(key_event);
317   EXPECT_EQ(1, signin_delegate->GetEventCount());
318   EXPECT_EQ(1, user_delegate->GetEventCount());
319
320   // Unlock screen, making sur ekey events go to the user profile again.
321   DismissLockScreen(tester.get());
322   signin_api.OnKeyEvent(key_event);
323   user_api.OnKeyEvent(key_event);
324   EXPECT_EQ(1, signin_delegate->GetEventCount());
325   EXPECT_EQ(2, user_delegate->GetEventCount());
326 }
327
328 }  // namespace braille_display_private
329 }  // namespace api
330 }  // namespace extensions