1 // Copyright 2013 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/common/extensions/sync_helper.h" 6 7 #include "base/logging.h" 8 #include "chrome/common/extensions/api/plugins/plugins_handler.h" 9 #include "chrome/common/extensions/extension_constants.h" 10 #include "chrome/common/extensions/manifest_url_handler.h" 11 #include "extensions/common/constants.h" 12 #include "extensions/common/extension.h" 13 #include "extensions/common/manifest.h" 14 #include "extensions/common/permissions/permissions_data.h" 15 16 namespace extensions { 17 namespace sync_helper { 18 19 namespace { 20 21 enum SyncType { 22 SYNC_TYPE_NONE = 0, 23 SYNC_TYPE_EXTENSION, 24 SYNC_TYPE_APP 25 }; 26 27 SyncType GetSyncType(const Extension* extension) { 28 if (!IsSyncable(extension)) { 29 // We have a non-standard location. 30 return SYNC_TYPE_NONE; 31 } 32 33 // Disallow extensions with non-gallery auto-update URLs for now. 34 // 35 // TODO(akalin): Relax this restriction once we've put in UI to 36 // approve synced extensions. 37 if (!ManifestURL::GetUpdateURL(extension).is_empty() && 38 !ManifestURL::UpdatesFromGallery(extension)) { 39 return SYNC_TYPE_NONE; 40 } 41 42 // Disallow extensions with native code plugins. 43 // 44 // TODO(akalin): Relax this restriction once we've put in UI to 45 // approve synced extensions. 46 if (PluginInfo::HasPlugins(extension) || 47 extension->permissions_data()->HasAPIPermission(APIPermission::kPlugin)) { 48 return SYNC_TYPE_NONE; 49 } 50 51 switch (extension->GetType()) { 52 case Manifest::TYPE_EXTENSION: 53 return SYNC_TYPE_EXTENSION; 54 55 case Manifest::TYPE_USER_SCRIPT: 56 // We only want to sync user scripts with gallery update URLs. 57 if (ManifestURL::UpdatesFromGallery(extension)) 58 return SYNC_TYPE_EXTENSION; 59 return SYNC_TYPE_NONE; 60 61 case Manifest::TYPE_HOSTED_APP: 62 case Manifest::TYPE_LEGACY_PACKAGED_APP: 63 case Manifest::TYPE_PLATFORM_APP: 64 return SYNC_TYPE_APP; 65 66 case Manifest::TYPE_UNKNOWN: 67 // Confusingly, themes are actually synced. 68 // TODO(yoz): Make this look less inconsistent. 69 case Manifest::TYPE_THEME: 70 case Manifest::TYPE_SHARED_MODULE: 71 return SYNC_TYPE_NONE; 72 73 case Manifest::NUM_LOAD_TYPES: 74 NOTREACHED(); 75 } 76 NOTREACHED(); 77 return SYNC_TYPE_NONE; 78 } 79 80 } // namespace 81 82 bool IsSyncable(const Extension* extension) { 83 // TODO(akalin): Figure out if we need to allow some other types. 84 85 // Default apps are not synced because otherwise they will pollute profiles 86 // that don't already have them. Specially, if a user doesn't have default 87 // apps, creates a new profile (which get default apps) and then enables sync 88 // for it, then their profile everywhere gets the default apps. 89 bool is_syncable = (extension->location() == Manifest::INTERNAL && 90 !extension->was_installed_by_default()); 91 // Sync the chrome web store to maintain its position on the new tab page. 92 is_syncable |= (extension->id() == extensions::kWebStoreAppId); 93 // Sync the chrome component app to maintain its position on the app list. 94 is_syncable |= (extension->id() == extension_misc::kChromeAppId); 95 return is_syncable; 96 } 97 98 bool IsSyncableExtension(const Extension* extension) { 99 return GetSyncType(extension) == SYNC_TYPE_EXTENSION; 100 } 101 102 bool IsSyncableApp(const Extension* extension) { 103 return GetSyncType(extension) == SYNC_TYPE_APP; 104 } 105 106 } // namespace sync_helper 107 } // namespace extensions 108