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 "base/basictypes.h" 6 #include "base/strings/utf_string_conversions.h" 7 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/extensions/app_sync_data.h" 9 #include "chrome/browser/extensions/bookmark_app_helper.h" 10 #include "chrome/browser/extensions/extension_service.h" 11 #include "chrome/browser/extensions/extension_sync_service.h" 12 #include "chrome/browser/extensions/launch_util.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/sync/test/integration/apps_helper.h" 15 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" 16 #include "chrome/browser/sync/test/integration/sync_app_helper.h" 17 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" 18 #include "chrome/browser/sync/test/integration/sync_test.h" 19 #include "chrome/common/extensions/extension_constants.h" 20 #include "content/public/browser/notification_service.h" 21 #include "content/public/test/test_utils.h" 22 #include "extensions/browser/app_sorting.h" 23 #include "extensions/browser/extension_prefs.h" 24 #include "extensions/browser/extension_registry.h" 25 #include "sync/api/string_ordinal.h" 26 27 using apps_helper::AllProfilesHaveSameAppsAsVerifier; 28 using apps_helper::CopyNTPOrdinals; 29 using apps_helper::DisableApp; 30 using apps_helper::EnableApp; 31 using apps_helper::FixNTPOrdinalCollisions; 32 using apps_helper::GetAppLaunchOrdinalForApp; 33 using apps_helper::HasSameAppsAsVerifier; 34 using apps_helper::IncognitoDisableApp; 35 using apps_helper::IncognitoEnableApp; 36 using apps_helper::InstallApp; 37 using apps_helper::InstallAppsPendingForSync; 38 using apps_helper::InstallPlatformApp; 39 using apps_helper::SetAppLaunchOrdinalForApp; 40 using apps_helper::SetPageOrdinalForApp; 41 using apps_helper::UninstallApp; 42 using sync_integration_test_util::AwaitCommitActivityCompletion; 43 44 class TwoClientAppsSyncTest : public SyncTest { 45 public: 46 TwoClientAppsSyncTest() : SyncTest(TWO_CLIENT) {} 47 48 virtual ~TwoClientAppsSyncTest() {} 49 50 private: 51 DISALLOW_COPY_AND_ASSIGN(TwoClientAppsSyncTest); 52 }; 53 54 class LegacyTwoClientAppsSyncTest : public SyncTest { 55 public: 56 LegacyTwoClientAppsSyncTest() : SyncTest(TWO_CLIENT_LEGACY) {} 57 58 virtual ~LegacyTwoClientAppsSyncTest() {} 59 60 private: 61 DISALLOW_COPY_AND_ASSIGN(LegacyTwoClientAppsSyncTest); 62 }; 63 64 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, StartWithNoApps) { 65 ASSERT_TRUE(SetupSync()); 66 67 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 68 } 69 70 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, StartWithSameApps) { 71 ASSERT_TRUE(SetupClients()); 72 73 const int kNumApps = 5; 74 for (int i = 0; i < kNumApps; ++i) { 75 InstallApp(GetProfile(0), i); 76 InstallApp(GetProfile(1), i); 77 InstallApp(verifier(), i); 78 } 79 80 ASSERT_TRUE(SetupSync()); 81 82 ASSERT_TRUE(AwaitQuiescence()); 83 84 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 85 } 86 87 // Install some apps on both clients, some on only one client, some on only the 88 // other, and sync. Both clients should end up with all apps, and the app and 89 // page ordinals should be identical. 90 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, StartWithDifferentApps) { 91 ASSERT_TRUE(SetupClients()); 92 93 int i = 0; 94 95 const int kNumCommonApps = 5; 96 for (int j = 0; j < kNumCommonApps; ++i, ++j) { 97 InstallApp(GetProfile(0), i); 98 InstallApp(GetProfile(1), i); 99 InstallApp(verifier(), i); 100 } 101 102 const int kNumProfile0Apps = 10; 103 for (int j = 0; j < kNumProfile0Apps; ++i, ++j) { 104 InstallApp(GetProfile(0), i); 105 InstallApp(verifier(), i); 106 CopyNTPOrdinals(GetProfile(0), verifier(), i); 107 } 108 109 const int kNumProfile1Apps = 10; 110 for (int j = 0; j < kNumProfile1Apps; ++i, ++j) { 111 InstallApp(GetProfile(1), i); 112 InstallApp(verifier(), i); 113 CopyNTPOrdinals(GetProfile(1), verifier(), i); 114 } 115 116 const int kNumPlatformApps = 5; 117 for (int j = 0; j < kNumPlatformApps; ++i, ++j) { 118 InstallPlatformApp(GetProfile(1), i); 119 InstallPlatformApp(verifier(), i); 120 CopyNTPOrdinals(GetProfile(1), verifier(), i); 121 } 122 123 FixNTPOrdinalCollisions(verifier()); 124 125 ASSERT_TRUE(SetupSync()); 126 127 ASSERT_TRUE(AwaitQuiescence()); 128 129 InstallAppsPendingForSync(GetProfile(0)); 130 InstallAppsPendingForSync(GetProfile(1)); 131 132 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 133 } 134 135 // Install some apps on both clients, then sync. Then install some apps on only 136 // one client, some on only the other, and then sync again. Both clients should 137 // end up with all apps, and the app and page ordinals should be identical. 138 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, InstallDifferentApps) { 139 ASSERT_TRUE(SetupClients()); 140 141 int i = 0; 142 143 const int kNumCommonApps = 5; 144 for (int j = 0; j < kNumCommonApps; ++i, ++j) { 145 InstallApp(GetProfile(0), i); 146 InstallApp(GetProfile(1), i); 147 InstallApp(verifier(), i); 148 } 149 150 ASSERT_TRUE(SetupSync()); 151 152 ASSERT_TRUE(AwaitQuiescence()); 153 154 const int kNumProfile0Apps = 10; 155 for (int j = 0; j < kNumProfile0Apps; ++i, ++j) { 156 InstallApp(GetProfile(0), i); 157 InstallApp(verifier(), i); 158 CopyNTPOrdinals(GetProfile(0), verifier(), i); 159 } 160 161 const int kNumProfile1Apps = 10; 162 for (int j = 0; j < kNumProfile1Apps; ++i, ++j) { 163 InstallApp(GetProfile(1), i); 164 InstallApp(verifier(), i); 165 CopyNTPOrdinals(GetProfile(1), verifier(), i); 166 } 167 168 FixNTPOrdinalCollisions(verifier()); 169 170 ASSERT_TRUE(AwaitQuiescence()); 171 172 InstallAppsPendingForSync(GetProfile(0)); 173 InstallAppsPendingForSync(GetProfile(1)); 174 175 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 176 } 177 178 // TCM ID - 3711279. 179 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, Add) { 180 ASSERT_TRUE(SetupSync()); 181 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 182 183 InstallApp(GetProfile(0), 0); 184 InstallApp(verifier(), 0); 185 ASSERT_TRUE(AwaitQuiescence()); 186 187 InstallAppsPendingForSync(GetProfile(0)); 188 InstallAppsPendingForSync(GetProfile(1)); 189 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 190 } 191 192 // TCM ID - 3706267. 193 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, Uninstall) { 194 ASSERT_TRUE(SetupSync()); 195 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 196 197 InstallApp(GetProfile(0), 0); 198 InstallApp(verifier(), 0); 199 ASSERT_TRUE(AwaitQuiescence()); 200 201 InstallAppsPendingForSync(GetProfile(0)); 202 InstallAppsPendingForSync(GetProfile(1)); 203 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 204 205 UninstallApp(GetProfile(0), 0); 206 UninstallApp(verifier(), 0); 207 ASSERT_TRUE(AwaitQuiescence()); 208 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 209 } 210 211 // Install an app on one client, then sync. Then uninstall the app on the first 212 // client and sync again. Now install a new app on the first client and sync. 213 // Both client should only have the second app, with identical app and page 214 // ordinals. 215 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UninstallThenInstall) { 216 ASSERT_TRUE(SetupSync()); 217 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 218 219 InstallApp(GetProfile(0), 0); 220 InstallApp(verifier(), 0); 221 ASSERT_TRUE(AwaitQuiescence()); 222 223 InstallAppsPendingForSync(GetProfile(0)); 224 InstallAppsPendingForSync(GetProfile(1)); 225 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 226 227 UninstallApp(GetProfile(0), 0); 228 UninstallApp(verifier(), 0); 229 ASSERT_TRUE(AwaitQuiescence()); 230 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 231 232 InstallApp(GetProfile(0), 1); 233 InstallApp(verifier(), 1); 234 ASSERT_TRUE(AwaitQuiescence()); 235 InstallAppsPendingForSync(GetProfile(0)); 236 InstallAppsPendingForSync(GetProfile(1)); 237 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 238 } 239 240 // TCM ID - 3699295. 241 // Flaky: http://crbug.com/226055 242 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, DISABLED_Merge) { 243 ASSERT_TRUE(SetupSync()); 244 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 245 246 InstallApp(GetProfile(0), 0); 247 InstallApp(GetProfile(1), 0); 248 ASSERT_TRUE(AwaitQuiescence()); 249 250 UninstallApp(GetProfile(0), 0); 251 InstallApp(GetProfile(0), 1); 252 InstallApp(verifier(), 1); 253 254 InstallApp(GetProfile(0), 2); 255 InstallApp(GetProfile(1), 2); 256 InstallApp(verifier(), 2); 257 258 InstallApp(GetProfile(1), 3); 259 InstallApp(verifier(), 3); 260 261 ASSERT_TRUE(AwaitQuiescence()); 262 InstallAppsPendingForSync(GetProfile(0)); 263 InstallAppsPendingForSync(GetProfile(1)); 264 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 265 } 266 267 // TCM ID - 7723126. 268 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateEnableDisableApp) { 269 ASSERT_TRUE(SetupSync()); 270 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 271 272 InstallApp(GetProfile(0), 0); 273 InstallApp(GetProfile(1), 0); 274 InstallApp(verifier(), 0); 275 ASSERT_TRUE(AwaitQuiescence()); 276 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 277 278 DisableApp(GetProfile(0), 0); 279 DisableApp(verifier(), 0); 280 ASSERT_TRUE(HasSameAppsAsVerifier(0)); 281 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 282 283 ASSERT_TRUE(AwaitQuiescence()); 284 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 285 286 EnableApp(GetProfile(1), 0); 287 EnableApp(verifier(), 0); 288 ASSERT_TRUE(HasSameAppsAsVerifier(1)); 289 ASSERT_FALSE(HasSameAppsAsVerifier(0)); 290 291 ASSERT_TRUE(AwaitQuiescence()); 292 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 293 } 294 295 // TCM ID - 7706637. 296 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateIncognitoEnableDisable) { 297 ASSERT_TRUE(SetupSync()); 298 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 299 300 InstallApp(GetProfile(0), 0); 301 InstallApp(GetProfile(1), 0); 302 InstallApp(verifier(), 0); 303 ASSERT_TRUE(AwaitQuiescence()); 304 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 305 306 IncognitoEnableApp(GetProfile(0), 0); 307 IncognitoEnableApp(verifier(), 0); 308 ASSERT_TRUE(HasSameAppsAsVerifier(0)); 309 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 310 311 ASSERT_TRUE(AwaitQuiescence()); 312 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 313 314 IncognitoDisableApp(GetProfile(1), 0); 315 IncognitoDisableApp(verifier(), 0); 316 ASSERT_TRUE(HasSameAppsAsVerifier(1)); 317 ASSERT_FALSE(HasSameAppsAsVerifier(0)); 318 319 ASSERT_TRUE(AwaitQuiescence()); 320 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 321 } 322 323 // TCM ID - 3718276. 324 IN_PROC_BROWSER_TEST_F(LegacyTwoClientAppsSyncTest, DisableApps) { 325 ASSERT_TRUE(SetupSync()); 326 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 327 328 ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::APPS)); 329 InstallApp(GetProfile(0), 0); 330 InstallApp(verifier(), 0); 331 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 332 ASSERT_TRUE(HasSameAppsAsVerifier(0)); 333 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 334 335 ASSERT_TRUE(GetClient(1)->EnableSyncForDatatype(syncer::APPS)); 336 ASSERT_TRUE(AwaitQuiescence()); 337 338 InstallAppsPendingForSync(GetProfile(0)); 339 InstallAppsPendingForSync(GetProfile(1)); 340 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 341 } 342 343 // Disable sync for the second client and then install an app on the first 344 // client, then enable sync on the second client. Both clients should have the 345 // same app with identical app and page ordinals. 346 // TCM ID - 3720303. 347 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, DisableSync) { 348 ASSERT_TRUE(SetupSync()); 349 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 350 351 ASSERT_TRUE(GetClient(1)->DisableSyncForAllDatatypes()); 352 InstallApp(GetProfile(0), 0); 353 InstallApp(verifier(), 0); 354 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); 355 ASSERT_TRUE(HasSameAppsAsVerifier(0)); 356 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 357 358 ASSERT_TRUE(GetClient(1)->EnableSyncForAllDatatypes()); 359 ASSERT_TRUE(AwaitQuiescence()); 360 361 InstallAppsPendingForSync(GetProfile(0)); 362 InstallAppsPendingForSync(GetProfile(1)); 363 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 364 } 365 366 // Install the same app on both clients, then sync. Change the page ordinal on 367 // one client and sync. Both clients should have the updated page ordinal for 368 // the app. 369 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdatePageOrdinal) { 370 ASSERT_TRUE(SetupSync()); 371 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 372 373 syncer::StringOrdinal initial_page = 374 syncer::StringOrdinal::CreateInitialOrdinal(); 375 InstallApp(GetProfile(0), 0); 376 InstallApp(GetProfile(1), 0); 377 InstallApp(verifier(), 0); 378 ASSERT_TRUE(AwaitQuiescence()); 379 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 380 381 syncer::StringOrdinal second_page = initial_page.CreateAfter(); 382 SetPageOrdinalForApp(GetProfile(0), 0, second_page); 383 SetPageOrdinalForApp(verifier(), 0, second_page); 384 ASSERT_TRUE(AwaitQuiescence()); 385 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 386 } 387 388 // Install the same app on both clients, then sync. Change the app launch 389 // ordinal on one client and sync. Both clients should have the updated app 390 // launch ordinal for the app. 391 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateAppLaunchOrdinal) { 392 ASSERT_TRUE(SetupSync()); 393 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 394 395 InstallApp(GetProfile(0), 0); 396 InstallApp(GetProfile(1), 0); 397 InstallApp(verifier(), 0); 398 ASSERT_TRUE(AwaitQuiescence()); 399 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 400 401 syncer::StringOrdinal initial_position = 402 GetAppLaunchOrdinalForApp(GetProfile(0), 0); 403 404 syncer::StringOrdinal second_position = initial_position.CreateAfter(); 405 SetAppLaunchOrdinalForApp(GetProfile(0), 0, second_position); 406 SetAppLaunchOrdinalForApp(verifier(), 0, second_position); 407 ASSERT_TRUE(AwaitQuiescence()); 408 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 409 } 410 411 // Adjust the CWS location within a page on the first client and sync. Adjust 412 // which page the CWS appears on and sync. Both clients should have the same 413 // page and app launch ordinal values for the CWS. 414 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateCWSOrdinals) { 415 ASSERT_TRUE(SetupSync()); 416 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 417 418 // Change the app launch ordinal. 419 syncer::StringOrdinal cws_app_launch_ordinal = 420 extensions::ExtensionPrefs::Get(GetProfile(0)) 421 ->app_sorting() 422 ->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId); 423 extensions::ExtensionPrefs::Get(GetProfile(0)) 424 ->app_sorting() 425 ->SetAppLaunchOrdinal(extension_misc::kWebStoreAppId, 426 cws_app_launch_ordinal.CreateAfter()); 427 extensions::ExtensionPrefs::Get(verifier()) 428 ->app_sorting() 429 ->SetAppLaunchOrdinal(extension_misc::kWebStoreAppId, 430 cws_app_launch_ordinal.CreateAfter()); 431 ASSERT_TRUE(AwaitQuiescence()); 432 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 433 434 // Change the page ordinal. 435 syncer::StringOrdinal cws_page_ordinal = 436 extensions::ExtensionPrefs::Get(GetProfile(1)) 437 ->app_sorting() 438 ->GetPageOrdinal(extension_misc::kWebStoreAppId); 439 extensions::ExtensionPrefs::Get(GetProfile(1))->app_sorting()->SetPageOrdinal( 440 extension_misc::kWebStoreAppId, cws_page_ordinal.CreateAfter()); 441 extensions::ExtensionPrefs::Get(verifier())->app_sorting()->SetPageOrdinal( 442 extension_misc::kWebStoreAppId, cws_page_ordinal.CreateAfter()); 443 ASSERT_TRUE(AwaitQuiescence()); 444 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 445 } 446 447 // Adjust the launch type on the first client and sync. Both clients should 448 // have the same launch type values for the CWS. 449 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateLaunchType) { 450 ASSERT_TRUE(SetupSync()); 451 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 452 453 // Change the launch type to window. 454 extensions::SetLaunchType(GetProfile(1)->GetExtensionService(), 455 extension_misc::kWebStoreAppId, 456 extensions::LAUNCH_TYPE_WINDOW); 457 extensions::SetLaunchType(verifier()->GetExtensionService(), 458 extension_misc::kWebStoreAppId, 459 extensions::LAUNCH_TYPE_WINDOW); 460 ASSERT_TRUE(AwaitQuiescence()); 461 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 462 463 // Change the launch type to regular tab. 464 extensions::SetLaunchType(GetProfile(1)->GetExtensionService(), 465 extension_misc::kWebStoreAppId, 466 extensions::LAUNCH_TYPE_REGULAR); 467 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 468 extensions::SetLaunchType(verifier()->GetExtensionService(), 469 extension_misc::kWebStoreAppId, 470 extensions::LAUNCH_TYPE_REGULAR); 471 ASSERT_TRUE(AwaitQuiescence()); 472 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 473 } 474 475 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UnexpectedLaunchType) { 476 ASSERT_TRUE(SetupSync()); 477 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 478 479 extensions::SetLaunchType(GetProfile(1)->GetExtensionService(), 480 extension_misc::kWebStoreAppId, 481 extensions::LAUNCH_TYPE_REGULAR); 482 extensions::SetLaunchType(verifier()->GetExtensionService(), 483 extension_misc::kWebStoreAppId, 484 extensions::LAUNCH_TYPE_REGULAR); 485 ASSERT_TRUE(AwaitQuiescence()); 486 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 487 488 const extensions::Extension* extension = 489 GetProfile(1)->GetExtensionService()-> 490 GetInstalledExtension(extension_misc::kWebStoreAppId); 491 ASSERT_TRUE(extension); 492 493 ExtensionSyncService* extension_sync_service = 494 ExtensionSyncService::Get(GetProfile(1)); 495 496 extensions::AppSyncData original_data( 497 extension_sync_service->GetAppSyncData(*extension)); 498 499 // Create an invalid launch type and ensure it doesn't get down-synced. This 500 // simulates the case of a future launch type being added which old versions 501 // don't yet understand. 502 extensions::AppSyncData invalid_launch_type_data( 503 *extension, 504 original_data.extension_sync_data().enabled(), 505 original_data.extension_sync_data().incognito_enabled(), 506 original_data.extension_sync_data().remote_install(), 507 original_data.app_launch_ordinal(), 508 original_data.page_ordinal(), 509 extensions::NUM_LAUNCH_TYPES); 510 extension_sync_service->ProcessAppSyncData(invalid_launch_type_data); 511 512 // The launch type should remain the same. 513 ASSERT_TRUE(AwaitQuiescence()); 514 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 515 } 516 517 IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, BookmarkApp) { 518 ASSERT_TRUE(SetupSync()); 519 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 520 521 size_t num_extensions = 522 GetProfile(0)->GetExtensionService()->extensions()->size(); 523 524 WebApplicationInfo web_app_info; 525 web_app_info.app_url = GURL("http://www.chromium.org"); 526 web_app_info.title = base::UTF8ToUTF16("Test name"); 527 web_app_info.description = base::UTF8ToUTF16("Test description"); 528 ++num_extensions; 529 { 530 content::WindowedNotificationObserver windowed_observer( 531 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 532 content::NotificationService::AllSources()); 533 extensions::CreateOrUpdateBookmarkApp(GetProfile(0)->GetExtensionService(), 534 web_app_info); 535 windowed_observer.Wait(); 536 EXPECT_EQ(num_extensions, 537 extensions::ExtensionRegistry::Get(GetProfile(0)) 538 ->enabled_extensions() 539 .size()); 540 } 541 { 542 content::WindowedNotificationObserver windowed_observer( 543 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 544 content::NotificationService::AllSources()); 545 extensions::CreateOrUpdateBookmarkApp(verifier()->GetExtensionService(), 546 web_app_info); 547 windowed_observer.Wait(); 548 EXPECT_EQ(num_extensions, 549 extensions::ExtensionRegistry::Get(verifier()) 550 ->enabled_extensions() 551 .size()); 552 } 553 { 554 // Wait for the synced app to install. 555 content::WindowedNotificationObserver windowed_observer( 556 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 557 content::NotificationService::AllSources()); 558 ASSERT_TRUE(AwaitQuiescence()); 559 windowed_observer.Wait(); 560 ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier()); 561 } 562 } 563 // TODO(akalin): Add tests exercising: 564 // - Offline installation/uninstallation behavior 565 // - App-specific properties 566