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