extension_web_contents_observer.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
1// Copyright 2014 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 "extensions/browser/extension_web_contents_observer.h" 6 7#include "content/public/browser/child_process_security_policy.h" 8#include "content/public/browser/render_process_host.h" 9#include "content/public/browser/render_view_host.h" 10#include "content/public/browser/site_instance.h" 11#include "content/public/browser/web_contents.h" 12#include "content/public/common/url_constants.h" 13#include "extensions/browser/extension_prefs.h" 14#include "extensions/browser/extension_registry.h" 15#include "extensions/browser/view_type_utils.h" 16#include "extensions/common/constants.h" 17#include "extensions/common/extension_messages.h" 18 19namespace extensions { 20 21ExtensionWebContentsObserver::ExtensionWebContentsObserver( 22 content::WebContents* web_contents) 23 : content::WebContentsObserver(web_contents), 24 browser_context_(web_contents->GetBrowserContext()) { 25 NotifyRenderViewType(web_contents->GetRenderViewHost()); 26} 27 28ExtensionWebContentsObserver::~ExtensionWebContentsObserver() {} 29 30void ExtensionWebContentsObserver::RenderViewCreated( 31 content::RenderViewHost* render_view_host) { 32 NotifyRenderViewType(render_view_host); 33 34 const Extension* extension = GetExtension(render_view_host); 35 if (!extension) 36 return; 37 38 content::RenderProcessHost* process = render_view_host->GetProcess(); 39 40 // Some extensions use chrome:// URLs. 41 // This is a temporary solution. Replace it with access to chrome-static:// 42 // once it is implemented. See: crbug.com/226927. 43 Manifest::Type type = extension->GetType(); 44 if (type == Manifest::TYPE_EXTENSION || 45 type == Manifest::TYPE_LEGACY_PACKAGED_APP || 46 (type == Manifest::TYPE_PLATFORM_APP && 47 extension->location() == Manifest::COMPONENT)) { 48 content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme( 49 process->GetID(), content::kChromeUIScheme); 50 } 51 52 // Some extensions use file:// URLs. 53 if (type == Manifest::TYPE_EXTENSION || 54 type == Manifest::TYPE_LEGACY_PACKAGED_APP) { 55 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_); 56 if (prefs->AllowFileAccess(extension->id())) { 57 content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme( 58 process->GetID(), content::kFileScheme); 59 } 60 } 61 62 switch (type) { 63 case Manifest::TYPE_EXTENSION: 64 case Manifest::TYPE_USER_SCRIPT: 65 case Manifest::TYPE_HOSTED_APP: 66 case Manifest::TYPE_LEGACY_PACKAGED_APP: 67 case Manifest::TYPE_PLATFORM_APP: 68 // Always send a Loaded message before ActivateExtension so that 69 // ExtensionDispatcher knows what Extension is active, not just its ID. 70 // This is important for classifying the Extension's JavaScript context 71 // correctly (see ExtensionDispatcher::ClassifyJavaScriptContext). 72 render_view_host->Send( 73 new ExtensionMsg_Loaded(std::vector<ExtensionMsg_Loaded_Params>( 74 1, ExtensionMsg_Loaded_Params(extension)))); 75 render_view_host->Send( 76 new ExtensionMsg_ActivateExtension(extension->id())); 77 break; 78 79 case Manifest::TYPE_UNKNOWN: 80 case Manifest::TYPE_THEME: 81 case Manifest::TYPE_SHARED_MODULE: 82 break; 83 } 84} 85 86void ExtensionWebContentsObserver::NotifyRenderViewType( 87 content::RenderViewHost* render_view_host) { 88 if (render_view_host) { 89 render_view_host->Send(new ExtensionMsg_NotifyRenderViewType( 90 render_view_host->GetRoutingID(), GetViewType(web_contents()))); 91 } 92} 93 94const Extension* ExtensionWebContentsObserver::GetExtension( 95 content::RenderViewHost* render_view_host) { 96 std::string extension_id = GetExtensionId(render_view_host); 97 if (extension_id.empty()) 98 return NULL; 99 100 // May be null if the extension doesn't exist, for example if somebody typos 101 // a chrome-extension:// URL. 102 return ExtensionRegistry::Get(browser_context_) 103 ->GetExtensionById(extension_id, ExtensionRegistry::ENABLED); 104} 105 106// static 107std::string ExtensionWebContentsObserver::GetExtensionId( 108 content::RenderViewHost* render_view_host) { 109 // Note that due to ChromeContentBrowserClient::GetEffectiveURL(), hosted apps 110 // (excluding bookmark apps) will have a chrome-extension:// URL for their 111 // site, so we can ignore that wrinkle here. 112 const GURL& site = render_view_host->GetSiteInstance()->GetSiteURL(); 113 114 if (!site.SchemeIs(kExtensionScheme)) 115 return std::string(); 116 117 return site.host(); 118} 119 120} // namespace extensions 121