sync_app_helper.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/sync_app_helper.h"
6
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/sync_helper.h"
15#include "extensions/browser/app_sorting.h"
16#include "extensions/browser/extension_system.h"
17#include "extensions/common/extension.h"
18#include "extensions/common/extension_set.h"
19#include "extensions/common/id_util.h"
20
21namespace {
22
23struct AppState {
24  AppState();
25  ~AppState();
26  bool IsValid() const;
27  bool Equals(const AppState& other) const;
28
29  syncer::StringOrdinal app_launch_ordinal;
30  syncer::StringOrdinal page_ordinal;
31  extensions::LaunchType launch_type;
32};
33
34typedef std::map<std::string, AppState> AppStateMap;
35
36AppState::AppState() : launch_type(extensions::LAUNCH_TYPE_INVALID) {}
37
38AppState::~AppState() {}
39
40bool AppState::IsValid() const {
41  return page_ordinal.IsValid() && app_launch_ordinal.IsValid();
42}
43
44bool AppState::Equals(const AppState& other) const {
45  return app_launch_ordinal.Equals(other.app_launch_ordinal) &&
46      page_ordinal.Equals(other.page_ordinal) &&
47      launch_type == other.launch_type;
48}
49
50// Load all the app specific values for |id| into |app_state|.
51void LoadApp(ExtensionService* extension_service,
52             const std::string& id,
53             AppState* app_state) {
54  app_state->app_launch_ordinal = extension_service->extension_prefs()->
55      app_sorting()->GetAppLaunchOrdinal(id);
56  app_state->page_ordinal = extension_service->extension_prefs()->
57      app_sorting()->GetPageOrdinal(id);
58  app_state->launch_type =
59      extensions::GetLaunchTypePrefValue(extension_service->extension_prefs(),
60                                         id);
61}
62
63// Returns a map from |profile|'s installed extensions to their state.
64AppStateMap GetAppStates(Profile* profile) {
65  AppStateMap app_state_map;
66
67  ExtensionService* extension_service = profile->GetExtensionService();
68
69  scoped_ptr<const extensions::ExtensionSet> extensions(
70      extension_service->GenerateInstalledExtensionsSet());
71  for (extensions::ExtensionSet::const_iterator it = extensions->begin();
72       it != extensions->end(); ++it) {
73    if (extensions::sync_helper::IsSyncableApp(it->get())) {
74      const std::string& id = (*it)->id();
75      LoadApp(extension_service, id, &(app_state_map[id]));
76    }
77  }
78
79  const extensions::PendingExtensionManager* pending_extension_manager =
80      extension_service->pending_extension_manager();
81
82  std::list<std::string> pending_crx_ids;
83  pending_extension_manager->GetPendingIdsForUpdateCheck(&pending_crx_ids);
84
85  for (std::list<std::string>::const_iterator id = pending_crx_ids.begin();
86       id != pending_crx_ids.end(); ++id) {
87    LoadApp(extension_service, *id, &(app_state_map[*id]));
88  }
89
90  return app_state_map;
91}
92
93}  // namespace
94
95SyncAppHelper* SyncAppHelper::GetInstance() {
96  SyncAppHelper* instance = Singleton<SyncAppHelper>::get();
97  instance->SetupIfNecessary(sync_datatype_helper::test());
98  return instance;
99}
100
101void SyncAppHelper::SetupIfNecessary(SyncTest* test) {
102  if (setup_completed_)
103    return;
104
105  for (int i = 0; i < test->num_clients(); ++i) {
106    extensions::ExtensionSystem::Get(
107        test->GetProfile(i))->InitForRegularProfile(true);
108  }
109  extensions::ExtensionSystem::Get(
110      test->verifier())->InitForRegularProfile(true);
111
112  setup_completed_ = true;
113}
114
115bool SyncAppHelper::AppStatesMatch(Profile* profile1, Profile* profile2) {
116  if (!SyncExtensionHelper::GetInstance()->ExtensionStatesMatch(
117          profile1, profile2))
118    return false;
119
120  const AppStateMap& state_map1 = GetAppStates(profile1);
121  const AppStateMap& state_map2 = GetAppStates(profile2);
122  if (state_map1.size() != state_map2.size()) {
123    DVLOG(2) << "Number of Apps for profile " << profile1->GetDebugName()
124             << " does not match profile " << profile2->GetDebugName();
125    return false;
126  }
127
128  AppStateMap::const_iterator it1 = state_map1.begin();
129  AppStateMap::const_iterator it2 = state_map2.begin();
130  while (it1 != state_map1.end()) {
131    if (it1->first != it2->first) {
132      DVLOG(2) << "Apps for profile " << profile1->GetDebugName()
133               << " do not match profile " << profile2->GetDebugName();
134      return false;
135    } else if (!it1->second.IsValid()) {
136      DVLOG(2) << "Apps for profile " << profile1->GetDebugName()
137               << " are not valid.";
138      return false;
139    } else if (!it2->second.IsValid()) {
140      DVLOG(2) << "Apps for profile " << profile2->GetDebugName()
141               << " are not valid.";
142      return false;
143    } else if (!it1->second.Equals(it2->second)) {
144      DVLOG(2) << "App states for profile " << profile1->GetDebugName()
145               << " do not match profile " << profile2->GetDebugName();
146      return false;
147    }
148    ++it1;
149    ++it2;
150  }
151
152  return true;
153}
154
155syncer::StringOrdinal SyncAppHelper::GetPageOrdinalForApp(
156    Profile* profile,
157    const std::string& name) {
158  return profile->GetExtensionService()->extension_prefs()->
159      app_sorting()->GetPageOrdinal(extensions::id_util::GenerateId(name));
160}
161
162void SyncAppHelper::SetPageOrdinalForApp(
163    Profile* profile,
164    const std::string& name,
165    const syncer::StringOrdinal& page_ordinal) {
166  profile->GetExtensionService()->extension_prefs()->app_sorting()->
167      SetPageOrdinal(extensions::id_util::GenerateId(name), page_ordinal);
168}
169
170syncer::StringOrdinal SyncAppHelper::GetAppLaunchOrdinalForApp(
171    Profile* profile,
172    const std::string& name) {
173  return profile->GetExtensionService()->extension_prefs()->
174      app_sorting()->GetAppLaunchOrdinal(extensions::id_util::GenerateId(name));
175}
176
177void SyncAppHelper::SetAppLaunchOrdinalForApp(
178    Profile* profile,
179    const std::string& name,
180    const syncer::StringOrdinal& app_launch_ordinal) {
181  profile->GetExtensionService()->extension_prefs()->app_sorting()->
182      SetAppLaunchOrdinal(extensions::id_util::GenerateId(name),
183                          app_launch_ordinal);
184}
185
186void SyncAppHelper::FixNTPOrdinalCollisions(Profile* profile) {
187  profile->GetExtensionService()->extension_prefs()->app_sorting()->
188      FixNTPOrdinalCollisions();
189}
190
191SyncAppHelper::SyncAppHelper() : setup_completed_(false) {}
192
193SyncAppHelper::~SyncAppHelper() {}
194