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