extension_util.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2010 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/sync/glue/extension_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/scoped_ptr.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util-inl.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/version.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/extensions/extension_prefs.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extensions_service.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/protocol/extension_specifics.pb.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionType GetExtensionType(const Extension& extension) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension.is_theme()) { 24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return THEME; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension.is_app()) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return APP; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension.converted_from_user_script()) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension.update_url().is_empty()) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LOCAL_USER_SCRIPT; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UPDATEABLE_USER_SCRIPT; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Otherwise, we just have a regular extension. 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return EXTENSION; 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Keep this in sync with the above function. 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// TODO(akalin): Or just hurry up and remove this! 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochExtensionType GetExtensionTypeFromUninstalledExtensionInfo( 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UninstalledExtensionInfo& uninstalled_extension_info) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninstalled_extension_info.is_theme) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return THEME; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (uninstalled_extension_info.is_app) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return APP; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninstalled_extension_info.converted_from_user_script) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninstalled_extension_info.update_url.is_empty()) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LOCAL_USER_SCRIPT; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UPDATEABLE_USER_SCRIPT; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EXTENSION; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsExtensionValid(const Extension& extension) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(akalin): Figure out if we need to allow some other types. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension.location() != Extension::INTERNAL) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have a non-standard location. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disallow extensions with non-gallery auto-update URLs for now. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(akalin): Relax this restriction once we've put in UI to 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // approve synced extensions. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension.update_url().is_empty() && 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (extension.update_url() != 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL(extension_urls::kGalleryUpdateHttpUrl)) && 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (extension.update_url() != 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL(extension_urls::kGalleryUpdateHttpsUrl))) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disallow extensions with native code plugins. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(akalin): Relax this restriction once we've put in UI to 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // approve synced extensions. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension.plugins().empty()) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsExtensionValidAndSyncable(const Extension& extension, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionTypeSet& allowed_types) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsExtensionValid(extension) && 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContainsKey(allowed_types, GetExtensionType(extension)); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ExtensionSpecificsToString( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::ExtensionSpecifics& specifics) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::stringstream ss; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << "{ "; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << "id: " << specifics.id() << ", "; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << "version: " << specifics.version() << ", "; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << "update_url: " << specifics.update_url() << ", "; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << "enabled: " << specifics.enabled() << ", "; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << "incognito_enabled: " << specifics.incognito_enabled() << ", "; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << "name: " << specifics.name(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss << " }"; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ss.str(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsExtensionSpecificsValid( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::ExtensionSpecifics& specifics) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Extension::IdIsValid(specifics.id())) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Version> version( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version::GetVersionFromString(specifics.version())); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!version.get()) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The update URL must be either empty or valid. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL update_url(specifics.update_url()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!update_url.is_empty() && !update_url.is_valid()) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DcheckIsExtensionSpecificsValid( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::ExtensionSpecifics& specifics) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsExtensionSpecificsValid(specifics)) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ExtensionSpecificsToString(specifics); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AreExtensionSpecificsEqual(const sync_pb::ExtensionSpecifics& a, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::ExtensionSpecifics& b) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(akalin): Figure out if we have to worry about version/URL 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // strings that are not identical but map to the same object. 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ((a.id() == b.id()) && 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (a.version() == b.version()) && 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (a.update_url() == b.update_url()) && 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (a.enabled() == b.enabled()) && 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (a.incognito_enabled() == b.incognito_enabled()) && 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (a.name() == b.name())); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsExtensionSpecificsUnset( 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::ExtensionSpecifics& specifics) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AreExtensionSpecificsEqual(specifics, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::ExtensionSpecifics()); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyUserProperties( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::ExtensionSpecifics& specifics, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::ExtensionSpecifics* dest_specifics) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dest_specifics); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_specifics->set_enabled(specifics.enabled()); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_specifics->set_incognito_enabled(specifics.incognito_enabled()); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CopyNonUserProperties( 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const sync_pb::ExtensionSpecifics& specifics, 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_pb::ExtensionSpecifics* dest_specifics) { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(dest_specifics); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_pb::ExtensionSpecifics old_dest_specifics(*dest_specifics); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *dest_specifics = specifics; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CopyUserProperties(old_dest_specifics, dest_specifics); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AreExtensionSpecificsUserPropertiesEqual( 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const sync_pb::ExtensionSpecifics& a, 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const sync_pb::ExtensionSpecifics& b) { 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sync_pb::ExtensionSpecifics a_user_properties, b_user_properties; 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CopyUserProperties(a, &a_user_properties); 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CopyUserProperties(b, &b_user_properties); 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return AreExtensionSpecificsEqual(a_user_properties, b_user_properties); 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool AreExtensionSpecificsNonUserPropertiesEqual( 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const sync_pb::ExtensionSpecifics& a, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::ExtensionSpecifics& b) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::ExtensionSpecifics a_non_user_properties, b_non_user_properties; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyNonUserProperties(a, &a_non_user_properties); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyNonUserProperties(b, &b_non_user_properties); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AreExtensionSpecificsEqual( 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_non_user_properties, b_non_user_properties); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetExtensionSpecifics(const Extension& extension, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionPrefs* extension_prefs, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::ExtensionSpecifics* specifics) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id = extension.id(); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled = 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs->GetExtensionState(id) == Extension::ENABLED; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool incognito_enabled = extension_prefs->IsIncognitoEnabled(id); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetExtensionSpecificsHelper(extension, enabled, incognito_enabled, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) specifics); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetExtensionSpecificsHelper(const Extension& extension, 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool enabled, bool incognito_enabled, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::ExtensionSpecifics* specifics) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsExtensionValid(extension)); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id = extension.id(); 211 specifics->set_id(id); 212 specifics->set_version(extension.VersionString()); 213 specifics->set_update_url(extension.update_url().spec()); 214 specifics->set_enabled(enabled); 215 specifics->set_incognito_enabled(incognito_enabled); 216 specifics->set_name(extension.name()); 217 DcheckIsExtensionSpecificsValid(*specifics); 218} 219 220bool IsExtensionOutdated(const Extension& extension, 221 const sync_pb::ExtensionSpecifics& specifics) { 222 DCHECK(IsExtensionValid(extension)); 223 DcheckIsExtensionSpecificsValid(specifics); 224 scoped_ptr<Version> specifics_version( 225 Version::GetVersionFromString(specifics.version())); 226 if (!specifics_version.get()) { 227 // If version is invalid, assume we're up-to-date. 228 return false; 229 } 230 return extension.version()->CompareTo(*specifics_version) < 0; 231} 232 233void SetExtensionProperties( 234 const sync_pb::ExtensionSpecifics& specifics, 235 ExtensionsService* extensions_service, Extension* extension) { 236 DcheckIsExtensionSpecificsValid(specifics); 237 CHECK(extensions_service); 238 CHECK(extension); 239 DCHECK(IsExtensionValid(*extension)); 240 const std::string& id = extension->id(); 241 GURL update_url(specifics.update_url()); 242 if (update_url != extension->update_url()) { 243 LOG(WARNING) << "specifics for extension " << id 244 << "has a different update URL than the extension: " 245 << update_url.spec() << " vs. " << extension->update_url(); 246 } 247 ExtensionPrefs* extension_prefs = extensions_service->extension_prefs(); 248 bool enabled = extension_prefs->GetExtensionState(id) == Extension::ENABLED; 249 if (enabled && !specifics.enabled()) { 250 extensions_service->DisableExtension(id); 251 } else if (!enabled && specifics.enabled()) { 252 extensions_service->EnableExtension(id); 253 } 254 bool incognito_enabled = extension_prefs->IsIncognitoEnabled(id); 255 if (incognito_enabled != specifics.incognito_enabled()) { 256 extensions_service->SetIsIncognitoEnabled( 257 extension, specifics.incognito_enabled()); 258 } 259 if (specifics.name() != extension->name()) { 260 LOG(WARNING) << "specifics for extension " << id 261 << "has a different name than the extension: " 262 << specifics.name() << " vs. " << extension->name(); 263 } 264} 265 266void MergeExtensionSpecifics( 267 const sync_pb::ExtensionSpecifics& specifics, 268 bool merge_user_properties, 269 sync_pb::ExtensionSpecifics* merged_specifics) { 270 DcheckIsExtensionSpecificsValid(*merged_specifics); 271 DcheckIsExtensionSpecificsValid(specifics); 272 DCHECK_EQ(specifics.id(), merged_specifics->id()); 273 // TODO(akalin): Merge enabled permissions when we sync those. 274 scoped_ptr<Version> version( 275 Version::GetVersionFromString(specifics.version())); 276 CHECK(version.get()); 277 scoped_ptr<Version> merged_version( 278 Version::GetVersionFromString(merged_specifics->version())); 279 CHECK(merged_version.get()); 280 if (version->CompareTo(*merged_version) >= 0) { 281 // |specifics| has a more recent or the same version, so merge it 282 // in. 283 CopyNonUserProperties(specifics, merged_specifics); 284 if (merge_user_properties) { 285 CopyUserProperties(specifics, merged_specifics); 286 } 287 } 288} 289 290} // namespace browser_sync 291