diff options
author | rogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-20 23:26:40 +0000 |
---|---|---|
committer | rogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-20 23:26:40 +0000 |
commit | d11c8e956955c9dd87e98033c7c4fa152da9fd76 (patch) | |
tree | c6f396cd5c37092550ade19561c9e0cc083943d5 /chrome | |
parent | f3c0de82e9c1dcc822882243b0ba776953d4e4e3 (diff) | |
download | chromium_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.cc | 52 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 6 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.cc | 62 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.h | 23 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.cc | 5 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_browsertest.cc | 5 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 59 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 11 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/common/notification_type.h | 4 | ||||
-rw-r--r-- | chrome/test/automation/automation_constants.h | 6 | ||||
-rw-r--r-- | chrome/test/automation/automation_messages.h | 34 | ||||
-rw-r--r-- | chrome/test/automation/automation_messages_internal.h | 11 |
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) |