summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authormpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-27 19:35:09 +0000
committermpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-27 19:35:09 +0000
commit81e6378c98d0e69339302527eb1de4735d1e2c3f (patch)
treed8020f1a2a842b0735c22a35e89a97ec7630bf17 /chrome/browser/extensions
parent4c8c60ee58cf2f22fcdc0cf3b30f1f5e8884f0ff (diff)
downloadchromium_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-xchrome/browser/extensions/extension_view.cc32
-rwxr-xr-xchrome/browser/extensions/extension_view.h46
-rwxr-xr-xchrome/browser/extensions/extension_view_unittest.cc108
-rw-r--r--chrome/browser/extensions/extensions_service.cc15
-rw-r--r--chrome/browser/extensions/extensions_service.h11
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_;