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/browser/extensions/extension_util.h"
      6 
      7 #include "base/command_line.h"
      8 #include "chrome/browser/extensions/extension_prefs.h"
      9 #include "chrome/browser/extensions/extension_service.h"
     10 #include "chrome/browser/extensions/extension_sync_service.h"
     11 #include "chrome/common/chrome_switches.h"
     12 #include "chrome/common/extensions/sync_helper.h"
     13 #include "extensions/common/extension.h"
     14 #include "extensions/common/manifest.h"
     15 #include "extensions/common/manifest_handlers/incognito_info.h"
     16 
     17 using extensions::Extension;
     18 using extensions::ExtensionPrefs;
     19 
     20 namespace extension_util {
     21 
     22 bool IsIncognitoEnabled(const std::string& extension_id,
     23                         const ExtensionService* service) {
     24   if (!service)
     25     return false;
     26 
     27   const Extension* extension = service->GetInstalledExtension(extension_id);
     28   if (extension && !extension->can_be_incognito_enabled())
     29     return false;
     30   // If this is an existing component extension we always allow it to
     31   // work in incognito mode.
     32   if (extension && extension->location() == extensions::Manifest::COMPONENT)
     33     return true;
     34   if (extension && extension->force_incognito_enabled())
     35     return true;
     36 
     37   // Check the prefs.
     38   return service->extension_prefs()->IsIncognitoEnabled(extension_id);
     39 }
     40 
     41 void SetIsIncognitoEnabled(const std::string& extension_id,
     42                            ExtensionService* service,
     43                            bool enabled) {
     44   const Extension* extension = service->GetInstalledExtension(extension_id);
     45   if (extension && !extension->can_be_incognito_enabled())
     46     return;
     47   if (extension && extension->location() == extensions::Manifest::COMPONENT) {
     48     // This shouldn't be called for component extensions unless it is called
     49     // by sync, for syncable component extensions.
     50     // See http://crbug.com/112290 and associated CLs for the sordid history.
     51     DCHECK(extensions::sync_helper::IsSyncable(extension));
     52 
     53     // If we are here, make sure the we aren't trying to change the value.
     54     DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, service));
     55     return;
     56   }
     57 
     58   ExtensionPrefs* extension_prefs = service->extension_prefs();
     59   // Broadcast unloaded and loaded events to update browser state. Only bother
     60   // if the value changed and the extension is actually enabled, since there is
     61   // no UI otherwise.
     62   bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id);
     63   if (enabled == old_enabled)
     64     return;
     65 
     66   extension_prefs->SetIsIncognitoEnabled(extension_id, enabled);
     67 
     68   bool extension_is_enabled = service->extensions()->Contains(extension_id);
     69 
     70   // When we reload the extension the ID may be invalidated if we've passed it
     71   // by const ref everywhere. Make a copy to be safe.
     72   std::string id = extension_id;
     73   if (extension_is_enabled)
     74     service->ReloadExtension(id);
     75 
     76   // Reloading the extension invalidates the |extension| pointer.
     77   extension = service->GetInstalledExtension(id);
     78   if (extension) {
     79     ExtensionSyncService::Get(service->profile())->
     80         SyncExtensionChangeIfNeeded(*extension);
     81   }
     82 }
     83 
     84 bool CanCrossIncognito(const Extension* extension,
     85                        const ExtensionService* service) {
     86   // We allow the extension to see events and data from another profile iff it
     87   // uses "spanning" behavior and it has incognito access. "split" mode
     88   // extensions only see events for a matching profile.
     89   CHECK(extension);
     90   return extension_util::IsIncognitoEnabled(extension->id(), service) &&
     91          !extensions::IncognitoInfo::IsSplitMode(extension);
     92 }
     93 
     94 bool CanLoadInIncognito(const Extension* extension,
     95                         const ExtensionService* service) {
     96   if (extension->is_hosted_app())
     97     return true;
     98   // Packaged apps and regular extensions need to be enabled specifically for
     99   // incognito (and split mode should be set).
    100   return extensions::IncognitoInfo::IsSplitMode(extension) &&
    101          extension_util::IsIncognitoEnabled(extension->id(), service);
    102 }
    103 
    104 bool AllowFileAccess(const Extension* extension,
    105                      const ExtensionService* service) {
    106   return (CommandLine::ForCurrentProcess()->HasSwitch(
    107               switches::kDisableExtensionsFileAccessCheck) ||
    108           service->extension_prefs()->AllowFileAccess(extension->id()));
    109 }
    110 
    111 void SetAllowFileAccess(const Extension* extension,
    112                         ExtensionService* service,
    113                         bool allow) {
    114   // Reload to update browser state. Only bother if the value changed and the
    115   // extension is actually enabled, since there is no UI otherwise.
    116   bool old_allow = AllowFileAccess(extension, service);
    117   if (allow == old_allow)
    118     return;
    119 
    120   service->extension_prefs()->SetAllowFileAccess(extension->id(), allow);
    121 
    122   bool extension_is_enabled = service->extensions()->Contains(extension->id());
    123   if (extension_is_enabled)
    124     service->ReloadExtension(extension->id());
    125 }
    126 
    127 bool IsAppLaunchable(const std::string& extension_id,
    128                      const ExtensionService* service) {
    129   return !(service->extension_prefs()->GetDisableReasons(extension_id) &
    130            Extension::DISABLE_UNSUPPORTED_REQUIREMENT);
    131 }
    132 
    133 bool IsAppLaunchableWithoutEnabling(const std::string& extension_id,
    134                                     const ExtensionService* service) {
    135   const Extension* launchable_extension = service->GetExtensionById(
    136       extension_id, ExtensionService::INCLUDE_ENABLED);
    137   return launchable_extension != NULL;
    138 }
    139 
    140 }  // namespace extension_util
    141