| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/common/extensions/sync_helper.h" |
| |
| #include "base/logging.h" |
| #include "chrome/common/extensions/api/plugins/plugins_handler.h" |
| #include "chrome/common/extensions/extension_constants.h" |
| #include "chrome/common/extensions/manifest_url_handler.h" |
| #include "extensions/common/extension.h" |
| #include "extensions/common/manifest.h" |
| #include "extensions/common/permissions/permissions_data.h" |
| |
| namespace extensions { |
| namespace sync_helper { |
| |
| namespace { |
| |
| enum SyncType { |
| SYNC_TYPE_NONE = 0, |
| SYNC_TYPE_EXTENSION, |
| SYNC_TYPE_APP |
| }; |
| |
| SyncType GetSyncType(const Extension* extension) { |
| if (!IsSyncable(extension)) { |
| // We have a non-standard location. |
| return SYNC_TYPE_NONE; |
| } |
| |
| // Disallow extensions with non-gallery auto-update URLs for now. |
| // |
| // TODO(akalin): Relax this restriction once we've put in UI to |
| // approve synced extensions. |
| if (!ManifestURL::GetUpdateURL(extension).is_empty() && |
| !ManifestURL::UpdatesFromGallery(extension)) { |
| return SYNC_TYPE_NONE; |
| } |
| |
| // Disallow extensions with native code plugins. |
| // |
| // TODO(akalin): Relax this restriction once we've put in UI to |
| // approve synced extensions. |
| if (PluginInfo::HasPlugins(extension) || |
| extension->permissions_data()->HasAPIPermission(APIPermission::kPlugin)) { |
| return SYNC_TYPE_NONE; |
| } |
| |
| switch (extension->GetType()) { |
| case Manifest::TYPE_EXTENSION: |
| return SYNC_TYPE_EXTENSION; |
| |
| case Manifest::TYPE_USER_SCRIPT: |
| // We only want to sync user scripts with gallery update URLs. |
| if (ManifestURL::UpdatesFromGallery(extension)) |
| return SYNC_TYPE_EXTENSION; |
| return SYNC_TYPE_NONE; |
| |
| case Manifest::TYPE_HOSTED_APP: |
| case Manifest::TYPE_LEGACY_PACKAGED_APP: |
| case Manifest::TYPE_PLATFORM_APP: |
| return SYNC_TYPE_APP; |
| |
| case Manifest::TYPE_UNKNOWN: |
| // Confusingly, themes are actually synced. |
| // TODO(yoz): Make this look less inconsistent. |
| case Manifest::TYPE_THEME: |
| case Manifest::TYPE_SHARED_MODULE: |
| return SYNC_TYPE_NONE; |
| |
| case Manifest::NUM_LOAD_TYPES: |
| NOTREACHED(); |
| } |
| NOTREACHED(); |
| return SYNC_TYPE_NONE; |
| } |
| |
| } // namespace |
| |
| bool IsSyncable(const Extension* extension) { |
| // TODO(akalin): Figure out if we need to allow some other types. |
| |
| // Default apps are not synced because otherwise they will pollute profiles |
| // that don't already have them. Specially, if a user doesn't have default |
| // apps, creates a new profile (which get default apps) and then enables sync |
| // for it, then their profile everywhere gets the default apps. |
| bool is_syncable = (extension->location() == Manifest::INTERNAL && |
| !extension->was_installed_by_default()); |
| // Sync the chrome web store to maintain its position on the new tab page. |
| is_syncable |= (extension->id() == extension_misc::kWebStoreAppId); |
| // Sync the chrome component app to maintain its position on the app list. |
| is_syncable |= (extension->id() == extension_misc::kChromeAppId); |
| return is_syncable; |
| } |
| |
| bool IsSyncableExtension(const Extension* extension) { |
| return GetSyncType(extension) == SYNC_TYPE_EXTENSION; |
| } |
| |
| bool IsSyncableApp(const Extension* extension) { |
| return GetSyncType(extension) == SYNC_TYPE_APP; |
| } |
| |
| } // namespace sync_helper |
| } // namespace extensions |