15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/apps_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/sync/test/integration/status_change_checker.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/sync_app_helper.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/sync_extension_helper.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/sync/test/integration/sync_extension_installer.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_observer.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_registrar.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_service.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_prefs.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_prefs_observer.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_registry.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_registry_observer.h"
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_datatype_helper::test;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string CreateFakeAppName(int index) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "fakeapp" + base::IntToString(index);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace apps_helper {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasSameAppsAsVerifier(int index) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SyncAppHelper::GetInstance()->AppStatesMatch(
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test()->GetProfile(index), test()->verifier());
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AllProfilesHaveSameAppsAsVerifier() {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < test()->num_clients(); ++i) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!HasSameAppsAsVerifier(i)) {
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DVLOG(1) << "Profile " << i << " doesn't have the same apps as the"
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     " verifier profile.";
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string InstallApp(Profile* profile, int index) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SyncExtensionHelper::GetInstance()->InstallExtension(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateFakeAppName(index),
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::Manifest::TYPE_HOSTED_APP);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string InstallPlatformApp(Profile* profile, int index) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SyncExtensionHelper::GetInstance()->InstallExtension(
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateFakeAppName(index),
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::Manifest::TYPE_PLATFORM_APP);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string InstallAppForAllProfiles(int index) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < test()->num_clients(); ++i)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallApp(test()->GetProfile(i), index);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return InstallApp(test()->verifier(), index);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UninstallApp(Profile* profile, int index) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SyncExtensionHelper::GetInstance()->UninstallExtension(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile, CreateFakeAppName(index));
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void EnableApp(Profile* profile, int index) {
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return SyncExtensionHelper::GetInstance()->EnableExtension(
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      profile, CreateFakeAppName(index));
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DisableApp(Profile* profile, int index) {
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return SyncExtensionHelper::GetInstance()->DisableExtension(
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      profile, CreateFakeAppName(index));
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IncognitoEnableApp(Profile* profile, int index) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SyncExtensionHelper::GetInstance()->IncognitoEnableExtension(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile, CreateFakeAppName(index));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IncognitoDisableApp(Profile* profile, int index) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SyncExtensionHelper::GetInstance()->IncognitoDisableExtension(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile, CreateFakeAppName(index));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallAppsPendingForSync(Profile* profile) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncExtensionHelper::GetInstance()->InstallExtensionsPendingForSync(profile);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::StringOrdinal GetPageOrdinalForApp(Profile* profile,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int app_index) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SyncAppHelper::GetInstance()->GetPageOrdinalForApp(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile, CreateFakeAppName(app_index));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetPageOrdinalForApp(Profile* profile,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int app_index,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const syncer::StringOrdinal& page_ordinal) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncAppHelper::GetInstance()->SetPageOrdinalForApp(
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile, CreateFakeAppName(app_index), page_ordinal);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::StringOrdinal GetAppLaunchOrdinalForApp(Profile* profile,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                int app_index) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SyncAppHelper::GetInstance()->GetAppLaunchOrdinalForApp(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile, CreateFakeAppName(app_index));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetAppLaunchOrdinalForApp(
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int app_index,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const syncer::StringOrdinal& app_launch_ordinal) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncAppHelper::GetInstance()->SetAppLaunchOrdinalForApp(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile, CreateFakeAppName(app_index), app_launch_ordinal);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyNTPOrdinals(Profile* source, Profile* destination, int index) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPageOrdinalForApp(destination, index, GetPageOrdinalForApp(source, index));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetAppLaunchOrdinalForApp(
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      destination, index, GetAppLaunchOrdinalForApp(source, index));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FixNTPOrdinalCollisions(Profile* profile) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncAppHelper::GetInstance()->FixNTPOrdinalCollisions(profile);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A helper class to implement waiting for a set of profiles to have matching
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// extensions lists.
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class AppsMatchChecker : public StatusChangeChecker,
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         public extensions::ExtensionRegistryObserver,
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         public extensions::ExtensionPrefsObserver,
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         public content::NotificationObserver {
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit AppsMatchChecker(const std::vector<Profile*>& profiles);
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~AppsMatchChecker();
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // StatusChangeChecker implementation.
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual std::string GetDebugMessage() const OVERRIDE;
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual bool IsExitConditionSatisfied() OVERRIDE;
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // extensions::ExtensionRegistryObserver implementation.
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionLoaded(
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::BrowserContext* context,
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const extensions::Extension* extension) OVERRIDE;
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionUnloaded(
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::BrowserContext* context,
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const extensions::Extension* extenion,
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE;
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    const extensions::Extension* extension,
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    bool is_update) OVERRIDE;
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionUninstalled(
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::BrowserContext* browser_context,
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const extensions::Extension* extension,
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::UninstallReason reason) OVERRIDE;
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // extensions::ExtensionPrefsObserver implementation.
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionDisableReasonsChanged(const std::string& extension_id,
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                int disabled_reasons) OVERRIDE;
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionRegistered(const std::string& extension_id,
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     const base::Time& install_time,
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     bool is_enabled) OVERRIDE;
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionPrefsLoaded(
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const std::string& extension_id,
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const extensions::ExtensionPrefs* prefs) OVERRIDE;
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionPrefsDeleted(
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const std::string& extension_id) OVERRIDE;
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnExtensionStateChanged(const std::string& extension_id,
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       bool state) OVERRIDE;
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Implementation of content::NotificationObserver.
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Observe(int type,
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const content::NotificationSource& source,
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void Wait();
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<Profile*> profiles_;
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool observing_;
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  content::NotificationRegistrar registrar_;
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // This installs apps, too.
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ScopedVector<SyncedExtensionInstaller> synced_extension_installers_;
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppsMatchChecker);
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)AppsMatchChecker::AppsMatchChecker(const std::vector<Profile*>& profiles)
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : profiles_(profiles), observing_(false) {
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_GE(profiles_.size(), 2U);
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)AppsMatchChecker::~AppsMatchChecker() {
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (observing_) {
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for (std::vector<Profile*>::iterator it = profiles_.begin();
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         it != profiles_.end();
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         ++it) {
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::ExtensionRegistry* registry =
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          extensions::ExtensionRegistry::Get(*it);
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      registry->RemoveObserver(this);
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(*it);
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      prefs->RemoveObserver(this);
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::string AppsMatchChecker::GetDebugMessage() const {
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return "Waiting for apps to match";
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool AppsMatchChecker::IsExitConditionSatisfied() {
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<Profile*>::iterator it = profiles_.begin();
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile0 = *it;
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ++it;
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (; it != profiles_.end(); ++it) {
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!SyncAppHelper::GetInstance()->AppStatesMatch(profile0, *it)) {
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionLoaded(
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::BrowserContext* context,
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const extensions::Extension* extension) {
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionUnloaded(
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::BrowserContext* context,
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const extensions::Extension* extenion,
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    extensions::UnloadedExtensionInfo::Reason reason) {
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionInstalled(
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::BrowserContext* browser_context,
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const extensions::Extension* extension,
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool is_update) {
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionUninstalled(
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::BrowserContext* browser_context,
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const extensions::Extension* extension,
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    extensions::UninstallReason reason) {
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionDisableReasonsChanged(
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& extension_id,
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int disabled_reasons) {
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionRegistered(const std::string& extension_id,
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             const base::Time& install_time,
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             bool is_enabled) {
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionPrefsLoaded(
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& extension_id,
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const extensions::ExtensionPrefs* prefs) {
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionPrefsDeleted(
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& extension_id) {
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::OnExtensionStateChanged(const std::string& extension_id,
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               bool state) {
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::Observe(int type,
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               const content::NotificationSource& source,
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               const content::NotificationDetails& details) {
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(chrome::NOTIFICATION_APP_LAUNCHER_REORDERED, type);
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckExitCondition();
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AppsMatchChecker::Wait() {
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (std::vector<Profile*>::iterator it = profiles_.begin();
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != profiles_.end();
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Begin mocking the installation of synced extensions from the web store.
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    synced_extension_installers_.push_back(new SyncedExtensionInstaller(*it));
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Register as an observer of ExtensionsRegistry to receive notifications of
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // big events, like installs and uninstalls.
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    extensions::ExtensionRegistry* registry =
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        extensions::ExtensionRegistry::Get(*it);
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    registry->AddObserver(this);
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Register for ExtensionPrefs events, too, so we can get notifications
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // about
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // smaller but still syncable events, like launch type changes.
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(*it);
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    prefs->AddObserver(this);
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registrar_.Add(this,
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 chrome::NOTIFICATION_APP_LAUNCHER_REORDERED,
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 content::NotificationService::AllSources());
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  observing_ = true;
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (IsExitConditionSatisfied()) {
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DVLOG(1) << "Apps matched without waiting";
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DVLOG(1) << "Starting Wait: " << GetDebugMessage();
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StartBlockingWait();
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool AwaitAllProfilesHaveSameAppsAsVerifier() {
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<Profile*> profiles;
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  profiles.push_back(test()->verifier());
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (int i = 0; i < test()->num_clients(); ++i) {
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    profiles.push_back(test()->GetProfile(i));
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AppsMatchChecker checker(profiles);
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  checker.Wait();
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return !checker.TimedOut();
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace apps_helper
351