diff options
author | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-27 19:35:09 +0000 |
---|---|---|
committer | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-27 19:35:09 +0000 |
commit | 81e6378c98d0e69339302527eb1de4735d1e2c3f (patch) | |
tree | d8020f1a2a842b0735c22a35e89a97ec7630bf17 /chrome/browser/extensions | |
parent | 4c8c60ee58cf2f22fcdc0cf3b30f1f5e8884f0ff (diff) | |
download | chromium_src-81e6378c98d0e69339302527eb1de4735d1e2c3f.zip chromium_src-81e6378c98d0e69339302527eb1de4735d1e2c3f.tar.gz chromium_src-81e6378c98d0e69339302527eb1de4735d1e2c3f.tar.bz2 |
Prototype extension process. This is a proof of concept, with a lot of
rough edges. Mostly this just fires up a renderer with an "extension" object
exposed, which right now only has a single method "getTestString".
I also did some misc cleanup along the way.
Review URL: http://codereview.chromium.org/27187
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10620 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rwxr-xr-x | chrome/browser/extensions/extension_view.cc | 32 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_view.h | 46 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_view_unittest.cc | 108 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 15 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 11 |
5 files changed, 207 insertions, 5 deletions
diff --git a/chrome/browser/extensions/extension_view.cc b/chrome/browser/extensions/extension_view.cc new file mode 100755 index 0000000..1647ecb --- /dev/null +++ b/chrome/browser/extensions/extension_view.cc @@ -0,0 +1,32 @@ +// Copyright (c) 2006-2009 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 "chrome/browser/extensions/extension_view.h" + +#include "chrome/browser/renderer_host/render_view_host.h" + +ExtensionView::ExtensionView(const GURL& url, Profile* profile) : + HWNDHtmlView(url, this, false), profile_(profile) { +} + +void ExtensionView::CreatingRenderer() { + render_view_host()->AllowExtensionBindings(); +} + +WebPreferences ExtensionView::GetWebkitPrefs() { + // TODO(mpcomplete): return some reasonable prefs. + return WebPreferences(); +} + +void ExtensionView::RunJavaScriptMessage( + const std::wstring& message, + const std::wstring& default_prompt, + const int flags, + IPC::Message* reply_msg, + bool* did_suppress_message) { + // Automatically cancel the javascript alert (otherwise the renderer hangs + // indefinitely). + *did_suppress_message = true; + render_view_host()->JavaScriptMessageBoxClosed(reply_msg, true, L""); +} diff --git a/chrome/browser/extensions/extension_view.h b/chrome/browser/extensions/extension_view.h new file mode 100755 index 0000000..5eb869c --- /dev/null +++ b/chrome/browser/extensions/extension_view.h @@ -0,0 +1,46 @@ +// Copyright (c) 2006-2009 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 CHROME_BROWSER_EXTENSIONS_EXTENSION_VIEW_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_VIEW_H_ + +#include "chrome/browser/renderer_host/render_view_host_delegate.h" + +// TODO(port): Port these files. +#if defined(OS_WIN) +#include "chrome/browser/views/hwnd_html_view.h" +#else +#include "chrome/common/temp_scaffolding_stubs.h" +#endif + +class Profile; +struct WebPreferences; + +// This class is the browser component of an extension component's RenderView. +// It handles setting up the renderer process, if needed, with special +// priviliges available to extensions. The view may be drawn to the screen or +// hidden. +class ExtensionView : public HWNDHtmlView, + public RenderViewHostDelegate { + public: + ExtensionView(const GURL& url, Profile* profile); + + // HWNDHtmlView + virtual void CreatingRenderer(); + + // RenderViewHostDelegate + virtual Profile* GetProfile() const { return profile_; } + virtual WebPreferences GetWebkitPrefs(); + virtual void RunJavaScriptMessage( + const std::wstring& message, + const std::wstring& default_prompt, + const int flags, + IPC::Message* reply_msg, + bool* did_suppress_message); + + private: + Profile* profile_; +}; + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_VIEW_H_ diff --git a/chrome/browser/extensions/extension_view_unittest.cc b/chrome/browser/extensions/extension_view_unittest.cc new file mode 100755 index 0000000..930b068 --- /dev/null +++ b/chrome/browser/extensions/extension_view_unittest.cc @@ -0,0 +1,108 @@ +// Copyright (c) 2006-2008 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 "base/message_loop.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/extensions/extension_view.h" +#include "chrome/browser/extensions/extensions_service.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/notification_service.h" +#include "chrome/test/in_process_browser_test.h" +#include "chrome/test/ui_test_utils.h" + +namespace { + +// How long to wait for the extension to put up a javascript alert before giving +// up. +const int kAlertTimeoutMs = 10000; + +// The extension we're using as our test case. +const char* kExtensionId = "com.google.myextension1"; + +// This class starts up an extension process and waits until it tries to put +// up a javascript alert. +class MockExtensionView : public ExtensionView { + public: + MockExtensionView(const GURL& url, Profile* profile) + : ExtensionView(url, profile), got_message_(false) { + InitHidden(); + MessageLoop::current()->PostDelayedTask(FROM_HERE, + new MessageLoop::QuitTask, kAlertTimeoutMs); + ui_test_utils::RunMessageLoop(); + } + + bool got_message() { return got_message_; } + private: + virtual void RunJavaScriptMessage( + const std::wstring& message, + const std::wstring& default_prompt, + const int flags, + IPC::Message* reply_msg, + bool* did_suppress_message) { + got_message_ = true; + MessageLoopForUI::current()->Quit(); + } + + bool got_message_; +}; + +// This class waits for a specific extension to be loaded. +class ExtensionLoadedObserver : public NotificationObserver { + public: + explicit ExtensionLoadedObserver() : extension_(NULL) { + registrar_.Add(this, NotificationType::EXTENSIONS_LOADED, + NotificationService::AllSources()); + ui_test_utils::RunMessageLoop(); + } + + Extension* extension() { return extension_; } + private: + virtual void Observe(NotificationType type, const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::EXTENSIONS_LOADED) { + ExtensionList* extensions = Details<ExtensionList>(details).ptr(); + for (size_t i = 0; i < (*extensions).size(); i++) { + if ((*extensions)[i]->id() == kExtensionId) { + extension_ = (*extensions)[i]; + MessageLoopForUI::current()->Quit(); + break; + } + } + } else { + NOTREACHED(); + } + } + + NotificationRegistrar registrar_; + Extension* extension_; +}; + +} // namespace + +class ExtensionViewTest : public InProcessBrowserTest { +}; + +IN_PROC_BROWSER_TEST_F(ExtensionViewTest, TestMe) { + // Get the path to our extension. + FilePath path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); + path = path.AppendASCII("extensions"). + AppendASCII("good").AppendASCII("extension1").AppendASCII("1"); + + // Load it. + Profile* profile = browser()->profile(); + profile->GetExtensionsService()->Init(); + profile->GetExtensionsService()->LoadExtension(path); + + // Now wait for it to load, and grab a pointer to it. + Extension* extension = ExtensionLoadedObserver().extension(); + ASSERT_TRUE(extension); + GURL url = Extension::GetResourceURL(extension->url(), "index.html"); + + // Start the extension process and wait for it to show a javascript alert. + MockExtensionView view(url, profile); + EXPECT_TRUE(view.got_message()); +} diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 9fc0040..3271920 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -16,7 +16,9 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/user_script_master.h" +#include "chrome/browser/extensions/extension_view.h" #include "chrome/browser/plugin_service.h" +#include "chrome/browser/profile.h" #include "chrome/common/json_value_serializer.h" #include "chrome/common/notification_service.h" #include "chrome/common/unzip.h" @@ -63,12 +65,12 @@ const wchar_t kRegistryExtensionVersion[] = L"version"; const char kExternalInstallFile[] = "EXTERNAL_INSTALL"; } - -ExtensionsService::ExtensionsService(const FilePath& profile_directory, +ExtensionsService::ExtensionsService(Profile* profile, UserScriptMaster* user_script_master) : message_loop_(MessageLoop::current()), backend_(new ExtensionsServiceBackend), - install_directory_(profile_directory.AppendASCII(kInstallDirectoryName)), + install_directory_(profile->GetPath().AppendASCII(kInstallDirectoryName)), + profile_(profile), user_script_master_(user_script_master) { } @@ -104,6 +106,13 @@ bool ExtensionsService::Init() { return true; } +void ExtensionsService::LaunchExtensionProcess(Extension* extension) { + // TODO(mpcomplete): Do something useful here. + GURL url = Extension::GetResourceURL(extension->url(), "index.html"); + ExtensionView* view = new ExtensionView(url, profile_); + view->InitHidden(); +} + MessageLoop* ExtensionsService::GetMessageLoop() { return message_loop_; } diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index efba0086..7489de7 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -16,6 +16,7 @@ typedef std::vector<Extension*> ExtensionList; class ExtensionsServiceBackend; +class Profile; class UserScriptMaster; // Interface for the frontend to implement. Typically, this will be @@ -51,8 +52,7 @@ class ExtensionsServiceFrontendInterface // Manages installed and running Chromium extensions. class ExtensionsService : public ExtensionsServiceFrontendInterface { public: - ExtensionsService(const FilePath& profile_directory, - UserScriptMaster* user_script_master); + ExtensionsService(Profile* profile, UserScriptMaster* user_script_master); ~ExtensionsService(); // Gets the list of currently installed extensions. @@ -63,6 +63,10 @@ class ExtensionsService : public ExtensionsServiceFrontendInterface { // Initialize and start all installed extensions. bool Init(); + // Start the extension process for this extension. TODO(mpcomplete): not sure + // how this should actually work yet. + void LaunchExtensionProcess(Extension* extension); + // ExtensionsServiceFrontendInterface virtual MessageLoop* GetMessageLoop(); virtual void InstallExtension(const FilePath& extension_path); @@ -90,6 +94,9 @@ class ExtensionsService : public ExtensionsServiceFrontendInterface { // The full path to the directory where extensions are installed. FilePath install_directory_; + // The profile associated with this set of extensions. + Profile* profile_; + // The user script master for this profile. scoped_refptr<UserScriptMaster> user_script_master_; |