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 19 namespace extensions { 20 21 ExtensionWebContentsObserver::ExtensionWebContentsObserver( 22 content::WebContents* web_contents) 23 : content::WebContentsObserver(web_contents), 24 browser_context_(web_contents->GetBrowserContext()) { 25 NotifyRenderViewType(web_contents->GetRenderViewHost()); 26 } 27 28 ExtensionWebContentsObserver::~ExtensionWebContentsObserver() {} 29 30 void 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(), url::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 case Manifest::NUM_LOAD_TYPES: 85 NOTREACHED(); 86 } 87 } 88 89 void ExtensionWebContentsObserver::NotifyRenderViewType( 90 content::RenderViewHost* render_view_host) { 91 if (render_view_host) { 92 render_view_host->Send(new ExtensionMsg_NotifyRenderViewType( 93 render_view_host->GetRoutingID(), GetViewType(web_contents()))); 94 } 95 } 96 97 const Extension* ExtensionWebContentsObserver::GetExtension( 98 content::RenderViewHost* render_view_host) { 99 std::string extension_id = GetExtensionId(render_view_host); 100 if (extension_id.empty()) 101 return NULL; 102 103 // May be null if the extension doesn't exist, for example if somebody typos 104 // a chrome-extension:// URL. 105 return ExtensionRegistry::Get(browser_context_) 106 ->GetExtensionById(extension_id, ExtensionRegistry::ENABLED); 107 } 108 109 // static 110 std::string ExtensionWebContentsObserver::GetExtensionId( 111 content::RenderViewHost* render_view_host) { 112 // Note that due to ChromeContentBrowserClient::GetEffectiveURL(), hosted apps 113 // (excluding bookmark apps) will have a chrome-extension:// URL for their 114 // site, so we can ignore that wrinkle here. 115 const GURL& site = render_view_host->GetSiteInstance()->GetSiteURL(); 116 117 if (!site.SchemeIs(kExtensionScheme)) 118 return std::string(); 119 120 return site.host(); 121 } 122 123 } // namespace extensions 124