Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / sync / test / integration / sync_app_helper.cc
blob1f28b36aa4b3aeaa194017c45a688a4bd7901399
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/sync_app_helper.h"
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/extensions/launch_util.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/sync/test/integration/extensions_helper.h"
11 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
12 #include "chrome/browser/sync/test/integration/sync_extension_helper.h"
13 #include "chrome/common/extensions/extension_constants.h"
14 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
15 #include "chrome/common/extensions/sync_helper.h"
16 #include "components/crx_file/id_util.h"
17 #include "extensions/browser/app_sorting.h"
18 #include "extensions/browser/extension_prefs.h"
19 #include "extensions/browser/extension_registry.h"
20 #include "extensions/browser/extension_system.h"
21 #include "extensions/common/extension_set.h"
23 using extensions::ExtensionPrefs;
25 namespace {
27 struct AppState {
28 AppState();
29 ~AppState();
30 bool IsValid() const;
31 bool Equals(const AppState& other) const;
33 syncer::StringOrdinal app_launch_ordinal;
34 syncer::StringOrdinal page_ordinal;
35 extensions::LaunchType launch_type;
36 GURL launch_web_url;
37 std::string description;
38 std::string name;
39 bool from_bookmark;
42 typedef std::map<std::string, AppState> AppStateMap;
44 AppState::AppState()
45 : launch_type(extensions::LAUNCH_TYPE_INVALID), from_bookmark(false) {}
47 AppState::~AppState() {}
49 bool AppState::IsValid() const {
50 return page_ordinal.IsValid() && app_launch_ordinal.IsValid();
53 bool AppState::Equals(const AppState& other) const {
54 return app_launch_ordinal.Equals(other.app_launch_ordinal) &&
55 page_ordinal.Equals(other.page_ordinal) &&
56 launch_type == other.launch_type &&
57 launch_web_url == other.launch_web_url &&
58 description == other.description && name == other.name &&
59 from_bookmark == other.from_bookmark;
62 // Load all the app specific values for |id| into |app_state|.
63 void LoadApp(content::BrowserContext* context,
64 const std::string& id,
65 AppState* app_state) {
66 ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
67 app_state->app_launch_ordinal = prefs->app_sorting()->GetAppLaunchOrdinal(id);
68 app_state->page_ordinal = prefs->app_sorting()->GetPageOrdinal(id);
69 app_state->launch_type = extensions::GetLaunchTypePrefValue(prefs, id);
70 ExtensionService* service =
71 extensions::ExtensionSystem::Get(context)->extension_service();
72 const extensions::Extension* extension = service->GetInstalledExtension(id);
73 // GetInstalledExtension(id) returns null if |id| is for a pending extension.
74 // In case of running tests against real backend servers, pending apps won't
75 // be installed.
76 if (extension) {
77 app_state->launch_web_url =
78 extensions::AppLaunchInfo::GetLaunchWebURL(extension);
79 app_state->description = extension->description();
80 app_state->name = extension->name();
81 app_state->from_bookmark = extension->from_bookmark();
85 // Returns a map from |profile|'s installed extensions to their state.
86 AppStateMap GetAppStates(Profile* profile) {
87 AppStateMap app_state_map;
89 scoped_ptr<const extensions::ExtensionSet> extensions(
90 extensions::ExtensionRegistry::Get(profile)
91 ->GenerateInstalledExtensionsSet());
92 for (const auto& extension : *extensions) {
93 if (extension->is_app() &&
94 extensions::sync_helper::IsSyncable(extension.get())) {
95 const std::string& id = extension->id();
96 LoadApp(profile, id, &(app_state_map[id]));
100 const extensions::PendingExtensionManager* pending_extension_manager =
101 extensions::ExtensionSystem::Get(profile)
102 ->extension_service()
103 ->pending_extension_manager();
105 std::list<std::string> pending_crx_ids;
106 pending_extension_manager->GetPendingIdsForUpdateCheck(&pending_crx_ids);
108 for (std::list<std::string>::const_iterator id = pending_crx_ids.begin();
109 id != pending_crx_ids.end(); ++id) {
110 LoadApp(profile, *id, &(app_state_map[*id]));
113 return app_state_map;
116 } // namespace
118 SyncAppHelper* SyncAppHelper::GetInstance() {
119 SyncAppHelper* instance = base::Singleton<SyncAppHelper>::get();
120 instance->SetupIfNecessary(sync_datatype_helper::test());
121 return instance;
124 void SyncAppHelper::SetupIfNecessary(SyncTest* test) {
125 if (setup_completed_)
126 return;
128 for (int i = 0; i < test->num_clients(); ++i) {
129 extensions::ExtensionSystem::Get(
130 test->GetProfile(i))->InitForRegularProfile(true);
132 if (test->use_verifier()) {
133 extensions::ExtensionSystem::Get(test->verifier())
134 ->InitForRegularProfile(true);
137 setup_completed_ = true;
140 bool SyncAppHelper::AppStatesMatch(Profile* profile1, Profile* profile2) {
141 if (!SyncExtensionHelper::GetInstance()->ExtensionStatesMatch(
142 profile1, profile2))
143 return false;
145 const AppStateMap& state_map1 = GetAppStates(profile1);
146 const AppStateMap& state_map2 = GetAppStates(profile2);
147 if (state_map1.size() != state_map2.size()) {
148 DVLOG(2) << "Number of Apps for profile " << profile1->GetDebugName()
149 << " does not match profile " << profile2->GetDebugName();
150 return false;
153 AppStateMap::const_iterator it1 = state_map1.begin();
154 AppStateMap::const_iterator it2 = state_map2.begin();
155 while (it1 != state_map1.end()) {
156 if (it1->first != it2->first) {
157 DVLOG(2) << "Apps for profile " << profile1->GetDebugName()
158 << " do not match profile " << profile2->GetDebugName();
159 return false;
160 } else if (!it1->second.IsValid()) {
161 DVLOG(2) << "Apps for profile " << profile1->GetDebugName()
162 << " are not valid.";
163 return false;
164 } else if (!it2->second.IsValid()) {
165 DVLOG(2) << "Apps for profile " << profile2->GetDebugName()
166 << " are not valid.";
167 return false;
168 } else if (!sync_datatype_helper::test()->UsingExternalServers() &&
169 !it1->second.Equals(it2->second)) {
170 // If this test is run against real backend servers then we do not expect
171 // to install pending apps. So, we don't check equality of AppStates of
172 // each app per profile.
173 DVLOG(2) << "App states for profile " << profile1->GetDebugName()
174 << " do not match profile " << profile2->GetDebugName();
175 return false;
177 ++it1;
178 ++it2;
181 return true;
184 syncer::StringOrdinal SyncAppHelper::GetPageOrdinalForApp(
185 Profile* profile,
186 const std::string& name) {
187 return ExtensionPrefs::Get(profile)->app_sorting()->GetPageOrdinal(
188 crx_file::id_util::GenerateId(name));
191 void SyncAppHelper::SetPageOrdinalForApp(
192 Profile* profile,
193 const std::string& name,
194 const syncer::StringOrdinal& page_ordinal) {
195 ExtensionPrefs::Get(profile)->app_sorting()->SetPageOrdinal(
196 crx_file::id_util::GenerateId(name), page_ordinal);
199 syncer::StringOrdinal SyncAppHelper::GetAppLaunchOrdinalForApp(
200 Profile* profile,
201 const std::string& name) {
202 return ExtensionPrefs::Get(profile)->app_sorting()->GetAppLaunchOrdinal(
203 crx_file::id_util::GenerateId(name));
206 void SyncAppHelper::SetAppLaunchOrdinalForApp(
207 Profile* profile,
208 const std::string& name,
209 const syncer::StringOrdinal& app_launch_ordinal) {
210 ExtensionPrefs::Get(profile)->app_sorting()->SetAppLaunchOrdinal(
211 crx_file::id_util::GenerateId(name), app_launch_ordinal);
214 void SyncAppHelper::FixNTPOrdinalCollisions(Profile* profile) {
215 ExtensionPrefs::Get(profile)->app_sorting()->FixNTPOrdinalCollisions();
218 SyncAppHelper::SyncAppHelper() : setup_completed_(false) {}
220 SyncAppHelper::~SyncAppHelper() {}