Home | History | Annotate | Download | only in extensions
      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