15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_sync_bundle.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_sync_service.h" 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/extensions/extension_util.h" 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/sync_helper.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_change_processor.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error_factory.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ExtensionSyncBundle::ExtensionSyncBundle( 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ExtensionSyncService* extension_sync_service) 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) : extension_sync_service_(extension_sync_service) {} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSyncBundle::~ExtensionSyncBundle() {} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::SetupSync( 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChangeProcessor* sync_processor, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncErrorFactory* sync_error_factory, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::SyncDataList& initial_sync_data) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_processor_.reset(sync_processor); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_error_factory_.reset(sync_error_factory); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (syncer::SyncDataList::const_iterator i = initial_sync_data.begin(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != initial_sync_data.end(); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionSyncData extension_sync_data(*i); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddExtension(extension_sync_data.id()); 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->ProcessExtensionSyncData(extension_sync_data); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::Reset() { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_processor_.reset(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_error_factory_.reset(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) synced_extensions_.clear(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_sync_data_.clear(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncChange ExtensionSyncBundle::CreateSyncChangeToDelete( 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) const { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExtensionSyncData sync_data = 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->GetExtensionSyncData(*extension); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sync_data.GetSyncChange(syncer::SyncChange::ACTION_DELETE); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::ProcessDeletion( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id, const syncer::SyncChange& sync_change) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveExtension(extension_id); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChangeList(1, sync_change)); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncChange ExtensionSyncBundle::CreateSyncChange( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::SyncData& sync_data) { 64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const syncer::SyncDataLocal sync_data_local(sync_data); 65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (HasExtensionId(sync_data_local.GetTag())) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::SyncChange(FROM_HERE, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange::ACTION_UPDATE, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_data); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch AddExtension(sync_data_local.GetTag()); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::SyncChange(FROM_HERE, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange::ACTION_ADD, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_data); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncDataList ExtensionSyncBundle::GetAllSyncData() const { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ExtensionSyncData> extension_sync_data = 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->GetExtensionSyncDataList(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncDataList result(extension_sync_data.size()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < static_cast<int>(extension_sync_data.size()); ++i) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result[i] = extension_sync_data[i].GetSyncData(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::ProcessSyncChange( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionSyncData extension_sync_data) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_sync_data.uninstalled()) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveExtension(extension_sync_data.id()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddExtension(extension_sync_data.id()); 931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->ProcessExtensionSyncData(extension_sync_data); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::ProcessSyncChangeList( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChangeList sync_change_list) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSyncBundle::HasExtensionId( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id) const { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return synced_extensions_.find(id) != synced_extensions_.end(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSyncBundle::HasPendingExtensionId( 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id) const { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pending_sync_data_.find(id) != pending_sync_data_.end(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::AddPendingExtension( 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionSyncData& extension_sync_data) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_sync_data_[id] = extension_sync_data; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool ExtensionSyncBundle::IsSyncing() const { 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return sync_processor_ != NULL; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ExtensionSyncBundle::SyncChangeIfNeeded(const Extension& extension) { 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ExtensionSyncData extension_sync_data = 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->GetExtensionSyncData(extension); 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) syncer::SyncChangeList sync_change_list(1, extension_sync_data.GetSyncChange( 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) HasExtensionId(extension.id()) ? 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) syncer::SyncChange::ACTION_UPDATE : syncer::SyncChange::ACTION_ADD)); 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list); 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MarkPendingExtensionSynced(extension.id()); 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<ExtensionSyncData> ExtensionSyncBundle::GetPendingData() const { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ExtensionSyncData> pending_extensions; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<std::string, ExtensionSyncData>::const_iterator 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = pending_sync_data_.begin(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_sync_data_.end(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_extensions.push_back(i->second); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pending_extensions; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::GetExtensionSyncDataListHelper( 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionSet& extensions, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ExtensionSyncData>* sync_data_list) const { 147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Profile* profile = extension_sync_service_->profile(); 148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator it = extensions.begin(); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != extensions.end(); ++it) { 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Extension& extension = *it->get(); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have pending extension data for this extension, then this 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // version is out of date. We'll sync back the version we got from 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sync. 155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (IsSyncing() && util::ShouldSyncExtension(&extension, profile) && 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !HasPendingExtensionId(extension.id())) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_data_list->push_back( 1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->GetExtensionSyncData(extension)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::AddExtension(const std::string& id) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) synced_extensions_.insert(id); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::RemoveExtension(const std::string& id) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) synced_extensions_.erase(id); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSyncBundle::MarkPendingExtensionSynced(const std::string& id) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_sync_data_.erase(id); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) synced_extensions_.insert(id); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 177