Move Webstore URL concepts to //extensions and out
[chromium-blink-merge.git] / chrome / browser / sync / test / integration / apps_helper.cc
blobc31c030c902fb94f10998f6368ded26f31975396
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.
5 #include "chrome/browser/sync/test/integration/apps_helper.h"
7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sync/test/integration/status_change_checker.h"
12 #include "chrome/browser/sync/test/integration/sync_app_helper.h"
13 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
14 #include "chrome/browser/sync/test/integration/sync_extension_helper.h"
15 #include "chrome/browser/sync/test/integration/sync_extension_installer.h"
16 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "content/public/browser/notification_service.h"
19 #include "extensions/browser/extension_prefs.h"
20 #include "extensions/browser/extension_prefs_observer.h"
21 #include "extensions/browser/extension_registry.h"
22 #include "extensions/browser/extension_registry_observer.h"
23 #include "extensions/common/manifest.h"
25 using sync_datatype_helper::test;
27 namespace {
29 std::string CreateFakeAppName(int index) {
30 return "fakeapp" + base::IntToString(index);
33 } // namespace
35 namespace apps_helper {
37 bool HasSameAppsAsVerifier(int index) {
38 return SyncAppHelper::GetInstance()->AppStatesMatch(
39 test()->GetProfile(index), test()->verifier());
42 bool AllProfilesHaveSameAppsAsVerifier() {
43 for (int i = 0; i < test()->num_clients(); ++i) {
44 if (!HasSameAppsAsVerifier(i)) {
45 DVLOG(1) << "Profile " << i << " doesn't have the same apps as the"
46 " verifier profile.";
47 return false;
50 return true;
53 std::string InstallApp(Profile* profile, int index) {
54 return SyncExtensionHelper::GetInstance()->InstallExtension(
55 profile,
56 CreateFakeAppName(index),
57 extensions::Manifest::TYPE_HOSTED_APP);
60 std::string InstallPlatformApp(Profile* profile, int index) {
61 return SyncExtensionHelper::GetInstance()->InstallExtension(
62 profile,
63 CreateFakeAppName(index),
64 extensions::Manifest::TYPE_PLATFORM_APP);
67 std::string InstallAppForAllProfiles(int index) {
68 for (int i = 0; i < test()->num_clients(); ++i)
69 InstallApp(test()->GetProfile(i), index);
70 return InstallApp(test()->verifier(), index);
73 void UninstallApp(Profile* profile, int index) {
74 return SyncExtensionHelper::GetInstance()->UninstallExtension(
75 profile, CreateFakeAppName(index));
78 void EnableApp(Profile* profile, int index) {
79 return SyncExtensionHelper::GetInstance()->EnableExtension(
80 profile, CreateFakeAppName(index));
83 void DisableApp(Profile* profile, int index) {
84 return SyncExtensionHelper::GetInstance()->DisableExtension(
85 profile, CreateFakeAppName(index));
88 void IncognitoEnableApp(Profile* profile, int index) {
89 return SyncExtensionHelper::GetInstance()->IncognitoEnableExtension(
90 profile, CreateFakeAppName(index));
93 void IncognitoDisableApp(Profile* profile, int index) {
94 return SyncExtensionHelper::GetInstance()->IncognitoDisableExtension(
95 profile, CreateFakeAppName(index));
98 void InstallAppsPendingForSync(Profile* profile) {
99 SyncExtensionHelper::GetInstance()->InstallExtensionsPendingForSync(profile);
102 syncer::StringOrdinal GetPageOrdinalForApp(Profile* profile,
103 int app_index) {
104 return SyncAppHelper::GetInstance()->GetPageOrdinalForApp(
105 profile, CreateFakeAppName(app_index));
108 void SetPageOrdinalForApp(Profile* profile,
109 int app_index,
110 const syncer::StringOrdinal& page_ordinal) {
111 SyncAppHelper::GetInstance()->SetPageOrdinalForApp(
112 profile, CreateFakeAppName(app_index), page_ordinal);
115 syncer::StringOrdinal GetAppLaunchOrdinalForApp(Profile* profile,
116 int app_index) {
117 return SyncAppHelper::GetInstance()->GetAppLaunchOrdinalForApp(
118 profile, CreateFakeAppName(app_index));
121 void SetAppLaunchOrdinalForApp(
122 Profile* profile,
123 int app_index,
124 const syncer::StringOrdinal& app_launch_ordinal) {
125 SyncAppHelper::GetInstance()->SetAppLaunchOrdinalForApp(
126 profile, CreateFakeAppName(app_index), app_launch_ordinal);
129 void CopyNTPOrdinals(Profile* source, Profile* destination, int index) {
130 SetPageOrdinalForApp(destination, index, GetPageOrdinalForApp(source, index));
131 SetAppLaunchOrdinalForApp(
132 destination, index, GetAppLaunchOrdinalForApp(source, index));
135 void FixNTPOrdinalCollisions(Profile* profile) {
136 SyncAppHelper::GetInstance()->FixNTPOrdinalCollisions(profile);
139 namespace {
141 // A helper class to implement waiting for a set of profiles to have matching
142 // extensions lists.
143 class AppsMatchChecker : public StatusChangeChecker,
144 public extensions::ExtensionRegistryObserver,
145 public extensions::ExtensionPrefsObserver,
146 public content::NotificationObserver {
147 public:
148 explicit AppsMatchChecker(const std::vector<Profile*>& profiles);
149 virtual ~AppsMatchChecker();
151 // StatusChangeChecker implementation.
152 virtual std::string GetDebugMessage() const OVERRIDE;
153 virtual bool IsExitConditionSatisfied() OVERRIDE;
155 // extensions::ExtensionRegistryObserver implementation.
156 virtual void OnExtensionLoaded(
157 content::BrowserContext* context,
158 const extensions::Extension* extension) OVERRIDE;
159 virtual void OnExtensionUnloaded(
160 content::BrowserContext* context,
161 const extensions::Extension* extenion,
162 extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE;
163 virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
164 const extensions::Extension* extension,
165 bool is_update) OVERRIDE;
166 virtual void OnExtensionUninstalled(
167 content::BrowserContext* browser_context,
168 const extensions::Extension* extension,
169 extensions::UninstallReason reason) OVERRIDE;
171 // extensions::ExtensionPrefsObserver implementation.
172 virtual void OnExtensionDisableReasonsChanged(const std::string& extension_id,
173 int disabled_reasons) OVERRIDE;
174 virtual void OnExtensionRegistered(const std::string& extension_id,
175 const base::Time& install_time,
176 bool is_enabled) OVERRIDE;
177 virtual void OnExtensionPrefsLoaded(
178 const std::string& extension_id,
179 const extensions::ExtensionPrefs* prefs) OVERRIDE;
180 virtual void OnExtensionPrefsDeleted(
181 const std::string& extension_id) OVERRIDE;
182 virtual void OnExtensionStateChanged(const std::string& extension_id,
183 bool state) OVERRIDE;
185 // Implementation of content::NotificationObserver.
186 virtual void Observe(int type,
187 const content::NotificationSource& source,
188 const content::NotificationDetails& details) OVERRIDE;
190 void Wait();
192 private:
193 std::vector<Profile*> profiles_;
194 bool observing_;
196 content::NotificationRegistrar registrar_;
198 // This installs apps, too.
199 ScopedVector<SyncedExtensionInstaller> synced_extension_installers_;
201 DISALLOW_COPY_AND_ASSIGN(AppsMatchChecker);
204 AppsMatchChecker::AppsMatchChecker(const std::vector<Profile*>& profiles)
205 : profiles_(profiles), observing_(false) {
206 DCHECK_GE(profiles_.size(), 2U);
209 AppsMatchChecker::~AppsMatchChecker() {
210 if (observing_) {
211 for (std::vector<Profile*>::iterator it = profiles_.begin();
212 it != profiles_.end();
213 ++it) {
214 extensions::ExtensionRegistry* registry =
215 extensions::ExtensionRegistry::Get(*it);
216 registry->RemoveObserver(this);
217 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(*it);
218 prefs->RemoveObserver(this);
223 std::string AppsMatchChecker::GetDebugMessage() const {
224 return "Waiting for apps to match";
227 bool AppsMatchChecker::IsExitConditionSatisfied() {
228 std::vector<Profile*>::iterator it = profiles_.begin();
229 Profile* profile0 = *it;
230 ++it;
231 for (; it != profiles_.end(); ++it) {
232 if (!SyncAppHelper::GetInstance()->AppStatesMatch(profile0, *it)) {
233 return false;
236 return true;
239 void AppsMatchChecker::OnExtensionLoaded(
240 content::BrowserContext* context,
241 const extensions::Extension* extension) {
242 CheckExitCondition();
245 void AppsMatchChecker::OnExtensionUnloaded(
246 content::BrowserContext* context,
247 const extensions::Extension* extenion,
248 extensions::UnloadedExtensionInfo::Reason reason) {
249 CheckExitCondition();
252 void AppsMatchChecker::OnExtensionInstalled(
253 content::BrowserContext* browser_context,
254 const extensions::Extension* extension,
255 bool is_update) {
256 CheckExitCondition();
259 void AppsMatchChecker::OnExtensionUninstalled(
260 content::BrowserContext* browser_context,
261 const extensions::Extension* extension,
262 extensions::UninstallReason reason) {
263 CheckExitCondition();
266 void AppsMatchChecker::OnExtensionDisableReasonsChanged(
267 const std::string& extension_id,
268 int disabled_reasons) {
269 CheckExitCondition();
272 void AppsMatchChecker::OnExtensionRegistered(const std::string& extension_id,
273 const base::Time& install_time,
274 bool is_enabled) {
275 CheckExitCondition();
278 void AppsMatchChecker::OnExtensionPrefsLoaded(
279 const std::string& extension_id,
280 const extensions::ExtensionPrefs* prefs) {
281 CheckExitCondition();
284 void AppsMatchChecker::OnExtensionPrefsDeleted(
285 const std::string& extension_id) {
286 CheckExitCondition();
289 void AppsMatchChecker::OnExtensionStateChanged(const std::string& extension_id,
290 bool state) {
291 CheckExitCondition();
294 void AppsMatchChecker::Observe(int type,
295 const content::NotificationSource& source,
296 const content::NotificationDetails& details) {
297 DCHECK_EQ(chrome::NOTIFICATION_APP_LAUNCHER_REORDERED, type);
298 CheckExitCondition();
301 void AppsMatchChecker::Wait() {
302 for (std::vector<Profile*>::iterator it = profiles_.begin();
303 it != profiles_.end();
304 ++it) {
305 // Begin mocking the installation of synced extensions from the web store.
306 synced_extension_installers_.push_back(new SyncedExtensionInstaller(*it));
308 // Register as an observer of ExtensionsRegistry to receive notifications of
309 // big events, like installs and uninstalls.
310 extensions::ExtensionRegistry* registry =
311 extensions::ExtensionRegistry::Get(*it);
312 registry->AddObserver(this);
314 // Register for ExtensionPrefs events, too, so we can get notifications
315 // about
316 // smaller but still syncable events, like launch type changes.
317 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(*it);
318 prefs->AddObserver(this);
321 registrar_.Add(this,
322 chrome::NOTIFICATION_APP_LAUNCHER_REORDERED,
323 content::NotificationService::AllSources());
325 observing_ = true;
327 if (IsExitConditionSatisfied()) {
328 DVLOG(1) << "Apps matched without waiting";
329 return;
332 DVLOG(1) << "Starting Wait: " << GetDebugMessage();
333 StartBlockingWait();
336 } // namespace
338 bool AwaitAllProfilesHaveSameAppsAsVerifier() {
339 std::vector<Profile*> profiles;
340 profiles.push_back(test()->verifier());
341 for (int i = 0; i < test()->num_clients(); ++i) {
342 profiles.push_back(test()->GetProfile(i));
345 AppsMatchChecker checker(profiles);
346 checker.Wait();
347 return !checker.TimedOut();
350 } // namespace apps_helper