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 "chrome/common/extensions/sync_helper.h" 15 #include "extensions/common/id_util.h" 16 17 namespace { 18 19 struct 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 29 typedef std::map<std::string, AppState> AppStateMap; 30 31 AppState::AppState() {} 32 33 AppState::~AppState() {} 34 35 bool AppState::IsValid() const { 36 return page_ordinal.IsValid() && app_launch_ordinal.IsValid(); 37 } 38 39 bool 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|. 45 void LoadApp(ExtensionService* extension_service, 46 const std::string& id, 47 AppState* app_state) { 48 app_state->app_launch_ordinal = extension_service->extension_prefs()-> 49 extension_sorting()->GetAppLaunchOrdinal(id); 50 app_state->page_ordinal = extension_service->extension_prefs()-> 51 extension_sorting()->GetPageOrdinal(id); 52 } 53 54 // Returns a map from |profile|'s installed extensions to their state. 55 AppStateMap 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 86 SyncAppHelper* SyncAppHelper::GetInstance() { 87 SyncAppHelper* instance = Singleton<SyncAppHelper>::get(); 88 instance->SetupIfNecessary(sync_datatype_helper::test()); 89 return instance; 90 } 91 92 void 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 106 bool 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 146 syncer::StringOrdinal SyncAppHelper::GetPageOrdinalForApp( 147 Profile* profile, 148 const std::string& name) { 149 return profile->GetExtensionService()->extension_prefs()-> 150 extension_sorting()->GetPageOrdinal( 151 extensions::id_util::GenerateId(name)); 152 } 153 154 void SyncAppHelper::SetPageOrdinalForApp( 155 Profile* profile, 156 const std::string& name, 157 const syncer::StringOrdinal& page_ordinal) { 158 profile->GetExtensionService()->extension_prefs()->extension_sorting()-> 159 SetPageOrdinal(extensions::id_util::GenerateId(name), page_ordinal); 160 } 161 162 syncer::StringOrdinal SyncAppHelper::GetAppLaunchOrdinalForApp( 163 Profile* profile, 164 const std::string& name) { 165 return profile->GetExtensionService()->extension_prefs()-> 166 extension_sorting()->GetAppLaunchOrdinal( 167 extensions::id_util::GenerateId(name)); 168 } 169 170 void SyncAppHelper::SetAppLaunchOrdinalForApp( 171 Profile* profile, 172 const std::string& name, 173 const syncer::StringOrdinal& app_launch_ordinal) { 174 profile->GetExtensionService()->extension_prefs()->extension_sorting()-> 175 SetAppLaunchOrdinal(extensions::id_util::GenerateId(name), 176 app_launch_ordinal); 177 } 178 179 void SyncAppHelper::FixNTPOrdinalCollisions(Profile* profile) { 180 profile->GetExtensionService()->extension_prefs()->extension_sorting()-> 181 FixNTPOrdinalCollisions(); 182 } 183 184 SyncAppHelper::SyncAppHelper() : setup_completed_(false) {} 185 186 SyncAppHelper::~SyncAppHelper() {} 187