Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / test / integration / apps_helper.cc
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 "chrome/browser/sync/test/integration/apps_helper.h"
6
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"
24
25 using sync_datatype_helper::test;
26
27 namespace {
28
29 std::string CreateFakeAppName(int index) {
30   return "fakeapp" + base::IntToString(index);
31 }
32
33 }  // namespace
34
35 namespace apps_helper {
36
37 bool HasSameAppsAsVerifier(int index) {
38   return SyncAppHelper::GetInstance()->AppStatesMatch(
39       test()->GetProfile(index), test()->verifier());
40 }
41
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;
48     }
49   }
50   return true;
51 }
52
53 std::string InstallApp(Profile* profile, int index) {
54   return SyncExtensionHelper::GetInstance()->InstallExtension(
55       profile,
56       CreateFakeAppName(index),
57       extensions::Manifest::TYPE_HOSTED_APP);
58 }
59
60 std::string InstallPlatformApp(Profile* profile, int index) {
61   return SyncExtensionHelper::GetInstance()->InstallExtension(
62       profile,
63       CreateFakeAppName(index),
64       extensions::Manifest::TYPE_PLATFORM_APP);
65 }
66
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);
71 }
72
73 void UninstallApp(Profile* profile, int index) {
74   return SyncExtensionHelper::GetInstance()->UninstallExtension(
75       profile, CreateFakeAppName(index));
76 }
77
78 void EnableApp(Profile* profile, int index) {
79   return SyncExtensionHelper::GetInstance()->EnableExtension(
80       profile, CreateFakeAppName(index));
81 }
82
83 void DisableApp(Profile* profile, int index) {
84   return SyncExtensionHelper::GetInstance()->DisableExtension(
85       profile, CreateFakeAppName(index));
86 }
87
88 void IncognitoEnableApp(Profile* profile, int index) {
89   return SyncExtensionHelper::GetInstance()->IncognitoEnableExtension(
90       profile, CreateFakeAppName(index));
91 }
92
93 void IncognitoDisableApp(Profile* profile, int index) {
94   return SyncExtensionHelper::GetInstance()->IncognitoDisableExtension(
95       profile, CreateFakeAppName(index));
96 }
97
98 void InstallAppsPendingForSync(Profile* profile) {
99   SyncExtensionHelper::GetInstance()->InstallExtensionsPendingForSync(profile);
100 }
101
102 syncer::StringOrdinal GetPageOrdinalForApp(Profile* profile,
103                                            int app_index) {
104   return SyncAppHelper::GetInstance()->GetPageOrdinalForApp(
105       profile, CreateFakeAppName(app_index));
106 }
107
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);
113 }
114
115 syncer::StringOrdinal GetAppLaunchOrdinalForApp(Profile* profile,
116                                                 int app_index) {
117   return SyncAppHelper::GetInstance()->GetAppLaunchOrdinalForApp(
118       profile, CreateFakeAppName(app_index));
119 }
120
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);
127 }
128
129 void CopyNTPOrdinals(Profile* source, Profile* destination, int index) {
130   SetPageOrdinalForApp(destination, index, GetPageOrdinalForApp(source, index));
131   SetAppLaunchOrdinalForApp(
132       destination, index, GetAppLaunchOrdinalForApp(source, index));
133 }
134
135 void FixNTPOrdinalCollisions(Profile* profile) {
136   SyncAppHelper::GetInstance()->FixNTPOrdinalCollisions(profile);
137 }
138
139 namespace {
140
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   ~AppsMatchChecker() override;
150
151   // StatusChangeChecker implementation.
152   std::string GetDebugMessage() const override;
153   bool IsExitConditionSatisfied() override;
154
155   // extensions::ExtensionRegistryObserver implementation.
156   void OnExtensionLoaded(content::BrowserContext* context,
157                          const extensions::Extension* extension) override;
158   void OnExtensionUnloaded(
159       content::BrowserContext* context,
160       const extensions::Extension* extenion,
161       extensions::UnloadedExtensionInfo::Reason reason) override;
162   void OnExtensionInstalled(content::BrowserContext* browser_context,
163                             const extensions::Extension* extension,
164                             bool is_update) override;
165   void OnExtensionUninstalled(content::BrowserContext* browser_context,
166                               const extensions::Extension* extension,
167                               extensions::UninstallReason reason) override;
168
169   // extensions::ExtensionPrefsObserver implementation.
170   void OnExtensionDisableReasonsChanged(const std::string& extension_id,
171                                         int disabled_reasons) override;
172   void OnExtensionRegistered(const std::string& extension_id,
173                              const base::Time& install_time,
174                              bool is_enabled) override;
175   void OnExtensionPrefsLoaded(const std::string& extension_id,
176                               const extensions::ExtensionPrefs* prefs) override;
177   void OnExtensionPrefsDeleted(const std::string& extension_id) override;
178   void OnExtensionStateChanged(const std::string& extension_id,
179                                bool state) override;
180
181   // Implementation of content::NotificationObserver.
182   void Observe(int type,
183                const content::NotificationSource& source,
184                const content::NotificationDetails& details) override;
185
186   void Wait();
187
188  private:
189   std::vector<Profile*> profiles_;
190   bool observing_;
191
192   content::NotificationRegistrar registrar_;
193
194   // This installs apps, too.
195   ScopedVector<SyncedExtensionInstaller> synced_extension_installers_;
196
197   DISALLOW_COPY_AND_ASSIGN(AppsMatchChecker);
198 };
199
200 AppsMatchChecker::AppsMatchChecker(const std::vector<Profile*>& profiles)
201     : profiles_(profiles), observing_(false) {
202   DCHECK_GE(profiles_.size(), 2U);
203 }
204
205 AppsMatchChecker::~AppsMatchChecker() {
206   if (observing_) {
207     for (std::vector<Profile*>::iterator it = profiles_.begin();
208          it != profiles_.end();
209          ++it) {
210       extensions::ExtensionRegistry* registry =
211           extensions::ExtensionRegistry::Get(*it);
212       registry->RemoveObserver(this);
213       extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(*it);
214       prefs->RemoveObserver(this);
215     }
216   }
217 }
218
219 std::string AppsMatchChecker::GetDebugMessage() const {
220   return "Waiting for apps to match";
221 }
222
223 bool AppsMatchChecker::IsExitConditionSatisfied() {
224   std::vector<Profile*>::iterator it = profiles_.begin();
225   Profile* profile0 = *it;
226   ++it;
227   for (; it != profiles_.end(); ++it) {
228     if (!SyncAppHelper::GetInstance()->AppStatesMatch(profile0, *it)) {
229       return false;
230     }
231   }
232   return true;
233 }
234
235 void AppsMatchChecker::OnExtensionLoaded(
236     content::BrowserContext* context,
237     const extensions::Extension* extension) {
238   CheckExitCondition();
239 }
240
241 void AppsMatchChecker::OnExtensionUnloaded(
242     content::BrowserContext* context,
243     const extensions::Extension* extenion,
244     extensions::UnloadedExtensionInfo::Reason reason) {
245   CheckExitCondition();
246 }
247
248 void AppsMatchChecker::OnExtensionInstalled(
249     content::BrowserContext* browser_context,
250     const extensions::Extension* extension,
251     bool is_update) {
252   CheckExitCondition();
253 }
254
255 void AppsMatchChecker::OnExtensionUninstalled(
256     content::BrowserContext* browser_context,
257     const extensions::Extension* extension,
258     extensions::UninstallReason reason) {
259   CheckExitCondition();
260 }
261
262 void AppsMatchChecker::OnExtensionDisableReasonsChanged(
263     const std::string& extension_id,
264     int disabled_reasons) {
265   CheckExitCondition();
266 }
267
268 void AppsMatchChecker::OnExtensionRegistered(const std::string& extension_id,
269                                              const base::Time& install_time,
270                                              bool is_enabled) {
271   CheckExitCondition();
272 }
273
274 void AppsMatchChecker::OnExtensionPrefsLoaded(
275     const std::string& extension_id,
276     const extensions::ExtensionPrefs* prefs) {
277   CheckExitCondition();
278 }
279
280 void AppsMatchChecker::OnExtensionPrefsDeleted(
281     const std::string& extension_id) {
282   CheckExitCondition();
283 }
284
285 void AppsMatchChecker::OnExtensionStateChanged(const std::string& extension_id,
286                                                bool state) {
287   CheckExitCondition();
288 }
289
290 void AppsMatchChecker::Observe(int type,
291                                const content::NotificationSource& source,
292                                const content::NotificationDetails& details) {
293   DCHECK_EQ(chrome::NOTIFICATION_APP_LAUNCHER_REORDERED, type);
294   CheckExitCondition();
295 }
296
297 void AppsMatchChecker::Wait() {
298   for (std::vector<Profile*>::iterator it = profiles_.begin();
299        it != profiles_.end();
300        ++it) {
301     // Begin mocking the installation of synced extensions from the web store.
302     synced_extension_installers_.push_back(new SyncedExtensionInstaller(*it));
303
304     // Register as an observer of ExtensionsRegistry to receive notifications of
305     // big events, like installs and uninstalls.
306     extensions::ExtensionRegistry* registry =
307         extensions::ExtensionRegistry::Get(*it);
308     registry->AddObserver(this);
309
310     // Register for ExtensionPrefs events, too, so we can get notifications
311     // about
312     // smaller but still syncable events, like launch type changes.
313     extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(*it);
314     prefs->AddObserver(this);
315   }
316
317   registrar_.Add(this,
318                  chrome::NOTIFICATION_APP_LAUNCHER_REORDERED,
319                  content::NotificationService::AllSources());
320
321   observing_ = true;
322
323   if (IsExitConditionSatisfied()) {
324     DVLOG(1) << "Apps matched without waiting";
325     return;
326   }
327
328   DVLOG(1) << "Starting Wait: " << GetDebugMessage();
329   StartBlockingWait();
330 }
331
332 }  // namespace
333
334 bool AwaitAllProfilesHaveSameAppsAsVerifier() {
335   std::vector<Profile*> profiles;
336   profiles.push_back(test()->verifier());
337   for (int i = 0; i < test()->num_clients(); ++i) {
338     profiles.push_back(test()->GetProfile(i));
339   }
340
341   AppsMatchChecker checker(profiles);
342   checker.Wait();
343   return !checker.TimedOut();
344 }
345
346 }  // namespace apps_helper