1 // Copyright (c) 2012 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 "ash/magnifier/magnification_controller.h" 8 #include "ash/shell.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/accessibility_manager.h" 14 #include "chrome/browser/chromeos/accessibility/magnification_manager.h" 15 #include "chrome/browser/chromeos/login/helper.h" 16 #include "chrome/browser/chromeos/login/login_utils.h" 17 #include "chrome/browser/chromeos/login/users/user_manager.h" 18 #include "chrome/browser/chromeos/login/users/user_manager_impl.h" 19 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile_manager.h" 21 #include "chrome/common/chrome_switches.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 "components/user_prefs/user_prefs.h" 27 #include "content/public/browser/notification_details.h" 28 #include "content/public/browser/notification_service.h" 29 #include "testing/gtest/include/gtest/gtest.h" 30 31 namespace chromeos { 32 33 namespace { 34 35 const char kTestUserName[] = "owner (at) invalid.domain"; 36 37 void SetMagnifierEnabled(bool enabled) { 38 MagnificationManager::Get()->SetMagnifierEnabled(enabled); 39 } 40 41 void SetMagnifierType(ash::MagnifierType type) { 42 MagnificationManager::Get()->SetMagnifierType(type); 43 } 44 45 void SetFullScreenMagnifierScale(double scale) { 46 ash::Shell::GetInstance()-> 47 magnification_controller()->SetScale(scale, false); 48 } 49 50 double GetFullScreenMagnifierScale() { 51 return ash::Shell::GetInstance()->magnification_controller()->GetScale(); 52 } 53 54 void SetSavedFullScreenMagnifierScale(double scale) { 55 MagnificationManager::Get()->SaveScreenMagnifierScale(scale); 56 } 57 58 double GetSavedFullScreenMagnifierScale() { 59 return MagnificationManager::Get()->GetSavedScreenMagnifierScale(); 60 } 61 62 ash::MagnifierType GetMagnifierType() { 63 return MagnificationManager::Get()->GetMagnifierType(); 64 } 65 66 bool IsMagnifierEnabled() { 67 return MagnificationManager::Get()->IsMagnifierEnabled(); 68 } 69 70 Profile* profile() { 71 Profile* profile = ProfileManager::GetActiveUserProfile(); 72 DCHECK(profile); 73 return profile; 74 } 75 76 PrefService* prefs() { 77 return user_prefs::UserPrefs::Get(profile()); 78 } 79 80 void SetScreenMagnifierEnabledPref(bool enabled) { 81 prefs()->SetBoolean(prefs::kAccessibilityScreenMagnifierEnabled, enabled); 82 } 83 84 void SetScreenMagnifierTypePref(ash::MagnifierType type) { 85 prefs()->SetInteger(prefs::kAccessibilityScreenMagnifierType, type); 86 } 87 88 void SetFullScreenMagnifierScalePref(double scale) { 89 prefs()->SetDouble(prefs::kAccessibilityScreenMagnifierScale, scale); 90 } 91 92 bool GetScreenMagnifierEnabledFromPref() { 93 return prefs()->GetBoolean(prefs::kAccessibilityScreenMagnifierEnabled); 94 } 95 96 // Creates and logs into a profile with account |name|, and makes sure that 97 // the profile is regarded as "non new" in the next login. This is used in 98 // PRE_XXX cases so that in the main XXX case we can test non new profiles. 99 void PrepareNonNewProfile(const std::string& name) { 100 UserManager::Get()->UserLoggedIn(name, name, true); 101 // To prepare a non-new profile for tests, we must ensure the profile 102 // directory and the preference files are created, because that's what 103 // Profile::IsNewProfile() checks. UserLoggedIn(), however, does not yet 104 // create the profile directory until GetActiveUserProfile() is called. 105 ProfileManager::GetActiveUserProfile(); 106 } 107 108 } // namespace 109 110 class MockMagnificationObserver { 111 public: 112 MockMagnificationObserver() : observed_(false), 113 observed_enabled_(false), 114 magnifier_type_(-1) 115 { 116 AccessibilityManager* accessibility_manager = AccessibilityManager::Get(); 117 CHECK(accessibility_manager); 118 accessibility_subscription_ = accessibility_manager->RegisterCallback( 119 base::Bind(&MockMagnificationObserver::OnAccessibilityStatusChanged, 120 base::Unretained(this))); 121 } 122 123 virtual ~MockMagnificationObserver() {} 124 125 bool observed() const { return observed_; } 126 bool observed_enabled() const { return observed_enabled_; } 127 int magnifier_type() const { return magnifier_type_; } 128 129 void reset() { observed_ = false; } 130 131 private: 132 void OnAccessibilityStatusChanged( 133 const AccessibilityStatusEventDetails& details) { 134 if (details.notification_type == ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER) { 135 magnifier_type_ = details.magnifier_type; 136 observed_enabled_ = details.enabled; 137 observed_ = true; 138 } 139 } 140 141 bool observed_; 142 bool observed_enabled_; 143 int magnifier_type_; 144 145 scoped_ptr<AccessibilityStatusSubscription> accessibility_subscription_; 146 147 DISALLOW_COPY_AND_ASSIGN(MockMagnificationObserver); 148 }; 149 150 151 class MagnificationManagerTest : public InProcessBrowserTest { 152 protected: 153 MagnificationManagerTest() {} 154 virtual ~MagnificationManagerTest() {} 155 156 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 157 command_line->AppendSwitch(switches::kLoginManager); 158 command_line->AppendSwitchASCII(switches::kLoginProfile, 159 TestingProfile::kTestUserProfileDir); 160 } 161 162 virtual void SetUpOnMainThread() OVERRIDE { 163 // Set the login-screen profile. 164 MagnificationManager::Get()->SetProfileForTest( 165 ProfileManager::GetActiveUserProfile()); 166 } 167 168 DISALLOW_COPY_AND_ASSIGN(MagnificationManagerTest); 169 }; 170 171 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginOffToOff) { 172 // Create a new profile once, to run the test with non-new profile. 173 PrepareNonNewProfile(kTestUserName); 174 175 // Sets pref to explicitly disable the magnifier. 176 SetScreenMagnifierEnabledPref(false); 177 } 178 179 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginOffToOff) { 180 // Confirms that magnifier is disabled on the login screen. 181 EXPECT_FALSE(IsMagnifierEnabled()); 182 183 // Disables magnifier on login screen. 184 SetMagnifierEnabled(false); 185 EXPECT_FALSE(IsMagnifierEnabled()); 186 187 // Logs in with existing profile. 188 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 189 190 // Confirms that magnifier is still disabled just after login. 191 EXPECT_FALSE(IsMagnifierEnabled()); 192 193 UserManager::Get()->SessionStarted(); 194 195 // Confirms that magnifier is still disabled just after session starts. 196 EXPECT_FALSE(IsMagnifierEnabled()); 197 198 // Enables magnifier. 199 SetMagnifierEnabled(true); 200 // Confirms that magnifier is enabled. 201 EXPECT_TRUE(IsMagnifierEnabled()); 202 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 203 EXPECT_TRUE(GetScreenMagnifierEnabledFromPref()); 204 } 205 206 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToOff) { 207 // Create a new profile once, to run the test with non-new profile. 208 PrepareNonNewProfile(kTestUserName); 209 210 // Sets pref to explicitly disable the magnifier. 211 SetScreenMagnifierEnabledPref(false); 212 } 213 214 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginFullToOff) { 215 // Confirms that magnifier is disabled on the login screen. 216 EXPECT_FALSE(IsMagnifierEnabled()); 217 218 // Enables magnifier on login screen. 219 SetMagnifierEnabled(true); 220 SetMagnifierType(ash::MAGNIFIER_FULL); 221 SetFullScreenMagnifierScale(2.5); 222 EXPECT_TRUE(IsMagnifierEnabled()); 223 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 224 EXPECT_EQ(2.5, GetFullScreenMagnifierScale()); 225 226 // Logs in (but the session is not started yet). 227 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 228 229 // Confirms that magnifier is keeping enabled. 230 EXPECT_TRUE(IsMagnifierEnabled()); 231 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 232 233 UserManager::Get()->SessionStarted(); 234 235 // Confirms that magnifier is disabled just after session start. 236 EXPECT_FALSE(IsMagnifierEnabled()); 237 EXPECT_FALSE(GetScreenMagnifierEnabledFromPref()); 238 } 239 240 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginOffToFull) { 241 // Create a new profile once, to run the test with non-new profile. 242 PrepareNonNewProfile(kTestUserName); 243 244 // Sets prefs to explicitly enable the magnifier. 245 SetScreenMagnifierEnabledPref(true); 246 SetScreenMagnifierTypePref(ash::MAGNIFIER_FULL); 247 SetFullScreenMagnifierScalePref(2.5); 248 } 249 250 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginOffToFull) { 251 // Disables magnifier on login screen. 252 SetMagnifierEnabled(false); 253 EXPECT_FALSE(IsMagnifierEnabled()); 254 255 // Logs in (but the session is not started yet). 256 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 257 258 // Confirms that magnifier is keeping disabled. 259 EXPECT_FALSE(IsMagnifierEnabled()); 260 261 UserManager::Get()->SessionStarted(); 262 263 // Confirms that the magnifier is enabled and configured according to the 264 // explicitly set prefs just after session start. 265 EXPECT_TRUE(IsMagnifierEnabled()); 266 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 267 EXPECT_EQ(2.5, GetFullScreenMagnifierScale()); 268 EXPECT_TRUE(GetScreenMagnifierEnabledFromPref()); 269 } 270 271 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToFull) { 272 // Create a new profile once, to run the test with non-new profile. 273 PrepareNonNewProfile(kTestUserName); 274 275 // Sets prefs to explicitly enable the magnifier. 276 SetScreenMagnifierEnabledPref(true); 277 SetScreenMagnifierTypePref(ash::MAGNIFIER_FULL); 278 SetFullScreenMagnifierScalePref(2.5); 279 } 280 281 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginFullToFull) { 282 // Enables magnifier on login screen. 283 SetMagnifierType(ash::MAGNIFIER_FULL); 284 SetMagnifierEnabled(true); 285 SetFullScreenMagnifierScale(3.0); 286 EXPECT_TRUE(IsMagnifierEnabled()); 287 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 288 EXPECT_EQ(3.0, GetFullScreenMagnifierScale()); 289 290 // Logs in (but the session is not started yet). 291 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 292 293 // Confirms that magnifier is keeping enabled. 294 EXPECT_TRUE(IsMagnifierEnabled()); 295 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 296 297 UserManager::Get()->SessionStarted(); 298 299 // Confirms that the magnifier is enabled and configured according to the 300 // explicitly set prefs just after session start. 301 EXPECT_TRUE(IsMagnifierEnabled()); 302 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 303 EXPECT_EQ(2.5, GetFullScreenMagnifierScale()); 304 EXPECT_TRUE(GetScreenMagnifierEnabledFromPref()); 305 } 306 307 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, PRE_LoginFullToUnset) { 308 // Creates a new profile once, to run the test with non-new profile. 309 PrepareNonNewProfile(kTestUserName); 310 } 311 312 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginFullToUnset) { 313 // Enables full screen magnifier. 314 SetMagnifierType(ash::MAGNIFIER_FULL); 315 SetMagnifierEnabled(true); 316 EXPECT_TRUE(IsMagnifierEnabled()); 317 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 318 319 // Logs in (but the session is not started yet). 320 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 321 322 // Confirms that magnifier is keeping enabled. 323 EXPECT_TRUE(IsMagnifierEnabled()); 324 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 325 326 UserManager::Get()->SessionStarted(); 327 328 // Confirms that magnifier is disabled. 329 EXPECT_FALSE(IsMagnifierEnabled()); 330 EXPECT_FALSE(GetScreenMagnifierEnabledFromPref()); 331 } 332 333 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserOff) { 334 // Confirms that magnifier is disabled on the login screen. 335 EXPECT_FALSE(IsMagnifierEnabled()); 336 337 // Disables magnifier on login screen explicitly. 338 SetMagnifierEnabled(false); 339 340 // Logs in (but the session is not started yet). 341 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 342 343 // Confirms that magnifier is keeping disabled. 344 EXPECT_FALSE(IsMagnifierEnabled()); 345 346 UserManager::Get()->SessionStarted(); 347 348 // Confirms that magnifier is keeping disabled. 349 EXPECT_FALSE(IsMagnifierEnabled()); 350 EXPECT_FALSE(GetScreenMagnifierEnabledFromPref()); 351 } 352 353 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserFull) { 354 // Enables magnifier on login screen. 355 SetMagnifierType(ash::MAGNIFIER_FULL); 356 SetMagnifierEnabled(true); 357 SetFullScreenMagnifierScale(2.5); 358 EXPECT_TRUE(IsMagnifierEnabled()); 359 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 360 EXPECT_EQ(2.5, GetFullScreenMagnifierScale()); 361 362 // Logs in (but the session is not started yet). 363 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 364 365 // Confirms that magnifier is keeping enabled. 366 EXPECT_TRUE(IsMagnifierEnabled()); 367 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 368 369 UserManager::Get()->SessionStarted(); 370 371 // Confirms that magnifier keeps enabled. 372 EXPECT_TRUE(IsMagnifierEnabled()); 373 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 374 EXPECT_EQ(2.5, GetFullScreenMagnifierScale()); 375 EXPECT_TRUE(GetScreenMagnifierEnabledFromPref()); 376 } 377 378 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, LoginAsNewUserUnset) { 379 // Confirms that magnifier is disabled on the login screen. 380 EXPECT_FALSE(IsMagnifierEnabled()); 381 382 // Logs in (but the session is not started yet). 383 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 384 385 // Confirms that magnifier is keeping disabled. 386 EXPECT_FALSE(IsMagnifierEnabled()); 387 388 UserManager::Get()->SessionStarted(); 389 390 // Confirms that magnifier is keeping disabled. 391 EXPECT_FALSE(IsMagnifierEnabled()); 392 EXPECT_FALSE(GetScreenMagnifierEnabledFromPref()); 393 } 394 395 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, ChangeMagnifierType) { 396 // Enables/disables full screen magnifier. 397 SetMagnifierEnabled(false); 398 SetMagnifierType(ash::MAGNIFIER_FULL); 399 EXPECT_FALSE(IsMagnifierEnabled()); 400 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 401 402 SetMagnifierEnabled(true); 403 EXPECT_TRUE(IsMagnifierEnabled()); 404 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 405 406 SetMagnifierEnabled(false); 407 EXPECT_FALSE(IsMagnifierEnabled()); 408 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 409 410 // Enables/disables partial screen magnifier. 411 SetMagnifierType(ash::MAGNIFIER_PARTIAL); 412 EXPECT_FALSE(IsMagnifierEnabled()); 413 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 414 415 SetMagnifierEnabled(true); 416 EXPECT_TRUE(IsMagnifierEnabled()); 417 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 418 419 SetMagnifierEnabled(false); 420 EXPECT_FALSE(IsMagnifierEnabled()); 421 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 422 423 // Changes the magnifier type when the magnifier is enabled. 424 SetMagnifierType(ash::MAGNIFIER_FULL); 425 SetMagnifierEnabled(true); 426 EXPECT_TRUE(IsMagnifierEnabled()); 427 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 428 429 SetMagnifierType(ash::MAGNIFIER_PARTIAL); 430 EXPECT_TRUE(IsMagnifierEnabled()); 431 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 432 433 SetMagnifierType(ash::MAGNIFIER_FULL); 434 EXPECT_TRUE(IsMagnifierEnabled()); 435 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 436 437 // Changes the magnifier type when the magnifier is disabled. 438 SetMagnifierEnabled(false); 439 SetMagnifierType(ash::MAGNIFIER_FULL); 440 EXPECT_FALSE(IsMagnifierEnabled()); 441 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 442 443 SetMagnifierType(ash::MAGNIFIER_PARTIAL); 444 EXPECT_FALSE(IsMagnifierEnabled()); 445 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 446 447 SetMagnifierType(ash::MAGNIFIER_FULL); 448 EXPECT_FALSE(IsMagnifierEnabled()); 449 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 450 } 451 452 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, TypePref) { 453 // Logs in 454 UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true); 455 UserManager::Get()->SessionStarted(); 456 457 // Confirms that magnifier is disabled just after login. 458 EXPECT_FALSE(IsMagnifierEnabled()); 459 460 // Sets the pref as true to enable magnifier. 461 SetScreenMagnifierTypePref(ash::MAGNIFIER_FULL); 462 SetScreenMagnifierEnabledPref(true); 463 // Confirms that magnifier is enabled. 464 EXPECT_TRUE(IsMagnifierEnabled()); 465 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 466 } 467 468 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, ScalePref) { 469 SetMagnifierEnabled(false); 470 EXPECT_FALSE(IsMagnifierEnabled()); 471 472 // Sets 2.5x to the pref. 473 SetSavedFullScreenMagnifierScale(2.5); 474 475 // Enables full screen magnifier. 476 SetMagnifierType(ash::MAGNIFIER_FULL); 477 SetMagnifierEnabled(true); 478 EXPECT_TRUE(IsMagnifierEnabled()); 479 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 480 481 // Confirms that 2.5x is restored. 482 EXPECT_EQ(2.5, GetFullScreenMagnifierScale()); 483 484 // Sets the scale and confirms that the scale is saved to pref. 485 SetFullScreenMagnifierScale(3.0); 486 EXPECT_EQ(3.0, GetSavedFullScreenMagnifierScale()); 487 } 488 489 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, InvalidScalePref) { 490 // TEST 1: Sets too small scale 491 SetMagnifierEnabled(false); 492 EXPECT_FALSE(IsMagnifierEnabled()); 493 494 // Sets too small value to the pref. 495 SetSavedFullScreenMagnifierScale(0.5); 496 497 // Enables full screen magnifier. 498 SetMagnifierType(ash::MAGNIFIER_FULL); 499 SetMagnifierEnabled(true); 500 EXPECT_TRUE(IsMagnifierEnabled()); 501 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 502 503 // Confirms that the actual scale is set to the minimum scale. 504 EXPECT_EQ(1.0, GetFullScreenMagnifierScale()); 505 506 // TEST 2: Sets too large scale 507 SetMagnifierEnabled(false); 508 EXPECT_FALSE(IsMagnifierEnabled()); 509 510 // Sets too large value to the pref. 511 SetSavedFullScreenMagnifierScale(50.0); 512 513 // Enables full screen magnifier. 514 SetMagnifierEnabled(true); 515 EXPECT_TRUE(IsMagnifierEnabled()); 516 EXPECT_EQ(ash::MAGNIFIER_FULL, GetMagnifierType()); 517 518 // Confirms that the actual scale is set to the maximum scale. 519 EXPECT_EQ(4.0, GetFullScreenMagnifierScale()); 520 } 521 522 IN_PROC_BROWSER_TEST_F(MagnificationManagerTest, 523 ChangingTypeInvokesNotification) { 524 MockMagnificationObserver observer; 525 526 EXPECT_FALSE(observer.observed()); 527 528 // Set full screen magnifier, and confirm the observer is called. 529 SetMagnifierEnabled(true); 530 SetMagnifierType(ash::MAGNIFIER_FULL); 531 EXPECT_TRUE(observer.observed()); 532 EXPECT_TRUE(observer.observed_enabled()); 533 EXPECT_EQ(observer.magnifier_type(), ash::MAGNIFIER_FULL); 534 EXPECT_EQ(GetMagnifierType(), ash::MAGNIFIER_FULL); 535 observer.reset(); 536 537 // Set full screen magnifier again, and confirm the observer is not called. 538 SetMagnifierType(ash::MAGNIFIER_FULL); 539 EXPECT_FALSE(observer.observed()); 540 EXPECT_EQ(GetMagnifierType(), ash::MAGNIFIER_FULL); 541 observer.reset(); 542 } 543 544 } // namespace chromeos 545