diff --git a/apps/apps.gypi b/apps/apps.gypi index bcb458c6f99df7..393b9febeba5ea 100644 --- a/apps/apps.gypi +++ b/apps/apps.gypi @@ -124,6 +124,8 @@ '..', ], 'sources': [ + 'shell/renderer/shell_content_renderer_client.cc', + 'shell/renderer/shell_content_renderer_client.h', 'shell/shell_app_sorting.cc', 'shell/shell_app_sorting.h', 'shell/shell_browser_context.cc', diff --git a/apps/shell/DEPS b/apps/shell/DEPS index 4a90c8fc280744..8d6b630ad9e015 100644 --- a/apps/shell/DEPS +++ b/apps/shell/DEPS @@ -11,6 +11,7 @@ include_rules = [ "+chrome/common/chrome_paths.h", "+chrome/common/extensions/extension_file_util.h", "+chrome/common/extensions/features/base_feature_provider.h", + "+chrome/common/extensions/permissions/chrome_api_permissions.h", # Pieces of content_shell reused in app_shell. "+content/shell/browser/shell_browser_context.h", diff --git a/apps/shell/renderer/DEPS b/apps/shell/renderer/DEPS new file mode 100644 index 00000000000000..b201ed57ff58d2 --- /dev/null +++ b/apps/shell/renderer/DEPS @@ -0,0 +1,12 @@ +include_rules = [ + # Only allow includes the renderer can use. + "-content/public/browser", + "+content/public/common", + "+content/public/renderer", + "+content/public/test", + + # TODO(jamescook): Remove these. http://crbug.com/305404 + # Chrome pieces for bring-up. + "+chrome/renderer/extensions/dispatcher.h", + "+chrome/renderer/extensions/extension_helper.h", +] diff --git a/apps/shell/renderer/shell_content_renderer_client.cc b/apps/shell/renderer/shell_content_renderer_client.cc new file mode 100644 index 00000000000000..025a104cfde705 --- /dev/null +++ b/apps/shell/renderer/shell_content_renderer_client.cc @@ -0,0 +1,74 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "apps/shell/renderer/shell_content_renderer_client.h" + +#include "apps/shell/shell_extensions_client.h" +#include "chrome/renderer/extensions/dispatcher.h" +#include "chrome/renderer/extensions/extension_helper.h" +#include "content/public/renderer/render_thread.h" +#include "extensions/common/extensions_client.h" + +using blink::WebFrame; +using blink::WebString; +using content::RenderThread; + +namespace apps { + +ShellContentRendererClient::ShellContentRendererClient() {} + +ShellContentRendererClient::~ShellContentRendererClient() {} + +void ShellContentRendererClient::RenderThreadStarted() { + RenderThread* thread = RenderThread::Get(); + + extension_dispatcher_.reset(new extensions::Dispatcher()); + thread->AddObserver(extension_dispatcher_.get()); + + // TODO(jamescook): Init WebSecurityPolicy for chrome-extension: schemes. + // See ChromeContentRendererClient for details. + + extensions_client_.reset(new ShellExtensionsClient); + extensions::ExtensionsClient::Set(extensions_client_.get()); +} + +void ShellContentRendererClient::RenderFrameCreated( + content::RenderFrame* render_frame) { + // TODO(jamescook): Create ExtensionFrameHelper? This might be needed for + // Pepper plugins like Flash. +} + +void ShellContentRendererClient::RenderViewCreated( + content::RenderView* render_view) { + new extensions::ExtensionHelper(render_view, extension_dispatcher_.get()); +} + +bool ShellContentRendererClient::WillSendRequest( + blink::WebFrame* frame, + content::PageTransition transition_type, + const GURL& url, + const GURL& first_party_for_cookies, + GURL* new_url) { + // TODO(jamescook): Cause an error for bad extension scheme requests? + return false; +} + +void ShellContentRendererClient::DidCreateScriptContext( + WebFrame* frame, v8::Handle context, int extension_group, + int world_id) { + extension_dispatcher_->DidCreateScriptContext( + frame, context, extension_group, world_id); +} + +void ShellContentRendererClient::WillReleaseScriptContext( + WebFrame* frame, v8::Handle context, int world_id) { + extension_dispatcher_->WillReleaseScriptContext(frame, context, world_id); +} + +bool ShellContentRendererClient::ShouldEnableSiteIsolationPolicy() const { + // Extension renderers don't need site isolation. + return false; +} + +} // namespace apps diff --git a/apps/shell/renderer/shell_content_renderer_client.h b/apps/shell/renderer/shell_content_renderer_client.h new file mode 100644 index 00000000000000..12f95380ed63a5 --- /dev/null +++ b/apps/shell/renderer/shell_content_renderer_client.h @@ -0,0 +1,54 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef APPS_SHELL_RENDERER_SHELL_CONTENT_RENDERER_CLIENT_H_ +#define APPS_SHELL_RENDERER_SHELL_CONTENT_RENDERER_CLIENT_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/renderer/content_renderer_client.h" + +namespace extensions { +class Dispatcher; +} + +namespace apps { + +class ShellExtensionsClient; + +// Renderer initialization and runtime support for app_shell. +class ShellContentRendererClient : public content::ContentRendererClient { + public: + ShellContentRendererClient(); + virtual ~ShellContentRendererClient(); + + // content::ContentRendererClient implementation: + virtual void RenderThreadStarted() OVERRIDE; + virtual void RenderFrameCreated(content::RenderFrame* render_frame) OVERRIDE; + virtual void RenderViewCreated(content::RenderView* render_view) OVERRIDE; + virtual bool WillSendRequest(blink::WebFrame* frame, + content::PageTransition transition_type, + const GURL& url, + const GURL& first_party_for_cookies, + GURL* new_url) OVERRIDE; + virtual void DidCreateScriptContext(blink::WebFrame* frame, + v8::Handle context, + int extension_group, + int world_id) OVERRIDE; + virtual void WillReleaseScriptContext(blink::WebFrame* frame, + v8::Handle context, + int world_id) OVERRIDE; + virtual bool ShouldEnableSiteIsolationPolicy() const OVERRIDE; + + private: + scoped_ptr extensions_client_; + scoped_ptr extension_dispatcher_; + + DISALLOW_COPY_AND_ASSIGN(ShellContentRendererClient); +}; + +} // namespace apps + +#endif // APPS_SHELL_RENDERER_SHELL_CONTENT_RENDERER_CLIENT_H_ diff --git a/apps/shell/shell_browser_main_parts.cc b/apps/shell/shell_browser_main_parts.cc index 3750dd52e574e6..27d4a765d003a8 100644 --- a/apps/shell/shell_browser_main_parts.cc +++ b/apps/shell/shell_browser_main_parts.cc @@ -12,14 +12,11 @@ #include "base/command_line.h" #include "base/file_util.h" #include "base/files/file_path.h" -#include "base/path_service.h" #include "base/run_loop.h" -#include "chrome/common/chrome_paths.h" #include "components/browser_context_keyed_service/browser_context_dependency_manager.h" #include "content/public/common/result_codes.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/renderer_startup_helper.h" -#include "extensions/common/extension_paths.h" #include "ui/aura/env.h" #include "ui/aura/root_window.h" #include "ui/aura/test/test_screen.h" @@ -28,10 +25,6 @@ #include "ui/gfx/screen.h" #include "ui/wm/test/wm_test_helper.h" -#if defined(OS_CHROMEOS) -#include "chromeos/chromeos_paths.h" -#endif - using content::BrowserContext; using extensions::Extension; using extensions::ExtensionSystem; @@ -75,18 +68,6 @@ int ShellBrowserMainParts::PreCreateThreads() { void ShellBrowserMainParts::PreMainMessageLoopRun() { // NOTE: Much of this is culled from chrome/test/base/chrome_test_suite.cc - // Set up all the paths to load files. - chrome::RegisterPathProvider(); -#if defined(OS_CHROMEOS) - chromeos::RegisterPathProvider(); -#endif - extensions::RegisterPathProvider(); - - // The extensions system needs manifest data from the Chrome PAK file. - base::FilePath resources_pack_path; - PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path); - ResourceBundle::GetSharedInstance().AddDataPackFromPath( - resources_pack_path, ui::SCALE_FACTOR_NONE); // TODO(jamescook): Initialize chromeos::UserManager. diff --git a/apps/shell/shell_extensions_client.cc b/apps/shell/shell_extensions_client.cc index aa8073d04b71f6..ffd63b41357a02 100644 --- a/apps/shell/shell_extensions_client.cc +++ b/apps/shell/shell_extensions_client.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "chrome/common/extensions/features/base_feature_provider.h" +#include "chrome/common/extensions/permissions/chrome_api_permissions.h" #include "extensions/common/common_manifest_handlers.h" #include "extensions/common/manifest_handler.h" #include "extensions/common/permissions/permission_message_provider.h" @@ -25,25 +26,6 @@ namespace apps { namespace { -// TODO(jamescook): Refactor ChromeAPIPermissions to share some of the -// permissions registration for app_shell. For now, allow no permissions. -class ShellPermissionsProvider : public extensions::PermissionsProvider { - public: - ShellPermissionsProvider() {} - virtual ~ShellPermissionsProvider() {} - - virtual std::vector GetAllPermissions() const OVERRIDE { - return std::vector(); - } - - virtual std::vector GetAllAliases() const OVERRIDE { - return std::vector(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ShellPermissionsProvider); -}; - // TODO(jamescook): Refactor ChromePermissionsMessageProvider so we can share // code. class ShellPermissionMessageProvider @@ -101,8 +83,18 @@ void ShellExtensionsClient::Initialize() { const extensions::PermissionsProvider& ShellExtensionsClient::GetPermissionsProvider() const { - NOTIMPLEMENTED(); - static ShellPermissionsProvider provider; + // TODO(jamescook): app_shell needs a way to use a subset of the Chrome + // extension Features and Permissions. In particular, the lists of Features + // (including API features, manifest features and permission features) are + // listed in JSON files from c/c/e/api that are included into Chrome's + // resources.pak (_api_features.json and _permission_features.json). The + // PermissionsProvider must match the set of permissions used by the features + // in those files. We either need to make app_shell (and hence the extensions + // module) know about all possible permissions, or create a mechanism whereby + // we can build our own JSON files with only a subset of the data. For now, + // just provide all permissions Chrome knows about. Fixing this issue is + // http://crbug.com/339301 + static extensions::ChromeAPIPermissions provider; return provider; } diff --git a/apps/shell/shell_main_delegate.cc b/apps/shell/shell_main_delegate.cc index 2406ca97786017..23c91faa9a45ab 100644 --- a/apps/shell/shell_main_delegate.cc +++ b/apps/shell/shell_main_delegate.cc @@ -4,15 +4,23 @@ #include "apps/shell/shell_main_delegate.h" +#include "apps/shell/renderer/shell_content_renderer_client.h" #include "apps/shell/shell_content_browser_client.h" #include "apps/shell/shell_content_client.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/path_service.h" +#include "chrome/common/chrome_paths.h" #include "content/public/browser/browser_main_runner.h" +#include "content/public/common/content_switches.h" +#include "extensions/common/extension_paths.h" #include "ui/base/resource/resource_bundle.h" +#if defined(OS_CHROMEOS) +#include "chromeos/chromeos_paths.h" +#endif + namespace { void InitLogging() { @@ -41,11 +49,21 @@ bool ShellMainDelegate::BasicStartupComplete(int* exit_code) { InitLogging(); content_client_.reset(new ShellContentClient); SetContentClient(content_client_.get()); + + chrome::RegisterPathProvider(); +#if defined(OS_CHROMEOS) + chromeos::RegisterPathProvider(); +#endif + extensions::RegisterPathProvider(); return false; } void ShellMainDelegate::PreSandboxStartup() { - InitializeResourceBundle(); + std::string process_type = + CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kProcessType); + if (ProcessNeedsResourceBundle(process_type)) + InitializeResourceBundle(); } content::ContentBrowserClient* ShellMainDelegate::CreateContentBrowserClient() { @@ -55,13 +73,30 @@ content::ContentBrowserClient* ShellMainDelegate::CreateContentBrowserClient() { content::ContentRendererClient* ShellMainDelegate::CreateContentRendererClient() { - // TODO(jamescook): Create a ShellContentRendererClient with the extensions - // initialization pieces of ChromeContentRendererClient. - return content::ContentMainDelegate::CreateContentRendererClient(); + renderer_client_.reset(new ShellContentRendererClient); + return renderer_client_.get(); +} + +// static +bool ShellMainDelegate::ProcessNeedsResourceBundle( + const std::string& process_type) { + // The browser process has no process type flag, but needs resources. + // On Linux the zygote process opens the resources for the renderers. + return process_type.empty() || + process_type == switches::kZygoteProcess || + process_type == switches::kRendererProcess || + process_type == switches::kUtilityProcess; } void ShellMainDelegate::InitializeResourceBundle() { ui::ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL); + + // The extensions system needs manifest data from the Chrome PAK file. + // TODO(jamescook): app_shell needs its own manifest data file. + base::FilePath resources_pack_path; + PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path); + ResourceBundle::GetSharedInstance().AddDataPackFromPath( + resources_pack_path, ui::SCALE_FACTOR_NONE); } } // namespace apps diff --git a/apps/shell/shell_main_delegate.h b/apps/shell/shell_main_delegate.h index 19f033356e38a5..14f56589df52f2 100644 --- a/apps/shell/shell_main_delegate.h +++ b/apps/shell/shell_main_delegate.h @@ -13,6 +13,7 @@ namespace apps { class ShellContentBrowserClient; class ShellContentClient; +class ShellContentRendererClient; class ShellMainDelegate : public content::ContentMainDelegate { public: @@ -26,11 +27,17 @@ class ShellMainDelegate : public content::ContentMainDelegate { virtual content::ContentRendererClient* CreateContentRendererClient() OVERRIDE; + private: + // |process_type| is zygote, renderer, utility, etc. Returns true if the + // process needs data from resources.pak. + static bool ProcessNeedsResourceBundle(const std::string& process_type); + + // Initializes the resource bundle and resources.pak. static void InitializeResourceBundle(); - private: scoped_ptr content_client_; scoped_ptr browser_client_; + scoped_ptr renderer_client_; DISALLOW_COPY_AND_ASSIGN(ShellMainDelegate); }; diff --git a/extensions/common/extensions_client.cc b/extensions/common/extensions_client.cc index ccca164a5ff5e1..89795b86e45cb0 100644 --- a/extensions/common/extensions_client.cc +++ b/extensions/common/extensions_client.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/basictypes.h" +#include "base/logging.h" #include "extensions/common/extensions_client.h" namespace extensions { @@ -14,6 +15,7 @@ ExtensionsClient* g_client = NULL; } // namespace ExtensionsClient* ExtensionsClient::Get() { + DCHECK(g_client); return g_client; } diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h index f50dada3745760..6427e5794b173e 100644 --- a/extensions/common/permissions/api_permission.h +++ b/extensions/common/permissions/api_permission.h @@ -311,8 +311,7 @@ class APIPermissionInfo { } private: - // Instances should only be constructed from within a - // PermissionsInfo::Delegate. + // Instances should only be constructed from within a PermissionsProvider. friend class ChromeAPIPermissions; // Implementations of APIPermission will want to get the permission message, // but this class's implementation should be hidden from everyone else. diff --git a/extensions/common/permissions/permission_set.cc b/extensions/common/permissions/permission_set.cc index 8ec1cbedd02658..fd32d4e83d64ad 100644 --- a/extensions/common/permissions/permission_set.cc +++ b/extensions/common/permissions/permission_set.cc @@ -180,6 +180,7 @@ bool PermissionSet::HasAPIPermission( bool PermissionSet::HasAPIPermission(const std::string& permission_name) const { const APIPermissionInfo* permission = PermissionsInfo::GetInstance()->GetByName(permission_name); + // Ensure our PermissionsProvider is aware of this permission. CHECK(permission) << permission_name; return (permission && apis_.count(permission->id())); } diff --git a/extensions/common/permissions/permissions_info.cc b/extensions/common/permissions/permissions_info.cc index bac3d9c18e8e4f..e4684aa52235b7 100644 --- a/extensions/common/permissions/permissions_info.cc +++ b/extensions/common/permissions/permissions_info.cc @@ -64,7 +64,6 @@ bool PermissionsInfo::HasChildPermissions(const std::string& name) const { PermissionsInfo::PermissionsInfo() : hosted_app_permission_count_(0), permission_count_(0) { - DCHECK(ExtensionsClient::Get()); InitializeWithProvider(ExtensionsClient::Get()->GetPermissionsProvider()); }