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