summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-20 23:26:40 +0000
committerrogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-20 23:26:40 +0000
commitd11c8e956955c9dd87e98033c7c4fa152da9fd76 (patch)
treec6f396cd5c37092550ade19561c9e0cc083943d5 /chrome
parentf3c0de82e9c1dcc822882243b0ba776953d4e4e3 (diff)
downloadchromium_src-d11c8e956955c9dd87e98033c7c4fa152da9fd76.zip
chromium_src-d11c8e956955c9dd87e98033c7c4fa152da9fd76.tar.gz
chromium_src-d11c8e956955c9dd87e98033c7c4fa152da9fd76.tar.bz2
Add support for to automation interface load install and load extensions.
TEST=None BUG=0 Review URL: http://codereview.chromium.org/274076 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29586 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider.cc52
-rw-r--r--chrome/browser/automation/automation_provider.h6
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc62
-rw-r--r--chrome/browser/automation/automation_provider_observers.h23
-rw-r--r--chrome/browser/extensions/crx_installer.cc5
-rw-r--r--chrome/browser/extensions/extension_browsertest.cc5
-rw-r--r--chrome/browser/extensions/extensions_service.cc59
-rw-r--r--chrome/browser/extensions/extensions_service.h11
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc2
-rw-r--r--chrome/common/notification_type.h4
-rw-r--r--chrome/test/automation/automation_constants.h6
-rw-r--r--chrome/test/automation/automation_messages.h34
-rw-r--r--chrome/test/automation/automation_messages_internal.h11
13 files changed, 263 insertions, 17 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 06a0ddf..2194fe6e 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -32,6 +32,8 @@
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_shelf.h"
+#include "chrome/browser/extensions/crx_installer.h"
+#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/find_bar.h"
#include "chrome/browser/find_bar_controller.h"
@@ -436,6 +438,10 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(AutomationMsg_ConnectExternalTab, ConnectExternalTab)
#endif
IPC_MESSAGE_HANDLER(AutomationMsg_SetPageFontSize, OnSetPageFontSize)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InstallExtension,
+ InstallExtension)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension,
+ LoadExpandedExtension)
IPC_END_MESSAGE_MAP()
}
@@ -2105,3 +2111,49 @@ void AutomationProvider::GetBrowserForWindow(int window_handle,
}
}
}
+
+void AutomationProvider::InstallExtension(const FilePath& crx_path,
+ IPC::Message* reply_message) {
+ ExtensionsService* service = profile_->GetExtensionsService();
+ if (service) {
+ // The observer will delete itself when done.
+ new ExtensionNotificationObserver(this,
+ AutomationMsg_InstallExtension::ID,
+ reply_message);
+
+ const FilePath& install_dir = service->install_directory();
+ MessageLoop* io_loop = g_browser_process->file_thread()->message_loop();
+
+ CrxInstaller::Start(crx_path,
+ install_dir,
+ Extension::INTERNAL,
+ "", // no expected id
+ false, // please do not delete crx file
+ true, // privilege increase allowed
+ io_loop,
+ service,
+ NULL); // silent isntall, no UI
+ } else {
+ AutomationMsg_InstallExtension::WriteReplyParams(
+ reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
+ Send(reply_message);
+ }
+}
+
+void AutomationProvider::LoadExpandedExtension(
+ const FilePath& extension_dir,
+ IPC::Message* reply_message) {
+ if (profile_->GetExtensionsService() && profile_->GetUserScriptMaster()) {
+ // The observer will delete itself when done.
+ new ExtensionNotificationObserver(this,
+ AutomationMsg_LoadExpandedExtension::ID,
+ reply_message);
+
+ profile_->GetExtensionsService()->LoadExtension(extension_dir);
+ profile_->GetUserScriptMaster()->AddWatchedPath(extension_dir);
+ } else {
+ AutomationMsg_LoadExpandedExtension::WriteReplyParams(
+ reply_message, AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
+ Send(reply_message);
+ }
+}
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 60bb2f8..1b5ee7d 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -302,6 +302,12 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
void OnSetPageFontSize(int tab_handle, int font_size);
+ void InstallExtension(const FilePath& crx_path,
+ IPC::Message* reply_message);
+
+ void LoadExpandedExtension(const FilePath& extension_dir,
+ IPC::Message* reply_message);
+
void NavigateInExternalTab(
int handle, const GURL& url, const GURL& referrer,
AutomationMsg_NavigationResponseValues* status);
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index 9250ec8..0009b6f 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -277,6 +277,68 @@ void TabClosedNotificationObserver::set_for_browser_command(
for_browser_command_ = for_browser_command;
}
+ExtensionNotificationObserver::ExtensionNotificationObserver(
+ AutomationProvider* automation, int id, IPC::Message* reply_message)
+ : automation_(automation),
+ id_(id),
+ reply_message_(reply_message) {
+ registrar_.Add(this, NotificationType::EXTENSION_LOADED,
+ NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::EXTENSION_INSTALL_ERROR,
+ NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::EXTENSION_OVERINSTALL_ERROR,
+ NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
+ NotificationService::AllSources());
+}
+
+ExtensionNotificationObserver::~ExtensionNotificationObserver() {
+}
+
+void ExtensionNotificationObserver::Observe(
+ NotificationType type, const NotificationSource& source,
+ const NotificationDetails& details) {
+ switch (type.value) {
+ case NotificationType::EXTENSION_LOADED:
+ SendResponse(AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED);
+ break;
+ case NotificationType::EXTENSION_INSTALL_ERROR:
+ case NotificationType::EXTENSION_UPDATE_DISABLED:
+ SendResponse(AUTOMATION_MSG_EXTENSION_INSTALL_FAILED);
+ break;
+ case NotificationType::EXTENSION_OVERINSTALL_ERROR:
+ SendResponse(AUTOMATION_MSG_EXTENSION_ALREADY_INSTALLED);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ delete this;
+}
+
+void ExtensionNotificationObserver::SendResponse(
+ AutomationMsg_ExtensionResponseValues response) {
+ if (reply_message_ != NULL) {
+ switch (id_) {
+ case AutomationMsg_InstallExtension::ID:
+ AutomationMsg_InstallExtension::WriteReplyParams(reply_message_,
+ response);
+ break;
+ case AutomationMsg_LoadExpandedExtension::ID:
+ AutomationMsg_LoadExpandedExtension::WriteReplyParams(reply_message_,
+ response);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ automation_->Send(reply_message_);
+ reply_message_ = NULL;
+ }
+}
+
BrowserOpenedNotificationObserver::BrowserOpenedNotificationObserver(
AutomationProvider* automation, IPC::Message* reply_message)
: automation_(automation),
diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h
index 5719582..58409d0 100644
--- a/chrome/browser/automation/automation_provider_observers.h
+++ b/chrome/browser/automation/automation_provider_observers.h
@@ -163,6 +163,29 @@ class TabClosedNotificationObserver : public TabStripNotificationObserver {
DISALLOW_COPY_AND_ASSIGN(TabClosedNotificationObserver);
};
+class ExtensionNotificationObserver : public NotificationObserver {
+ public:
+ ExtensionNotificationObserver(AutomationProvider* automation,
+ int id,
+ IPC::Message* reply_message);
+ virtual ~ExtensionNotificationObserver();
+
+ // Implementation of NotificationObserver.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ void SendResponse(AutomationMsg_ExtensionResponseValues response);
+
+ NotificationRegistrar registrar_;
+ scoped_refptr<AutomationProvider> automation_;
+ int id_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionNotificationObserver);
+};
+
class BrowserOpenedNotificationObserver : public NotificationObserver {
public:
BrowserOpenedNotificationObserver(AutomationProvider* automation,
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 7bb69d0..359f45a 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -285,6 +285,11 @@ void CrxInstaller::ReportOverinstallFromFileThread() {
void CrxInstaller::ReportOverinstallFromUIThread() {
DCHECK(MessageLoop::current() == ui_loop_);
+ NotificationService* service = NotificationService::current();
+ service->Notify(NotificationType::EXTENSION_OVERINSTALL_ERROR,
+ Source<CrxInstaller>(this),
+ Details<const FilePath>(&extension_->path()));
+
if (client_.get())
client_->OnOverinstallAttempted(extension_.get());
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index 7045cfa..fecef04 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -251,6 +251,11 @@ void ExtensionBrowserTest::Observe(NotificationType type,
MessageLoopForUI::current()->Quit();
break;
+ case NotificationType::EXTENSION_OVERINSTALL_ERROR:
+ std::cout << "Got EXTENSION_OVERINSTALL_ERROR notification.\n";
+ MessageLoopForUI::current()->Quit();
+ break;
+
default:
NOTREACHED();
break;
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 08bb324..71d3a08 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -54,15 +54,6 @@ class InstalledExtensionSet {
std::set<std::string> extensions_;
};
-static void ReportExtensionLoadError(
- const FilePath& extension_path, const std::string &error, bool be_noisy) {
- // TODO(port): note that this isn't guaranteed to work properly on Linux.
- std::string path_str = WideToASCII(extension_path.ToWStringHack());
- std::string message = StringPrintf("Could not load extension from '%s'. %s",
- path_str.c_str(), error.c_str());
- ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy);
-}
-
} // namespace
// ExtensionsService.
@@ -309,7 +300,10 @@ void ExtensionsService::LoadInstalledExtension(
}
if (!extension) {
- ReportExtensionLoadError(path, error, false);
+ ReportExtensionLoadError(path,
+ error,
+ NotificationType::EXTENSION_INSTALL_ERROR,
+ false);
return;
}
@@ -528,7 +522,13 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension,
}
} else {
// We already have the extension of the same or older version.
- LOG(WARNING) << "Duplicate extension load attempt: " << extension->id();
+ std::string error_message("Duplicate extension load attempt: ");
+ error_message += extension->id();
+ LOG(WARNING) << error_message;
+ ReportExtensionLoadError(extension->path(),
+ error_message,
+ NotificationType::EXTENSION_OVERINSTALL_ERROR,
+ false);
return;
}
}
@@ -553,9 +553,14 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension,
}
break;
case Extension::DISABLED:
+ NotificationService::current()->Notify(
+ NotificationType::EXTENSION_UPDATE_DISABLED,
+ Source<ExtensionsService>(this),
+ Details<Extension>(extension));
disabled_extensions_.push_back(scoped_extension.release());
break;
default:
+ NOTREACHED();
break;
}
}
@@ -668,6 +673,23 @@ void ExtensionsService::OnExternalExtensionFound(const std::string& id,
NULL); // no client (silent install)
}
+void ExtensionsService::ReportExtensionLoadError(
+ const FilePath& extension_path,
+ const std::string &error,
+ NotificationType type,
+ bool be_noisy) {
+ NotificationService* service = NotificationService::current();
+ service->Notify(type,
+ Source<ExtensionsService>(this),
+ Details<const std::string>(&error));
+
+ // TODO(port): note that this isn't guaranteed to work properly on Linux.
+ std::string path_str = WideToASCII(extension_path.ToWStringHack());
+ std::string message = StringPrintf("Could not load extension from '%s'. %s",
+ path_str.c_str(), error.c_str());
+ ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy);
+}
+
// ExtensionsServicesBackend
ExtensionsServiceBackend::ExtensionsServiceBackend(
@@ -722,7 +744,20 @@ void ExtensionsServiceBackend::LoadSingleExtension(
void ExtensionsServiceBackend::ReportExtensionLoadError(
const FilePath& extension_path, const std::string &error) {
- ::ReportExtensionLoadError(extension_path, error, alert_on_error_);
+ // In the unit tests, frontend_loop_ may be null.
+ if (frontend_loop_ == NULL) {
+ frontend_->ReportExtensionLoadError(
+ extension_path,
+ error,
+ NotificationType::EXTENSION_INSTALL_ERROR,
+ alert_on_error_);
+ return;
+ }
+
+ frontend_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(frontend_,
+ &ExtensionsService::ReportExtensionLoadError, extension_path,
+ error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_));
}
void ExtensionsServiceBackend::ReportExtensionLoaded(Extension* extension) {
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index e4fd701..4235c22 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -223,6 +223,13 @@ class ExtensionsService
// Note that this may return NULL if autoupdate is not turned on.
ExtensionUpdater* updater() { return updater_.get(); }
+ // Notify the frontend that there was an error loading an extension.
+ // This method is public because ExtensionsServiceBackend can post to here.
+ void ReportExtensionLoadError(const FilePath& extension_path,
+ const std::string& error,
+ NotificationType type,
+ bool be_noisy);
+
private:
// Look up an extension by ID, optionally including either or both of enabled
// and disabled extensions.
@@ -354,10 +361,6 @@ class ExtensionsServiceBackend
// Notify the frontend that an extension was loaded.
void ReportExtensionLoaded(Extension* extension);
- // Notify the frontend that there was an error installing an extension.
- void ReportExtensionInstallError(const FilePath& extension_path,
- const std::string& error);
-
// Lookup an external extension by |id| by going through all registered
// external extension providers until we find a provider that contains an
// extension that matches. If |version| is not NULL, the extension version
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index afadd3c..f2e357d 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -1439,7 +1439,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
loop_.RunAllPending();
ASSERT_EQ(1u, loaded_.size());
- ASSERT_EQ(0u, GetErrors().size());
+ ASSERT_EQ(1u, GetErrors().size());
}
TEST_F(ExtensionsServiceTest, ExternalPrefProvider) {
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 2768c8e..a6b8eab 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -660,6 +660,10 @@ class NotificationType {
// details about why the install failed.
EXTENSION_INSTALL_ERROR,
+ // An overinstall error occured during extension install. The details are a
+ // FilePath to the extension that was attempted to install.
+ EXTENSION_OVERINSTALL_ERROR,
+
// Sent when an extension is unloaded. This happens when an extension is
// uninstalled. When we add a disable feature, it will also happen then.
// The details are an Extension. Note that when this notification is sent,
diff --git a/chrome/test/automation/automation_constants.h b/chrome/test/automation/automation_constants.h
index 6d0a034..cf54a39 100644
--- a/chrome/test/automation/automation_constants.h
+++ b/chrome/test/automation/automation_constants.h
@@ -25,4 +25,10 @@ enum AutomationMsg_NavigationResponseValues {
AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
};
+enum AutomationMsg_ExtensionResponseValues {
+ AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED = 0,
+ AUTOMATION_MSG_EXTENSION_INSTALL_FAILED,
+ AUTOMATION_MSG_EXTENSION_ALREADY_INSTALLED,
+};
+
#endif // CHROME_TEST_AUTOMATION_AUTOMATION_CONSTANTS_H_
diff --git a/chrome/test/automation/automation_messages.h b/chrome/test/automation/automation_messages.h
index 416d168..388b6f2 100644
--- a/chrome/test/automation/automation_messages.h
+++ b/chrome/test/automation/automation_messages.h
@@ -93,6 +93,40 @@ struct ParamTraits<AutomationMsg_NavigationResponseValues> {
};
template <>
+struct ParamTraits<AutomationMsg_ExtensionResponseValues> {
+ typedef AutomationMsg_ExtensionResponseValues param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteInt(p);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ int type;
+ if (!m->ReadInt(iter, &type))
+ return false;
+ *p = static_cast<AutomationMsg_ExtensionResponseValues>(type);
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ std::wstring control;
+ switch (p) {
+ case AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED:
+ control = L"AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED";
+ break;
+ case AUTOMATION_MSG_EXTENSION_INSTALL_FAILED:
+ control = L"AUTOMATION_MSG_EXTENSION_INSTALL_FAILED";
+ break;
+ case AUTOMATION_MSG_EXTENSION_ALREADY_INSTALLED:
+ control = L"AUTOMATION_MSG_EXTENSION_ALREADY_INSTALLED";
+ break;
+ default:
+ control = L"UNKNOWN";
+ break;
+ }
+
+ LogParam(control, l);
+ }
+};
+
+template <>
struct ParamTraits<SecurityStyle> {
typedef SecurityStyle param_type;
static void Write(Message* m, const param_type& p) {
diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h
index 24261d4..174e1d0 100644
--- a/chrome/test/automation/automation_messages_internal.h
+++ b/chrome/test/automation/automation_messages_internal.h
@@ -1129,5 +1129,16 @@ IPC_BEGIN_MESSAGES(Automation)
int, // tab handle
int) // numbers of entries (negative or positive)
+ // Silently install the extension in the given crx file.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_InstallExtension,
+ FilePath /* full path to crx file */,
+ AutomationMsg_ExtensionResponseValues)
+
+ // Silently load the extension in the given directory. This expects an
+ // extension expanded into the directory, not a crx file.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_LoadExpandedExtension,
+ FilePath /* root directory of extension */,
+ AutomationMsg_ExtensionResponseValues)
+
IPC_END_MESSAGES(Automation)