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