Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_util.cc
index 890d8d1..6d86ca7 100644 (file)
 #include "chrome/browser/extensions/extension_util.h"
 
 #include "base/command_line.h"
-#include "chrome/browser/extensions/extension_prefs.h"
+#include "base/logging.h"
+#include "base/values.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_sync_service.h"
+#include "chrome/browser/extensions/permissions_updater.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/incognito_handler.h"
+#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
 #include "chrome/common/extensions/sync_helper.h"
+#include "content/public/browser/site_instance.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/extension_util.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_icon_set.h"
+#include "extensions/common/features/simple_feature.h"
 #include "extensions/common/manifest.h"
+#include "extensions/common/manifest_handlers/incognito_info.h"
+#include "grit/theme_resources.h"
+#include "ui/base/resource/resource_bundle.h"
 
-using extensions::Extension;
-using extensions::ExtensionPrefs;
+namespace extensions {
+namespace util {
 
-namespace extension_util {
+namespace {
+// The entry into the ExtensionPrefs for allowing an extension to script on
+// all urls without explicit permission.
+const char kExtensionAllowedOnAllUrlsPrefName[] =
+    "extension_can_script_all_urls";
 
-bool IsIncognitoEnabled(const std::string& extension_id,
-                        const ExtensionService* service) {
-  if (!service)
-    return false;
+// Returns true if |extension_id| for an external component extension should
+// always be enabled in incognito windows.
+bool IsWhitelistedForIncognito(const std::string& extension_id) {
+  static const char* kExtensionWhitelist[] = {
+    "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900
+    "D57DE394F36DC1C3220E7604C575D29C51A6C495",  // http://crbug.com/319444
+    "3F65507A3B39259B38C8173C6FFA3D12DF64CCE9"   // http://crbug.com/371562
+  };
 
-  const Extension* extension = service->GetInstalledExtension(extension_id);
-  if (extension && !extension->can_be_incognito_enabled())
-    return false;
-  // If this is an existing component extension we always allow it to
-  // work in incognito mode.
-  if (extension && extension->location() == extensions::Manifest::COMPONENT)
-    return true;
-  if (extension && extension->force_incognito_enabled())
-    return true;
+  return extensions::SimpleFeature::IsIdInList(
+      extension_id,
+      std::set<std::string>(
+          kExtensionWhitelist,
+          kExtensionWhitelist + arraysize(kExtensionWhitelist)));
+}
+}  // namespace
+
+bool IsIncognitoEnabled(const std::string& extension_id,
+                        content::BrowserContext* context) {
+  const Extension* extension = ExtensionRegistry::Get(context)->
+      GetExtensionById(extension_id, ExtensionRegistry::ENABLED);
+  if (extension) {
+    if (!extension->can_be_incognito_enabled())
+      return false;
+    // If this is an existing component extension we always allow it to
+    // work in incognito mode.
+    if (extension->location() == Manifest::COMPONENT)
+      return true;
+    if (extension->location() == Manifest::EXTERNAL_COMPONENT &&
+        IsWhitelistedForIncognito(extension_id)) {
+      return true;
+    }
+  }
 
-  // Check the prefs.
-  return service->extension_prefs()->IsIncognitoEnabled(extension_id);
+  return ExtensionPrefs::Get(context)->IsIncognitoEnabled(extension_id);
 }
 
 void SetIsIncognitoEnabled(const std::string& extension_id,
-                           ExtensionService* service,
+                           content::BrowserContext* context,
                            bool enabled) {
+  ExtensionService* service =
+      ExtensionSystem::Get(context)->extension_service();
+  CHECK(service);
   const Extension* extension = service->GetInstalledExtension(extension_id);
-  if (extension && !extension->can_be_incognito_enabled())
-    return;
-  if (extension && extension->location() == extensions::Manifest::COMPONENT) {
-    // This shouldn't be called for component extensions unless it is called
-    // by sync, for syncable component extensions.
-    // See http://crbug.com/112290 and associated CLs for the sordid history.
-    DCHECK(extensions::sync_helper::IsSyncable(extension));
-
-    // If we are here, make sure the we aren't trying to change the value.
-    DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, service));
-    return;
+
+  if (extension) {
+    if (!extension->can_be_incognito_enabled())
+      return;
+
+    if (extension->location() == Manifest::COMPONENT) {
+      // This shouldn't be called for component extensions unless it is called
+      // by sync, for syncable component extensions.
+      // See http://crbug.com/112290 and associated CLs for the sordid history.
+      DCHECK(sync_helper::IsSyncable(extension));
+
+      // If we are here, make sure the we aren't trying to change the value.
+      DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, service->profile()));
+      return;
+    }
   }
 
-  ExtensionPrefs* extension_prefs = service->extension_prefs();
+  ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(service->profile());
   // Broadcast unloaded and loaded events to update browser state. Only bother
   // if the value changed and the extension is actually enabled, since there is
   // no UI otherwise.
@@ -82,46 +125,189 @@ void SetIsIncognitoEnabled(const std::string& extension_id,
 }
 
 bool CanCrossIncognito(const Extension* extension,
-                       const ExtensionService* service) {
+                       content::BrowserContext* context) {
   // We allow the extension to see events and data from another profile iff it
   // uses "spanning" behavior and it has incognito access. "split" mode
   // extensions only see events for a matching profile.
   CHECK(extension);
-  return extension_util::IsIncognitoEnabled(extension->id(), service) &&
-         !extensions::IncognitoInfo::IsSplitMode(extension);
+  return IsIncognitoEnabled(extension->id(), context) &&
+         !IncognitoInfo::IsSplitMode(extension);
 }
 
 bool CanLoadInIncognito(const Extension* extension,
-                        const ExtensionService* service) {
+                        content::BrowserContext* context) {
+  CHECK(extension);
   if (extension->is_hosted_app())
     return true;
   // Packaged apps and regular extensions need to be enabled specifically for
   // incognito (and split mode should be set).
-  return extensions::IncognitoInfo::IsSplitMode(extension) &&
-         extension_util::IsIncognitoEnabled(extension->id(), service);
+  return IncognitoInfo::IsSplitMode(extension) &&
+         IsIncognitoEnabled(extension->id(), context);
 }
 
-bool AllowFileAccess(const Extension* extension,
-                     const ExtensionService* service) {
-  return (CommandLine::ForCurrentProcess()->HasSwitch(
-              switches::kDisableExtensionsFileAccessCheck) ||
-          service->extension_prefs()->AllowFileAccess(extension->id()));
+bool AllowFileAccess(const std::string& extension_id,
+                     content::BrowserContext* context) {
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+             switches::kDisableExtensionsFileAccessCheck) ||
+         ExtensionPrefs::Get(context)->AllowFileAccess(extension_id);
 }
 
-void SetAllowFileAccess(const Extension* extension,
-                        ExtensionService* service,
+void SetAllowFileAccess(const std::string& extension_id,
+                        content::BrowserContext* context,
                         bool allow) {
+  ExtensionService* service =
+      ExtensionSystem::Get(context)->extension_service();
+  CHECK(service);
+
   // Reload to update browser state. Only bother if the value changed and the
   // extension is actually enabled, since there is no UI otherwise.
-  bool old_allow = AllowFileAccess(extension, service);
-  if (allow == old_allow)
+  if (allow == AllowFileAccess(extension_id, context))
     return;
 
-  service->extension_prefs()->SetAllowFileAccess(extension->id(), allow);
+  ExtensionPrefs::Get(context)->SetAllowFileAccess(extension_id, allow);
 
-  bool extension_is_enabled = service->extensions()->Contains(extension->id());
+  bool extension_is_enabled = service->extensions()->Contains(extension_id);
   if (extension_is_enabled)
-    service->ReloadExtension(extension->id());
+    service->ReloadExtension(extension_id);
+}
+
+bool AllowedScriptingOnAllUrls(const std::string& extension_id,
+                               content::BrowserContext* context) {
+  bool allowed = false;
+  return ExtensionPrefs::Get(context)->ReadPrefAsBoolean(
+             extension_id,
+             kExtensionAllowedOnAllUrlsPrefName,
+             &allowed) &&
+         allowed;
+}
+
+void SetAllowedScriptingOnAllUrls(const std::string& extension_id,
+                                  content::BrowserContext* context,
+                                  bool allowed) {
+  if (allowed == AllowedScriptingOnAllUrls(extension_id, context))
+    return;  // Nothing to do here.
+
+  ExtensionPrefs::Get(context)->UpdateExtensionPref(
+      extension_id,
+      kExtensionAllowedOnAllUrlsPrefName,
+      allowed ? new base::FundamentalValue(true) : NULL);
+
+  const Extension* extension =
+      ExtensionRegistry::Get(context)->enabled_extensions().GetByID(
+          extension_id);
+  if (extension) {
+    PermissionsUpdater updater(context);
+    if (allowed)
+      updater.GrantWithheldImpliedAllHosts(extension);
+    else
+      updater.WithholdImpliedAllHosts(extension);
+  }
+}
+
+bool IsAppLaunchable(const std::string& extension_id,
+                     content::BrowserContext* context) {
+  int reason = ExtensionPrefs::Get(context)->GetDisableReasons(extension_id);
+  return !((reason & Extension::DISABLE_UNSUPPORTED_REQUIREMENT) ||
+           (reason & Extension::DISABLE_CORRUPTED));
+}
+
+bool IsAppLaunchableWithoutEnabling(const std::string& extension_id,
+                                    content::BrowserContext* context) {
+  return ExtensionRegistry::Get(context)->GetExtensionById(
+      extension_id, ExtensionRegistry::ENABLED) != NULL;
+}
+
+bool ShouldSyncExtension(const Extension* extension,
+                         content::BrowserContext* context) {
+  return sync_helper::IsSyncableExtension(extension) &&
+         !ExtensionPrefs::Get(context)->DoNotSync(extension->id());
+}
+
+bool ShouldSyncApp(const Extension* app, content::BrowserContext* context) {
+  return sync_helper::IsSyncableApp(app) &&
+         !util::IsEphemeralApp(app->id(), context) &&
+         !ExtensionPrefs::Get(context)->DoNotSync(app->id());
+}
+
+bool IsExtensionIdle(const std::string& extension_id,
+                     content::BrowserContext* context) {
+  ProcessManager* process_manager =
+      ExtensionSystem::Get(context)->process_manager();
+  DCHECK(process_manager);
+  ExtensionHost* host =
+      process_manager->GetBackgroundHostForExtension(extension_id);
+  if (host)
+    return false;
+
+  content::SiteInstance* site_instance = process_manager->GetSiteInstanceForURL(
+      Extension::GetBaseURLFromExtensionId(extension_id));
+  if (site_instance && site_instance->HasProcess())
+    return false;
+
+  return process_manager->GetRenderViewHostsForExtension(extension_id).empty();
+}
+
+GURL GetSiteForExtensionId(const std::string& extension_id,
+                           content::BrowserContext* context) {
+  return content::SiteInstance::GetSiteForURL(
+      context, Extension::GetBaseURLFromExtensionId(extension_id));
+}
+
+scoped_ptr<base::DictionaryValue> GetExtensionInfo(const Extension* extension) {
+  DCHECK(extension);
+  scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
+
+  dict->SetString("id", extension->id());
+  dict->SetString("name", extension->name());
+
+  GURL icon = extensions::ExtensionIconSource::GetIconURL(
+      extension,
+      extension_misc::EXTENSION_ICON_SMALLISH,
+      ExtensionIconSet::MATCH_BIGGER,
+      false,  // Not grayscale.
+      NULL);  // Don't set bool if exists.
+  dict->SetString("icon", icon.spec());
+
+  return dict.Pass();
+}
+
+bool HasIsolatedStorage(const ExtensionInfo& info) {
+  if (!info.extension_manifest.get())
+    return false;
+
+  std::string error;
+  scoped_refptr<const Extension> extension(Extension::Create(
+      info.extension_path,
+      info.extension_location,
+      *info.extension_manifest,
+      Extension::NO_FLAGS,
+      info.extension_id,
+      &error));
+  if (!extension.get())
+    return false;
+
+  return AppIsolationInfo::HasIsolatedStorage(extension.get());
+}
+
+bool SiteHasIsolatedStorage(const GURL& extension_site_url,
+                            content::BrowserContext* context) {
+  const Extension* extension = ExtensionRegistry::Get(context)->
+      enabled_extensions().GetExtensionOrAppByURL(extension_site_url);
+  if (!extension)
+    return false;
+
+  return AppIsolationInfo::HasIsolatedStorage(extension);
+}
+
+const gfx::ImageSkia& GetDefaultAppIcon() {
+  return *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+      IDR_APP_DEFAULT_ICON);
+}
+
+const gfx::ImageSkia& GetDefaultExtensionIcon() {
+  return *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+      IDR_EXTENSION_DEFAULT_ICON);
 }
 
-}  // namespace extension_util
+}  // namespace util
+}  // namespace extensions