1 // Copyright (c) 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.
5 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
7 #include "ash/magnifier/magnification_controller.h"
9 #include "base/command_line.h"
10 #include "base/prefs/pref_service.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/chromeos/accessibility/magnification_manager.h"
14 #include "chrome/browser/chromeos/login/helper.h"
15 #include "chrome/browser/chromeos/login/login_utils.h"
16 #include "chrome/browser/chromeos/login/user_manager.h"
17 #include "chrome/browser/chromeos/login/user_manager_impl.h"
18 #include "chrome/browser/chromeos/profiles/profile_helper.h"
19 #include "chrome/browser/extensions/api/braille_display_private/stub_braille_controller.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/profiles/profile_manager.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/in_process_browser_test.h"
24 #include "chrome/test/base/testing_profile.h"
25 #include "chromeos/chromeos_switches.h"
26 #include "content/public/browser/notification_service.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 using extensions::api::braille_display_private::BrailleObserver
;
30 using extensions::api::braille_display_private::DisplayState
;
31 using extensions::api::braille_display_private::StubBrailleController
;
37 const char kTestUserName
[] = "owner@invalid.domain";
39 const int kTestAutoclickDelayMs
= 2000;
41 // Test user name for locally managed user. The domain part must be matched
42 // with UserManager::kLocallyManagedUserDomain.
43 const char kTestLocallyManagedUserName
[] = "test@locally-managed.localhost";
45 class MockAccessibilityObserver
: public content::NotificationObserver
{
47 MockAccessibilityObserver() : observed_(false),
48 observed_enabled_(false),
52 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
,
53 content::NotificationService::AllSources());
56 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE
,
57 content::NotificationService::AllSources());
59 virtual ~MockAccessibilityObserver() {}
61 bool observed() const { return observed_
; }
62 bool observed_enabled() const { return observed_enabled_
; }
63 int observed_type() const { return observed_type_
; }
65 void reset() { observed_
= false; }
68 // content::NotificationObserver implimentation:
69 virtual void Observe(int type
,
70 const content::NotificationSource
& source
,
71 const content::NotificationDetails
& details
) OVERRIDE
{
72 AccessibilityStatusEventDetails
* accessibility_status
=
73 content::Details
<AccessibilityStatusEventDetails
>(
75 ASSERT_FALSE(observed_
);
78 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
:
80 observed_enabled_
= accessibility_status
->enabled
;
81 observed_type_
= type
;
83 case chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE
:
85 observed_enabled_
= accessibility_status
->enabled
;
86 observed_type_
= type
;
92 bool observed_enabled_
;
95 content::NotificationRegistrar registrar_
;
97 DISALLOW_COPY_AND_ASSIGN(MockAccessibilityObserver
);
100 class MockBrailleController
: public StubBrailleController
{
103 MockBrailleController() : available_(false), observer_(NULL
) {}
105 virtual scoped_ptr
<DisplayState
> GetDisplayState() OVERRIDE
{
106 scoped_ptr
<DisplayState
> state(new DisplayState());
107 state
->available
= available_
;
111 virtual void AddObserver(BrailleObserver
* observer
) OVERRIDE
{
112 ASSERT_EQ(NULL
, observer_
);
113 observer_
= observer
;
116 virtual void RemoveObserver(BrailleObserver
* observer
) OVERRIDE
{
117 ASSERT_EQ(observer_
, observer
);
120 void SetAvailable(bool available
) {
121 available_
= available
;
124 BrailleObserver
* GetObserver() {
130 BrailleObserver
* observer_
;
133 void SetLargeCursorEnabled(bool enabled
) {
134 return AccessibilityManager::Get()->EnableLargeCursor(enabled
);
137 bool IsLargeCursorEnabled() {
138 return AccessibilityManager::Get()->IsLargeCursorEnabled();
141 bool ShouldShowAccessibilityMenu() {
142 return AccessibilityManager::Get()->ShouldShowAccessibilityMenu();
145 void SetHighContrastEnabled(bool enabled
) {
146 return AccessibilityManager::Get()->EnableHighContrast(enabled
);
149 bool IsHighContrastEnabled() {
150 return AccessibilityManager::Get()->IsHighContrastEnabled();
153 void SetSpokenFeedbackEnabled(bool enabled
) {
154 return AccessibilityManager::Get()->EnableSpokenFeedback(
155 enabled
, ash::A11Y_NOTIFICATION_NONE
);
158 bool IsSpokenFeedbackEnabled() {
159 return AccessibilityManager::Get()->IsSpokenFeedbackEnabled();
162 void SetAutoclickEnabled(bool enabled
) {
163 return AccessibilityManager::Get()->EnableAutoclick(enabled
);
166 bool IsAutoclickEnabled() {
167 return AccessibilityManager::Get()->IsAutoclickEnabled();
170 void SetAutoclickDelay(int delay_ms
) {
171 return AccessibilityManager::Get()->SetAutoclickDelay(delay_ms
);
174 int GetAutoclickDelay() {
175 return AccessibilityManager::Get()->GetAutoclickDelay();
178 Profile
* GetProfile() {
179 Profile
* profile
= ProfileManager::GetActiveUserProfile();
184 PrefService
* GetPrefs() {
185 return GetProfile()->GetPrefs();
188 void SetLargeCursorEnabledPref(bool enabled
) {
189 GetPrefs()->SetBoolean(prefs::kLargeCursorEnabled
, enabled
);
192 void SetHighContrastEnabledPref(bool enabled
) {
193 GetPrefs()->SetBoolean(prefs::kHighContrastEnabled
, enabled
);
196 void SetSpokenFeedbackEnabledPref(bool enabled
) {
197 GetPrefs()->SetBoolean(prefs::kSpokenFeedbackEnabled
, enabled
);
200 void SetAutoclickEnabledPref(bool enabled
) {
201 GetPrefs()->SetBoolean(prefs::kAutoclickEnabled
, enabled
);
204 void SetAutoclickDelayPref(int delay_ms
) {
205 GetPrefs()->SetInteger(prefs::kAutoclickDelayMs
, delay_ms
);
208 bool GetLargeCursorEnabledFromPref() {
209 return GetPrefs()->GetBoolean(prefs::kLargeCursorEnabled
);
212 bool GetHighContrastEnabledFromPref() {
213 return GetPrefs()->GetBoolean(prefs::kHighContrastEnabled
);
216 bool GetSpokenFeedbackEnabledFromPref() {
217 return GetPrefs()->GetBoolean(prefs::kSpokenFeedbackEnabled
);
220 bool GetAutoclickEnabledFromPref() {
221 return GetPrefs()->GetBoolean(prefs::kAutoclickEnabled
);
224 int GetAutoclickDelayFromPref() {
225 return GetPrefs()->GetInteger(prefs::kAutoclickDelayMs
);
228 } // anonymouse namespace
230 class AccessibilityManagerTest
: public InProcessBrowserTest
{
232 AccessibilityManagerTest() : default_autoclick_delay_(0) {}
233 virtual ~AccessibilityManagerTest() {}
235 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
236 command_line
->AppendSwitch(chromeos::switches::kLoginManager
);
237 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
,
238 TestingProfile::kTestUserProfileDir
);
241 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE
{
242 AccessibilityManager::SetBrailleControllerForTest(&braille_controller_
);
245 virtual void SetUpOnMainThread() OVERRIDE
{
246 // Sets the login-screen profile.
247 AccessibilityManager::Get()->
248 SetProfileForTest(ProfileHelper::GetSigninProfile());
249 default_autoclick_delay_
= GetAutoclickDelay();
252 virtual void CleanUpOnMainThread() OVERRIDE
{
253 AccessibilityManager::SetBrailleControllerForTest(NULL
);
256 int default_autoclick_delay() const { return default_autoclick_delay_
; }
258 int default_autoclick_delay_
;
260 content::NotificationRegistrar registrar_
;
262 MockBrailleController braille_controller_
;
263 DISALLOW_COPY_AND_ASSIGN(AccessibilityManagerTest
);
266 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest
, Login
) {
267 // Confirms that a11y features are disabled on the login screen.
268 EXPECT_FALSE(IsLargeCursorEnabled());
269 EXPECT_FALSE(IsSpokenFeedbackEnabled());
270 EXPECT_FALSE(IsHighContrastEnabled());
271 EXPECT_FALSE(IsAutoclickEnabled());
272 EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay());
275 UserManager::Get()->UserLoggedIn(kTestUserName
, kTestUserName
, true);
277 // Confirms that the features still disabled just after login.
278 EXPECT_FALSE(IsLargeCursorEnabled());
279 EXPECT_FALSE(IsSpokenFeedbackEnabled());
280 EXPECT_FALSE(IsHighContrastEnabled());
281 EXPECT_FALSE(IsAutoclickEnabled());
282 EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay());
284 UserManager::Get()->SessionStarted();
286 // Confirms that the features are still disabled just after login.
287 EXPECT_FALSE(IsLargeCursorEnabled());
288 EXPECT_FALSE(IsSpokenFeedbackEnabled());
289 EXPECT_FALSE(IsHighContrastEnabled());
290 EXPECT_FALSE(IsAutoclickEnabled());
291 EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay());
293 // Enables large cursor.
294 SetLargeCursorEnabled(true);
295 // Confirms that large cursor is enabled.
296 EXPECT_TRUE(IsLargeCursorEnabled());
298 // Enables spoken feedback.
299 SetSpokenFeedbackEnabled(true);
300 // Confirms that the spoken feedback is enabled.
301 EXPECT_TRUE(IsSpokenFeedbackEnabled());
303 // Enables high contrast.
304 SetHighContrastEnabled(true);
305 // Confirms that high cotrast is enabled.
306 EXPECT_TRUE(IsHighContrastEnabled());
308 // Enables autoclick.
309 SetAutoclickEnabled(true);
310 // Confirms that autoclick is enabled.
311 EXPECT_TRUE(IsAutoclickEnabled());
313 // Test that autoclick delay is set properly.
314 SetAutoclickDelay(kTestAutoclickDelayMs
);
315 EXPECT_EQ(kTestAutoclickDelayMs
, GetAutoclickDelay());
318 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest
, BrailleOnLoginScreen
) {
319 EXPECT_FALSE(IsSpokenFeedbackEnabled());
321 // Signal the accessibility manager that a braille display was connected.
322 braille_controller_
.SetAvailable(true);
323 braille_controller_
.GetObserver()->OnDisplayStateChanged(
324 *braille_controller_
.GetDisplayState());
326 // Confirms that the spoken feedback is enabled.
327 EXPECT_TRUE(IsSpokenFeedbackEnabled());
330 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest
, TypePref
) {
332 UserManager::Get()->UserLoggedIn(kTestUserName
, kTestUserName
, true);
333 UserManager::Get()->SessionStarted();
335 // Confirms that the features are disabled just after login.
336 EXPECT_FALSE(IsLargeCursorEnabled());
337 EXPECT_FALSE(IsSpokenFeedbackEnabled());
338 EXPECT_FALSE(IsHighContrastEnabled());
339 EXPECT_FALSE(IsAutoclickEnabled());
340 EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay());
342 // Sets the pref as true to enable the large cursor.
343 SetLargeCursorEnabledPref(true);
344 // Confirms that the large cursor is enabled.
345 EXPECT_TRUE(IsLargeCursorEnabled());
347 // Sets the pref as true to enable the spoken feedback.
348 SetSpokenFeedbackEnabledPref(true);
349 // Confirms that the spoken feedback is enabled.
350 EXPECT_TRUE(IsSpokenFeedbackEnabled());
352 // Sets the pref as true to enable high contrast mode.
353 SetHighContrastEnabledPref(true);
354 // Confirms that the high contrast mode is enabled.
355 EXPECT_TRUE(IsHighContrastEnabled());
357 // Sets the pref as true to enable autoclick.
358 SetAutoclickEnabledPref(true);
359 // Confirms that autoclick is enabled.
360 EXPECT_TRUE(IsAutoclickEnabled());
362 // Set autoclick delay pref.
363 SetAutoclickDelayPref(kTestAutoclickDelayMs
);
364 // Confirm that the correct value is set.
365 EXPECT_EQ(kTestAutoclickDelayMs
, GetAutoclickDelay());
367 SetLargeCursorEnabledPref(false);
368 EXPECT_FALSE(IsLargeCursorEnabled());
370 SetSpokenFeedbackEnabledPref(false);
371 EXPECT_FALSE(IsSpokenFeedbackEnabled());
373 SetHighContrastEnabledPref(false);
374 EXPECT_FALSE(IsHighContrastEnabled());
376 SetAutoclickEnabledPref(false);
377 EXPECT_FALSE(IsAutoclickEnabled());
380 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest
, ResumeSavedPref
) {
381 // Loads the profile of the user.
382 UserManager::Get()->UserLoggedIn(kTestUserName
, kTestUserName
, true);
384 // Sets the pref to enable large cursor before login.
385 SetLargeCursorEnabledPref(true);
386 EXPECT_FALSE(IsLargeCursorEnabled());
388 // Sets the pref to enable spoken feedback before login.
389 SetSpokenFeedbackEnabledPref(true);
390 EXPECT_FALSE(IsSpokenFeedbackEnabled());
392 // Sets the pref to enable high contrast before login.
393 SetHighContrastEnabledPref(true);
394 EXPECT_FALSE(IsHighContrastEnabled());
396 // Sets the pref to enable autoclick before login.
397 SetAutoclickEnabledPref(true);
398 EXPECT_FALSE(IsAutoclickEnabled());
400 // Sets the autoclick delay pref before login but the
401 // initial value should not change.
402 SetAutoclickDelayPref(kTestAutoclickDelayMs
);
403 EXPECT_EQ(default_autoclick_delay(), GetAutoclickDelay());
406 UserManager::Get()->SessionStarted();
408 // Confirms that features are enabled by restring from pref just after login.
409 EXPECT_TRUE(IsLargeCursorEnabled());
410 EXPECT_TRUE(IsSpokenFeedbackEnabled());
411 EXPECT_TRUE(IsHighContrastEnabled());
412 EXPECT_TRUE(IsAutoclickEnabled());
413 EXPECT_EQ(kTestAutoclickDelayMs
, GetAutoclickDelay());
416 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest
,
417 ChangingTypeInvokesNotification
) {
418 MockAccessibilityObserver observer
;
421 UserManager::Get()->UserLoggedIn(kTestUserName
, kTestUserName
, true);
422 UserManager::Get()->SessionStarted();
424 EXPECT_FALSE(observer
.observed());
427 SetSpokenFeedbackEnabled(true);
428 EXPECT_TRUE(observer
.observed());
429 EXPECT_TRUE(observer
.observed_enabled());
430 EXPECT_EQ(observer
.observed_type(),
431 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
);
432 EXPECT_TRUE(IsSpokenFeedbackEnabled());
435 SetSpokenFeedbackEnabled(false);
436 EXPECT_TRUE(observer
.observed());
437 EXPECT_FALSE(observer
.observed_enabled());
438 EXPECT_EQ(observer
.observed_type(),
439 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
);
440 EXPECT_FALSE(IsSpokenFeedbackEnabled());
443 SetHighContrastEnabled(true);
444 EXPECT_TRUE(observer
.observed());
445 EXPECT_TRUE(observer
.observed_enabled());
446 EXPECT_EQ(observer
.observed_type(),
447 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE
);
448 EXPECT_TRUE(IsHighContrastEnabled());
451 SetHighContrastEnabled(false);
452 EXPECT_TRUE(observer
.observed());
453 EXPECT_FALSE(observer
.observed_enabled());
454 EXPECT_EQ(observer
.observed_type(),
455 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE
);
456 EXPECT_FALSE(IsHighContrastEnabled());
459 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest
,
460 ChangingTypePrefInvokesNotification
) {
461 MockAccessibilityObserver observer
;
464 UserManager::Get()->UserLoggedIn(kTestUserName
, kTestUserName
, true);
465 UserManager::Get()->SessionStarted();
467 EXPECT_FALSE(observer
.observed());
470 SetSpokenFeedbackEnabledPref(true);
471 EXPECT_TRUE(observer
.observed());
472 EXPECT_TRUE(observer
.observed_enabled());
473 EXPECT_EQ(observer
.observed_type(),
474 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
);
475 EXPECT_TRUE(IsSpokenFeedbackEnabled());
478 SetSpokenFeedbackEnabledPref(false);
479 EXPECT_TRUE(observer
.observed());
480 EXPECT_FALSE(observer
.observed_enabled());
481 EXPECT_EQ(observer
.observed_type(),
482 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
);
483 EXPECT_FALSE(IsSpokenFeedbackEnabled());
486 SetHighContrastEnabledPref(true);
487 EXPECT_TRUE(observer
.observed());
488 EXPECT_TRUE(observer
.observed_enabled());
489 EXPECT_EQ(observer
.observed_type(),
490 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE
);
491 EXPECT_TRUE(IsHighContrastEnabled());
494 SetHighContrastEnabledPref(false);
495 EXPECT_TRUE(observer
.observed());
496 EXPECT_FALSE(observer
.observed_enabled());
497 EXPECT_EQ(observer
.observed_type(),
498 chrome::NOTIFICATION_CROS_ACCESSIBILITY_TOGGLE_HIGH_CONTRAST_MODE
);
499 EXPECT_FALSE(IsHighContrastEnabled());
502 class AccessibilityManagerUserTypeTest
503 : public AccessibilityManagerTest
,
504 public ::testing::WithParamInterface
<const char*> {
506 AccessibilityManagerUserTypeTest() {}
507 virtual ~AccessibilityManagerUserTypeTest() {}
509 DISALLOW_COPY_AND_ASSIGN(AccessibilityManagerUserTypeTest
);
512 // TODO(yoshiki): Enable a test for retail mode.
513 INSTANTIATE_TEST_CASE_P(
514 UserTypeInstantiation
,
515 AccessibilityManagerUserTypeTest
,
516 ::testing::Values(kTestUserName
,
517 UserManager::kGuestUserName
,
518 //UserManager::kRetailModeUserName,
519 kTestLocallyManagedUserName
));
521 IN_PROC_BROWSER_TEST_P(AccessibilityManagerUserTypeTest
,
522 EnableOnLoginScreenAndLogin
) {
523 // Enables large cursor.
524 SetLargeCursorEnabled(true);
525 EXPECT_TRUE(IsLargeCursorEnabled());
526 // Enables spoken feedback.
527 SetSpokenFeedbackEnabled(true);
528 EXPECT_TRUE(IsSpokenFeedbackEnabled());
529 // Enables high contrast.
530 SetHighContrastEnabled(true);
531 EXPECT_TRUE(IsHighContrastEnabled());
532 // Enables autoclick.
533 SetAutoclickEnabled(true);
534 EXPECT_TRUE(IsAutoclickEnabled());
535 // Set autoclick delay.
536 SetAutoclickDelay(kTestAutoclickDelayMs
);
537 EXPECT_EQ(kTestAutoclickDelayMs
, GetAutoclickDelay());
540 const char* user_name
= GetParam();
541 UserManager::Get()->UserLoggedIn(user_name
, user_name
, true);
543 // Confirms that the features are still enabled just after login.
544 EXPECT_TRUE(IsLargeCursorEnabled());
545 EXPECT_TRUE(IsSpokenFeedbackEnabled());
546 EXPECT_TRUE(IsHighContrastEnabled());
547 EXPECT_TRUE(IsAutoclickEnabled());
548 EXPECT_EQ(kTestAutoclickDelayMs
, GetAutoclickDelay());
550 UserManager::Get()->SessionStarted();
552 // Confirms that the features keep enabled after session starts.
553 EXPECT_TRUE(IsLargeCursorEnabled());
554 EXPECT_TRUE(IsSpokenFeedbackEnabled());
555 EXPECT_TRUE(IsHighContrastEnabled());
556 EXPECT_TRUE(IsAutoclickEnabled());
557 EXPECT_EQ(kTestAutoclickDelayMs
, GetAutoclickDelay());
559 // Confirms that the prefs have been copied to the user's profile.
560 EXPECT_TRUE(GetLargeCursorEnabledFromPref());
561 EXPECT_TRUE(GetSpokenFeedbackEnabledFromPref());
562 EXPECT_TRUE(GetHighContrastEnabledFromPref());
563 EXPECT_TRUE(GetAutoclickEnabledFromPref());
564 EXPECT_EQ(kTestAutoclickDelayMs
, GetAutoclickDelayFromPref());
567 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest
, AcessibilityMenuVisibility
) {
569 UserManager::Get()->UserLoggedIn(kTestUserName
, kTestUserName
, true);
570 UserManager::Get()->SessionStarted();
572 // Confirms that the features are disabled.
573 EXPECT_FALSE(IsLargeCursorEnabled());
574 EXPECT_FALSE(IsSpokenFeedbackEnabled());
575 EXPECT_FALSE(IsHighContrastEnabled());
576 EXPECT_FALSE(IsAutoclickEnabled());
577 EXPECT_FALSE(ShouldShowAccessibilityMenu());
579 // Check large cursor.
580 SetLargeCursorEnabled(true);
581 EXPECT_TRUE(ShouldShowAccessibilityMenu());
582 SetLargeCursorEnabled(false);
583 EXPECT_FALSE(ShouldShowAccessibilityMenu());
585 // Check spoken feedback.
586 SetSpokenFeedbackEnabled(true);
587 EXPECT_TRUE(ShouldShowAccessibilityMenu());
588 SetSpokenFeedbackEnabled(false);
589 EXPECT_FALSE(ShouldShowAccessibilityMenu());
591 // Check high contrast.
592 SetHighContrastEnabled(true);
593 EXPECT_TRUE(ShouldShowAccessibilityMenu());
594 SetHighContrastEnabled(false);
595 EXPECT_FALSE(ShouldShowAccessibilityMenu());
598 SetAutoclickEnabled(true);
599 EXPECT_TRUE(ShouldShowAccessibilityMenu());
600 SetAutoclickEnabled(false);
601 EXPECT_FALSE(ShouldShowAccessibilityMenu());
604 } // namespace chromeos