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