summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-16 21:23:47 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-16 21:23:47 +0000
commitb32c76fc04ba5e17ae394f026542883cf8037a57 (patch)
tree1e06fec564ea11d33b8f38717366e45e6f0a3ced /apps
parenta208843d74b70f8d728c3b9e73de9e990393852d (diff)
downloadchromium_src-b32c76fc04ba5e17ae394f026542883cf8037a57.zip
chromium_src-b32c76fc04ba5e17ae394f026542883cf8037a57.tar.gz
chromium_src-b32c76fc04ba5e17ae394f026542883cf8037a57.tar.bz2
app_shell: Make renderer run background page JavaScript
* Install URL protocol handler for chrome-extension:// and chrome-extension-resource:// * Allow extension urls to be handled. * Register extensions with IO thread extension InfoMap. * Bonus: app_shell no longer crashes on startup. With this change an extension background page can print "Hello world" using console.log(). BUG=288226,332982 TEST=browser_tests. Also run app_shell --app=/path/to/extension with an extension with background.js. The JavaScript executes and console.log() works. Review URL: https://codereview.chromium.org/136453005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245325 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'apps')
-rw-r--r--apps/shell/DEPS2
-rw-r--r--apps/shell/shell_browser_main_parts.h4
-rw-r--r--apps/shell/shell_content_browser_client.cc110
-rw-r--r--apps/shell/shell_content_browser_client.h17
-rw-r--r--apps/shell/shell_extension_system.cc26
-rw-r--r--apps/shell/shell_extension_system.h4
6 files changed, 155 insertions, 8 deletions
diff --git a/apps/shell/DEPS b/apps/shell/DEPS
index 2ac93a1..4a90c8f 100644
--- a/apps/shell/DEPS
+++ b/apps/shell/DEPS
@@ -6,6 +6,8 @@ include_rules = [
# TODO(jamescook): Remove these. http://crbug.com/305404
# Chrome pieces for bring-up.
+ "+chrome/browser/extensions/extension_protocols.h",
+ "+chrome/browser/extensions/extension_resource_protocols.h",
"+chrome/common/chrome_paths.h",
"+chrome/common/extensions/extension_file_util.h",
"+chrome/common/extensions/features/base_feature_provider.h",
diff --git a/apps/shell/shell_browser_main_parts.h b/apps/shell/shell_browser_main_parts.h
index 21a11c4..62ff772 100644
--- a/apps/shell/shell_browser_main_parts.h
+++ b/apps/shell/shell_browser_main_parts.h
@@ -46,6 +46,10 @@ class ShellBrowserMainParts : public content::BrowserMainParts,
return browser_context_.get();
}
+ extensions::ShellExtensionSystem* extension_system() {
+ return extension_system_;
+ }
+
// BrowserMainParts overrides.
virtual void PreEarlyInitialization() OVERRIDE;
virtual void PreMainMessageLoopStart() OVERRIDE;
diff --git a/apps/shell/shell_content_browser_client.cc b/apps/shell/shell_content_browser_client.cc
index d269965..589028c 100644
--- a/apps/shell/shell_content_browser_client.cc
+++ b/apps/shell/shell_content_browser_client.cc
@@ -6,7 +6,25 @@
#include "apps/shell/shell_browser_context.h"
#include "apps/shell/shell_browser_main_parts.h"
+#include "apps/shell/shell_extension_system.h"
+#include "base/command_line.h"
+#include "chrome/browser/extensions/extension_protocols.h"
+#include "chrome/browser/extensions/extension_resource_protocols.h"
+#include "chrome/common/chrome_switches.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/site_instance.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
#include "content/shell/browser/shell_browser_context.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/info_map.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#include "url/gurl.h"
+
+using content::BrowserThread;
+using extensions::ExtensionRegistry;
namespace apps {
@@ -27,9 +45,99 @@ net::URLRequestContextGetter*
ShellContentBrowserClient::CreateRequestContext(
content::BrowserContext* content_browser_context,
content::ProtocolHandlerMap* protocol_handlers) {
- // TODO(jamescook): Should this be an off-the-record context?
+ // Handle chrome-extension: and chrome-extension-resource: requests.
+ extensions::InfoMap* extension_info_map =
+ browser_main_parts_->extension_system()->info_map();
+ (*protocol_handlers)[extensions::kExtensionScheme] =
+ linked_ptr<net::URLRequestJobFactory::ProtocolHandler>(
+ CreateExtensionProtocolHandler(false /*is_incognito*/,
+ extension_info_map));
+ (*protocol_handlers)[extensions::kExtensionResourceScheme] =
+ linked_ptr<net::URLRequestJobFactory::ProtocolHandler>(
+ CreateExtensionResourceProtocolHandler());
+ // Let content::ShellBrowserContext handle the rest of the setup.
return browser_main_parts_->browser_context()->CreateRequestContext(
protocol_handlers);
}
+bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
+ if (!url.is_valid())
+ return false;
+ // Keep in sync with ProtocolHandlers added in CreateRequestContext() and in
+ // content::ShellURLRequestContextGetter::GetURLRequestContext().
+ static const char* const kProtocolList[] = {
+ chrome::kBlobScheme,
+ chrome::kChromeUIScheme,
+ chrome::kChromeDevToolsScheme,
+ chrome::kDataScheme,
+ content::kFileScheme,
+ content::kFileSystemScheme,
+ extensions::kExtensionScheme,
+ extensions::kExtensionResourceScheme,
+ };
+ for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
+ if (url.scheme() == kProtocolList[i])
+ return true;
+ }
+ return false;
+}
+
+void ShellContentBrowserClient::SiteInstanceGotProcess(
+ content::SiteInstance* site_instance) {
+ // If this isn't an extension renderer there's nothing to do.
+ const extensions::Extension* extension = GetExtension(site_instance);
+ if (!extension)
+ return;
+
+ // TODO(jamescook): Add to extension service process_map().
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&extensions::InfoMap::RegisterExtensionProcess,
+ browser_main_parts_->extension_system()->info_map(),
+ extension->id(),
+ site_instance->GetProcess()->GetID(),
+ site_instance->GetId()));
+}
+
+void ShellContentBrowserClient::SiteInstanceDeleting(
+ content::SiteInstance* site_instance) {
+ // If this isn't an extension renderer there's nothing to do.
+ const extensions::Extension* extension = GetExtension(site_instance);
+ if (!extension)
+ return;
+
+ // TODO(jamescook): Remove from extension service process_map().
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&extensions::InfoMap::UnregisterExtensionProcess,
+ browser_main_parts_->extension_system()->info_map(),
+ extension->id(),
+ site_instance->GetProcess()->GetID(),
+ site_instance->GetId()));
+}
+
+void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
+ CommandLine* command_line, int child_process_id) {
+ std::string process_type =
+ command_line->GetSwitchValueASCII(switches::kProcessType);
+ if (process_type == switches::kRendererProcess) {
+ // TODO(jamescook): Should we check here if the process is in the extension
+ // service process map, or can we assume all renderers are extension
+ // renderers?
+ command_line->AppendSwitch(switches::kExtensionProcess);
+ }
+}
+
+const extensions::Extension* ShellContentBrowserClient::GetExtension(
+ content::SiteInstance* site_instance) {
+ ExtensionRegistry* registry =
+ ExtensionRegistry::Get(site_instance->GetBrowserContext());
+ return registry->enabled_extensions().GetExtensionOrAppByURL(
+ site_instance->GetSiteURL());
+}
+
} // namespace apps
diff --git a/apps/shell/shell_content_browser_client.h b/apps/shell/shell_content_browser_client.h
index e72ab2ed..db0f5a8 100644
--- a/apps/shell/shell_content_browser_client.h
+++ b/apps/shell/shell_content_browser_client.h
@@ -8,6 +8,12 @@
#include "base/compiler_specific.h"
#include "content/public/browser/content_browser_client.h"
+class GURL;
+
+namespace extensions {
+class Extension;
+}
+
namespace apps {
class ShellBrowserMainParts;
@@ -24,8 +30,19 @@ class ShellContentBrowserClient : public content::ContentBrowserClient {
content::ProtocolHandlerMap* protocol_handlers) OVERRIDE;
// TODO(jamescook): Quota management?
// TODO(jamescook): Speech recognition?
+ virtual bool IsHandledURL(const GURL& url) OVERRIDE;
+ virtual void SiteInstanceGotProcess(content::SiteInstance* site_instance)
+ OVERRIDE;
+ virtual void SiteInstanceDeleting(content::SiteInstance* site_instance)
+ OVERRIDE;
+ virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
+ int child_process_id) OVERRIDE;
private:
+ // Returns the extension or app associated with |site_instance| or NULL.
+ const extensions::Extension* GetExtension(
+ content::SiteInstance* site_instance);
+
// Owned by content::BrowserMainLoop.
ShellBrowserMainParts* browser_main_parts_;
diff --git a/apps/shell/shell_extension_system.cc b/apps/shell/shell_extension_system.cc
index f3ba941..dfb9fec 100644
--- a/apps/shell/shell_extension_system.cc
+++ b/apps/shell/shell_extension_system.cc
@@ -12,15 +12,18 @@
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/info_map.h"
#include "extensions/browser/lazy_background_task_queue.h"
#include "extensions/browser/process_manager.h"
using content::BrowserContext;
+using content::BrowserThread;
namespace extensions {
@@ -44,10 +47,16 @@ bool ShellExtensionSystem::LoadAndLaunchApp(const base::FilePath& app_dir) {
return false;
}
+ // TODO(jamescook): We may want to do some of these things here:
+ // * Create a PermissionsUpdater.
+ // * Call PermissionsUpdater::GrantActivePermissions().
+ // * Call ExtensionService::SatisfyImports().
+ // * Call ExtensionPrefs::OnExtensionInstalled().
+ // * Send NOTIFICATION_EXTENSION_INSTALLED.
+
ExtensionRegistry::Get(browser_context_)->AddEnabled(extension);
- // TODO(jamescook): If RegisterExtensionWithRequestContexts() did something,
- // this would be the place to call it.
+ RegisterExtensionWithRequestContexts(extension);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_EXTENSION_LOADED,
@@ -56,9 +65,6 @@ bool ShellExtensionSystem::LoadAndLaunchApp(const base::FilePath& app_dir) {
// Inform the rest of the extensions system to start.
ready_.Signal();
- LOG(WARNING) << "-----------------------------------";
- LOG(WARNING) << "app_shell is expected to crash now.";
- LOG(WARNING) << "-----------------------------------";
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_EXTENSIONS_READY,
content::Source<BrowserContext>(browser_context_),
@@ -79,7 +85,6 @@ void ShellExtensionSystem::InitForRegularProfile(bool extensions_enabled) {
}
ExtensionService* ShellExtensionSystem::extension_service() {
- NOTREACHED();
return NULL;
}
@@ -104,7 +109,9 @@ StateStore* ShellExtensionSystem::rules_store() {
}
InfoMap* ShellExtensionSystem::info_map() {
- return NULL;
+ if (!info_map_.get())
+ info_map_ = new InfoMap;
+ return info_map_;
}
LazyBackgroundTaskQueue* ShellExtensionSystem::lazy_background_task_queue() {
@@ -133,6 +140,11 @@ InstallVerifier* ShellExtensionSystem::install_verifier() {
void ShellExtensionSystem::RegisterExtensionWithRequestContexts(
const Extension* extension) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&InfoMap::AddExtension, info_map(),
+ make_scoped_refptr(extension), base::Time::Now(),
+ false, false));
}
void ShellExtensionSystem::UnregisterExtensionWithRequestContexts(
diff --git a/apps/shell/shell_extension_system.h b/apps/shell/shell_extension_system.h
index acc34f0..a72e089 100644
--- a/apps/shell/shell_extension_system.h
+++ b/apps/shell/shell_extension_system.h
@@ -20,6 +20,7 @@ class BrowserContext;
namespace extensions {
class EventRouter;
+class InfoMap;
class LazyBackgroundTaskQueue;
class ProcessManager;
@@ -63,6 +64,9 @@ class ShellExtensionSystem : public ExtensionSystem {
private:
content::BrowserContext* browser_context_; // Not owned.
+ // Data to be accessed on the IO thread. Must outlive process_manager_.
+ scoped_refptr<InfoMap> info_map_;
+
scoped_ptr<LazyBackgroundTaskQueue> lazy_background_task_queue_;
scoped_ptr<EventRouter> event_router_;
scoped_ptr<ProcessManager> process_manager_;