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