Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 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 "base/logging.h"
      6 #include "base/stl_util-inl.h"
      7 #include "chrome/browser/extensions/extension_service.h"
      8 #include "chrome/browser/extensions/pending_extension_manager.h"
      9 #include "chrome/common/extensions/extension.h"
     10 #include "content/browser/browser_thread.h"
     11 
     12 namespace {
     13 
     14 // Install predicate used by AddFromDefaultAppList().
     15 bool IsApp(const Extension& extension) {
     16   return extension.is_app();
     17 }
     18 
     19 // Install predicate used by AddFromExternalUpdateUrl().
     20 bool AlwaysInstall(const Extension& extension) {
     21   return true;
     22 }
     23 
     24 }  // namespace
     25 
     26 PendingExtensionManager::PendingExtensionManager(
     27     const ExtensionServiceInterface& service)
     28     : service_(service) {
     29 }
     30 
     31 PendingExtensionManager::~PendingExtensionManager() {}
     32 
     33 bool PendingExtensionManager::GetById(
     34     const std::string& id,
     35     PendingExtensionInfo* out_pending_extension_info) const {
     36 
     37   PendingExtensionMap::const_iterator it = pending_extension_map_.find(id);
     38   if (it != pending_extension_map_.end()) {
     39     *out_pending_extension_info = it->second;
     40     return true;
     41   }
     42 
     43   return false;
     44 }
     45 
     46 void PendingExtensionManager::Remove(const std::string& id) {
     47   pending_extension_map_.erase(id);
     48 }
     49 
     50 bool PendingExtensionManager::IsIdPending(const std::string& id) const {
     51   return ContainsKey(pending_extension_map_, id);
     52 }
     53 
     54 bool PendingExtensionManager::AddFromSync(
     55     const std::string& id,
     56     const GURL& update_url,
     57     PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
     58     bool install_silently,
     59     bool enable_on_install,
     60     bool enable_incognito_on_install) {
     61   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     62 
     63   if (service_.GetExtensionById(id, true)) {
     64     LOG(ERROR) << "Trying to add pending extension " << id
     65                << " which already exists";
     66     return false;
     67   }
     68 
     69   const bool kIsFromSync = true;
     70   const Extension::Location kSyncLocation = Extension::INTERNAL;
     71 
     72   return AddExtensionImpl(id, update_url, should_allow_install,
     73                           kIsFromSync, install_silently,
     74                           enable_on_install,
     75                           enable_incognito_on_install,
     76                           kSyncLocation);
     77 }
     78 
     79 void PendingExtensionManager::AddFromExternalUpdateUrl(
     80     const std::string& id, const GURL& update_url,
     81     Extension::Location location) {
     82   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     83 
     84   const bool kIsFromSync = false;
     85   const bool kInstallSilently = true;
     86   const bool kEnableOnInstall = true;
     87   const bool kEnableIncognitoOnInstall = false;
     88 
     89   if (service_.IsExternalExtensionUninstalled(id))
     90     return;
     91 
     92   if (service_.GetExtensionById(id, true)) {
     93     LOG(DFATAL) << "Trying to add extension " << id
     94                 << " by external update, but it is already installed.";
     95     return;
     96   }
     97 
     98   AddExtensionImpl(id, update_url, &AlwaysInstall,
     99                    kIsFromSync, kInstallSilently,
    100                    kEnableOnInstall, kEnableIncognitoOnInstall,
    101                    location);
    102 }
    103 
    104 
    105 // TODO(akalin): Change DefaultAppList to DefaultExtensionList and
    106 // remove the IsApp() check.
    107 void PendingExtensionManager::AddFromDefaultAppList(
    108     const std::string& id) {
    109   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    110 
    111   const bool kIsFromSync = false;
    112   const bool kInstallSilently = true;
    113   const bool kEnableOnInstall = true;
    114   const bool kEnableIncognitoOnInstall = true;
    115 
    116   // This can legitimately happen if the user manually installed one of the
    117   // default apps before this code ran.
    118   if (service_.GetExtensionById(id, true))
    119     return;
    120 
    121   AddExtensionImpl(id, GURL(), &IsApp,
    122                    kIsFromSync, kInstallSilently,
    123                    kEnableOnInstall, kEnableIncognitoOnInstall,
    124                    Extension::INTERNAL);
    125 }
    126 
    127 void PendingExtensionManager::AddFromExternalFile(
    128     const std::string& id,
    129     Extension::Location location) {
    130 
    131   GURL kUpdateUrl = GURL();
    132   bool kIsFromSync = false;
    133   bool kInstallSilently = true;
    134   bool kEnableOnInstall = true;
    135   bool kEnableIncognitoOnInstall = false;
    136 
    137   pending_extension_map_[id] =
    138       PendingExtensionInfo(kUpdateUrl,
    139                            &AlwaysInstall,
    140                            kIsFromSync,
    141                            kInstallSilently,
    142                            kEnableOnInstall,
    143                            kEnableIncognitoOnInstall,
    144                            location);
    145 }
    146 
    147 bool PendingExtensionManager::AddExtensionImpl(
    148     const std::string& id, const GURL& update_url,
    149     PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install,
    150     bool is_from_sync, bool install_silently,
    151     bool enable_on_install, bool enable_incognito_on_install,
    152     Extension::Location install_source) {
    153   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    154 
    155   // Will add a pending extension record unless this variable is set to false.
    156   bool should_add_pending_record = true;
    157 
    158   if (ContainsKey(pending_extension_map_, id)) {
    159     // Bugs in this code will manifest as sporadic incorrect extension
    160     // locations in situations where multiple install sources run at the
    161     // same time. For example, on first login to a chrome os machine, an
    162     // extension may be requested by sync sync and the default extension set.
    163     // The following logging will help diagnose such issues.
    164     VLOG(1) << "Extension id " << id
    165             << " was entered for update more than once."
    166             << "  old location: " << pending_extension_map_[id].install_source()
    167             << "  new location: " << install_source;
    168 
    169     Extension::Location higher_priority_location =
    170         Extension::GetHigherPriorityLocation(
    171             install_source, pending_extension_map_[id].install_source());
    172 
    173     if (higher_priority_location == install_source) {
    174       VLOG(1) << "Overwrite existing record.";
    175 
    176     } else {
    177       VLOG(1) << "Keep existing record.";
    178       should_add_pending_record = false;
    179     }
    180   }
    181 
    182   if (should_add_pending_record) {
    183     pending_extension_map_[id] = PendingExtensionInfo(
    184         update_url,
    185         should_allow_install,
    186         is_from_sync,
    187         install_silently,
    188         enable_on_install,
    189         enable_incognito_on_install,
    190         install_source);
    191     return true;
    192   }
    193   return false;
    194 }
    195 
    196 void PendingExtensionManager::AddForTesting(
    197     const std::string& id,
    198     const PendingExtensionInfo& pending_extension_info) {
    199   pending_extension_map_[id] = pending_extension_info;
    200 }
    201