diff options
author | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-16 02:18:43 +0000 |
---|---|---|
committer | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-16 02:18:43 +0000 |
commit | a1e62d1553f81d66fa5fdc6a4e54a5531d378bbc (patch) | |
tree | b14f0d7693c0843222d765da77d9c1ccc3e2de46 | |
parent | d5b42ac0413ca4dbac88bce952044808ba40b1a9 (diff) | |
download | chromium_src-a1e62d1553f81d66fa5fdc6a4e54a5531d378bbc.zip chromium_src-a1e62d1553f81d66fa5fdc6a4e54a5531d378bbc.tar.gz chromium_src-a1e62d1553f81d66fa5fdc6a4e54a5531d378bbc.tar.bz2 |
Adds an automation message to retrieve the list of enabled extensions, and CF bindings for it.
TEST=unit test to follow
BUG=none
Review URL: http://codereview.chromium.org/901002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41667 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 17 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 2 | ||||
-rw-r--r-- | chrome/browser/automation/chrome_frame_automation_provider.cc | 1 | ||||
-rw-r--r-- | chrome/test/automation/automation_messages_internal.h | 4 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.cc | 6 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy.h | 4 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_activex.cc | 19 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_activex.h | 3 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_activex_base.h | 20 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_automation.cc | 69 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_automation.h | 8 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_delegate.h | 7 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_npapi.cc | 53 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_npapi.h | 7 | ||||
-rw-r--r-- | chrome_frame/chrome_tab.idl | 16 |
15 files changed, 235 insertions, 1 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 998b252..8ae593b 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -484,6 +484,8 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) { InstallExtension) IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoadExpandedExtension, LoadExpandedExtension) + IPC_MESSAGE_HANDLER(AutomationMsg_GetEnabledExtensions, + GetEnabledExtensions) IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService, ShutdownSessionService) IPC_MESSAGE_HANDLER(AutomationMsg_SaveAsAsync, SaveAsAsync) @@ -2482,6 +2484,21 @@ void AutomationProvider::LoadExpandedExtension( } } +void AutomationProvider::GetEnabledExtensions( + std::vector<FilePath>* result) { + ExtensionsService* service = profile_->GetExtensionsService(); + DCHECK(service); + if (service->extensions_enabled()) { + const ExtensionList* extensions = service->extensions(); + DCHECK(extensions); + for (size_t i = 0; i < extensions->size(); ++i) { + Extension* extension = (*extensions)[i]; + DCHECK(extension); + result->push_back(extension->path()); + } + } +} + void AutomationProvider::SaveAsAsync(int tab_handle) { NavigationController* tab = NULL; TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab); diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h index 88bb865..e5b36bf 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -363,6 +363,8 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, void LoadExpandedExtension(const FilePath& extension_dir, IPC::Message* reply_message); + void GetEnabledExtensions(std::vector<FilePath>* result); + void NavigateInExternalTab( int handle, const GURL& url, const GURL& referrer, AutomationMsg_NavigationResponseValues* status); diff --git a/chrome/browser/automation/chrome_frame_automation_provider.cc b/chrome/browser/automation/chrome_frame_automation_provider.cc index ab87b92..c8bada3 100644 --- a/chrome/browser/automation/chrome_frame_automation_provider.cc +++ b/chrome/browser/automation/chrome_frame_automation_provider.cc @@ -45,6 +45,7 @@ bool ChromeFrameAutomationProvider::IsValidMessage(uint32 type) { case AutomationMsg_Find::ID: case AutomationMsg_InstallExtension::ID: case AutomationMsg_LoadExpandedExtension::ID: + case AutomationMsg_GetEnabledExtensions::ID: case AutomationMsg_SetEnableExtensionAutomation::ID: case AutomationMsg_SetInitialFocus::ID: case AutomationMsg_SetPageFontSize::ID: diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h index 8dcf03a..495905e 100644 --- a/chrome/test/automation/automation_messages_internal.h +++ b/chrome/test/automation/automation_messages_internal.h @@ -1161,6 +1161,10 @@ IPC_BEGIN_MESSAGES(Automation) FilePath /* root directory of extension */, AutomationMsg_ExtensionResponseValues) + // Retrieves a list of the root directories of all enabled extensions. + IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_GetEnabledExtensions, + std::vector<FilePath>) + // This message requests the type of the window with the given handle. The // return value contains the type (Browser::Type), or -1 if the request // failed. diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc index d03bc4d..d383443 100644 --- a/chrome/test/automation/automation_proxy.cc +++ b/chrome/test/automation/automation_proxy.cc @@ -237,6 +237,12 @@ bool AutomationProxy::InstallExtension(const FilePath& crx_file) { return response == AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED; } +bool AutomationProxy::GetEnabledExtensions( + std::vector<FilePath>* extension_directories) { + return Send(new AutomationMsg_GetEnabledExtensions( + 0, extension_directories)); +} + bool AutomationProxy::GetBrowserWindowCount(int* num_windows) { if (!num_windows) { NOTREACHED(); diff --git a/chrome/test/automation/automation_proxy.h b/chrome/test/automation/automation_proxy.h index c1f1e46..281de66 100644 --- a/chrome/test/automation/automation_proxy.h +++ b/chrome/test/automation/automation_proxy.h @@ -186,6 +186,10 @@ class AutomationProxy : public IPC::Channel::Listener, // Note: Overinstalls will fail. bool InstallExtension(const FilePath& crx_file); + // Gets a list of all enabled extensions' base directories. + // Returns true on success. + bool GetEnabledExtensions(std::vector<FilePath>* extension_directories); + #if defined(OS_CHROMEOS) // Logs in through the Chrome OS login wizard with given |username| // and |password|. Returns true on success. diff --git a/chrome_frame/chrome_frame_activex.cc b/chrome_frame/chrome_frame_activex.cc index 15ae065..3104f0e 100644 --- a/chrome_frame/chrome_frame_activex.cc +++ b/chrome_frame/chrome_frame_activex.cc @@ -255,6 +255,25 @@ void ChromeFrameActivex::OnExtensionInstalled( Fire_onextensionready(path_str, response); } +void ChromeFrameActivex::OnGetEnabledExtensionsComplete( + void* user_data, + const std::vector<FilePath>& extension_directories) { + SAFEARRAY* sa = ::SafeArrayCreateVector(VT_BSTR, 0, + extension_directories.size()); + sa->fFeatures = sa->fFeatures | FADF_BSTR; + ::SafeArrayLock(sa); + + for (size_t i = 0; i < extension_directories.size(); ++i) { + LONG index = static_cast<LONG>(i); + ::SafeArrayPutElement(sa, &index, reinterpret_cast<void*>( + CComBSTR(extension_directories[i].ToWStringHack().c_str()).Detach())); + } + + Fire_ongetenabledextensionscomplete(sa); + ::SafeArrayUnlock(sa); + ::SafeArrayDestroy(sa); +} + HRESULT ChromeFrameActivex::OnDraw(ATL_DRAWINFO& draw_info) { // NO_LINT HRESULT hr = S_OK; int dc_type = ::GetObjectType(draw_info.hicTargetDev); diff --git a/chrome_frame/chrome_frame_activex.h b/chrome_frame/chrome_frame_activex.h index 1d4f1e9..8ebab2b 100644 --- a/chrome_frame/chrome_frame_activex.h +++ b/chrome_frame/chrome_frame_activex.h @@ -94,6 +94,9 @@ END_MSG_MAP() AutomationLaunchResult reason, const std::string& server_version); virtual void OnExtensionInstalled(const FilePath& path, void* user_data, AutomationMsg_ExtensionResponseValues response); + virtual void OnGetEnabledExtensionsComplete( + void* user_data, + const std::vector<FilePath>& extension_directories); private: LRESULT OnCreate(UINT message, WPARAM wparam, LPARAM lparam, diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h index 263b2b9..5c8c2c4 100644 --- a/chrome_frame/chrome_frame_activex_base.h +++ b/chrome_frame/chrome_frame_activex_base.h @@ -132,6 +132,14 @@ class ATL_NO_VTABLE ProxyDIChromeFrameEvents args, arraysize(args)); } + + void Fire_ongetenabledextensionscomplete(SAFEARRAY* extension_dirs) { // NOLINT + VARIANT args[1] = { { VT_ARRAY | VT_BSTR } }; + args[0].parray = extension_dirs; + + FireMethodWithParams(CF_EVENT_DISPID_ONGETENABLEDEXTENSIONSCOMPLETE, + args, arraysize(args)); + } }; extern bool g_first_launch_by_process_; @@ -811,6 +819,18 @@ END_MSG_MAP() return S_OK; } + STDMETHOD(getEnabledExtensions)() { + DCHECK(automation_client_.get()); + + if (!is_privileged_) { + DLOG(ERROR) << "Attempt to getEnabledExtensions in non-privileged mode"; + return E_ACCESSDENIED; + } + + automation_client_->GetEnabledExtensions(NULL); + return S_OK; + } + // Returns the vector of event handlers for a given event (e.g. "load"). // If the event type isn't recognized, the function fills in a descriptive // error (IErrorInfo) and returns E_INVALIDARG. diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc index 988f27a7..785e3e5 100644 --- a/chrome_frame/chrome_frame_automation.cc +++ b/chrome_frame/chrome_frame_automation.cc @@ -96,6 +96,9 @@ class ChromeFrameAutomationProxyImpl::CFMsgDispatcher InvokeCallback<Tuple1<AutomationMsg_ExtensionResponseValues> >(msg, origin); break; + case AutomationMsg_GetEnabledExtensions::ID: + InvokeCallback<Tuple1<std::vector<FilePath> > >(msg, origin); + break; default: NOTREACHED(); } @@ -724,6 +727,72 @@ void ChromeFrameAutomationClient::InstallExtensionComplete( } } +// Class that maintains context during the async retrieval of fetching the +// list of enabled extensions. When done, GetEnabledExtensionsComplete is +// posted back to the UI thread so that the users of +// ChromeFrameAutomationClient can be notified. +class GetEnabledExtensionsContext { + public: + GetEnabledExtensionsContext( + ChromeFrameAutomationClient* client, void* user_data) : client_(client), + user_data_(user_data) { + extension_directories_ = new std::vector<FilePath>(); + } + + ~GetEnabledExtensionsContext() { + // ChromeFrameAutomationClient::GetEnabledExtensionsComplete takes + // ownership of extension_directories_. + } + + std::vector<FilePath>* extension_directories() { + return extension_directories_; + } + + void GetEnabledExtensionsComplete( + std::vector<FilePath> result) { + (*extension_directories_) = result; + client_->PostTask(FROM_HERE, NewRunnableMethod(client_.get(), + &ChromeFrameAutomationClient::GetEnabledExtensionsComplete, + user_data_, extension_directories_)); + delete this; + } + + private: + scoped_refptr<ChromeFrameAutomationClient> client_; + std::vector<FilePath>* extension_directories_; + void* user_data_; +}; + +void ChromeFrameAutomationClient::GetEnabledExtensions(void* user_data) { + if (automation_server_ == NULL) { + GetEnabledExtensionsComplete(user_data, &std::vector<FilePath>()); + return; + } + + GetEnabledExtensionsContext* ctx = new GetEnabledExtensionsContext( + this, user_data); + + IPC::SyncMessage* msg = new AutomationMsg_GetEnabledExtensions( + 0, ctx->extension_directories()); + + // The context will delete itself after it is called. + automation_server_->SendAsAsync(msg, NewCallback(ctx, + &GetEnabledExtensionsContext::GetEnabledExtensionsComplete), this); +} + +void ChromeFrameAutomationClient::GetEnabledExtensionsComplete( + void* user_data, + std::vector<FilePath>* extension_directories) { + DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_); + + if (chrome_frame_delegate_) { + chrome_frame_delegate_->OnGetEnabledExtensionsComplete( + user_data, *extension_directories); + } + + delete extension_directories; +} + void ChromeFrameAutomationClient::OnChromeFrameHostMoved() { // Use a local var to avoid the small possibility of getting the tab_ // member be cleared while we try to use it. diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h index 48c76fd..f01d1b4 100644 --- a/chrome_frame/chrome_frame_automation.h +++ b/chrome_frame/chrome_frame_automation.h @@ -186,11 +186,19 @@ class ChromeFrameAutomationClient virtual void LoadExpandedExtension(const FilePath& path, void* user_data); + // Starts a request to get the list of enabled extensions' base directories. + // Response comes back as ChromeFrameDelegate::OnEnabledExtensions(). + virtual void GetEnabledExtensions(void* user_data); + virtual void InstallExtensionComplete( const FilePath& path, void* user_data, AutomationMsg_ExtensionResponseValues res); + virtual void GetEnabledExtensionsComplete( + void* user_data, + std::vector<FilePath>* extension_directories); + virtual void OnChromeFrameHostMoved(); TabProxy* tab() const { return tab_.get(); } diff --git a/chrome_frame/chrome_frame_delegate.h b/chrome_frame/chrome_frame_delegate.h index 63409b9..f8f812d 100644 --- a/chrome_frame/chrome_frame_delegate.h +++ b/chrome_frame/chrome_frame_delegate.h @@ -9,6 +9,7 @@ #include <atlwin.h> #include <queue> +#include "base/file_path.h" #include "base/lock.h" #include "chrome/test/automation/automation_messages.h" #include "ipc/ipc_message.h" @@ -29,6 +30,9 @@ class ChromeFrameDelegate { const FilePath& path, void* user_data, AutomationMsg_ExtensionResponseValues response) = 0; + virtual void OnGetEnabledExtensionsComplete( + void* user_data, + const std::vector<FilePath>& extension_directories) = 0; virtual void OnMessageReceived(const IPC::Message& msg) = 0; // This remains in interface since we call it if Navigate() @@ -68,6 +72,9 @@ class ChromeFrameDelegateImpl : public ChromeFrameDelegate { const FilePath& path, void* user_data, AutomationMsg_ExtensionResponseValues response) {} + virtual void OnGetEnabledExtensionsComplete( + void* user_data, + const std::vector<FilePath>& extension_directories) {} virtual void OnLoadFailed(int error_code, const std::string& url) {} virtual void OnMessageReceived(const IPC::Message& msg); diff --git a/chrome_frame/chrome_frame_npapi.cc b/chrome_frame/chrome_frame_npapi.cc index c760453..573d32e 100644 --- a/chrome_frame/chrome_frame_npapi.cc +++ b/chrome_frame/chrome_frame_npapi.cc @@ -64,7 +64,8 @@ const NPUTF8* ChromeFrameNPAPI::plugin_method_identifier_names_[] = { "postPrivateMessage", "installExtension", "loadExtension", - "enableExtensionAutomation" + "enableExtensionAutomation", + "getEnabledExtensions" }; ChromeFrameNPAPI::PluginMethod ChromeFrameNPAPI::plugin_methods_[] = { @@ -73,6 +74,7 @@ ChromeFrameNPAPI::PluginMethod ChromeFrameNPAPI::plugin_methods_[] = { &ChromeFrameNPAPI::installExtension, &ChromeFrameNPAPI::loadExtension, &ChromeFrameNPAPI::enableExtensionAutomation, + &ChromeFrameNPAPI::getEnabledExtensions, }; NPIdentifier @@ -1414,6 +1416,55 @@ bool ChromeFrameNPAPI::enableExtensionAutomation(NPObject* npobject, return true; } +bool ChromeFrameNPAPI::getEnabledExtensions(NPObject* npobject, + const NPVariant* args, + uint32_t arg_count, + NPVariant* result) { + if (arg_count > 1 || !NPVARIANT_IS_OBJECT(args[0])) { + NOTREACHED(); + return false; + } + + if (!is_privileged_) { + DLOG(WARNING) << "getEnabledExtensions invoked in non-privileged mode"; + return false; + } + + if (!automation_client_.get()) { + DLOG(WARNING) << "getEnabledExtensions invoked with no automaton client"; + NOTREACHED(); + return false; + } + + NPObject* retained_function = npapi::RetainObject(args[0].value.objectValue); + + automation_client_->GetEnabledExtensions(retained_function); + // The response to this command will be returned in the + // OnGetEnabledExtensionsCompleted delegate callback function. + + return true; +} + +void ChromeFrameNPAPI::OnGetEnabledExtensionsComplete( + void* user_data, + const std::vector<FilePath>& extension_directories) { + std::vector<std::wstring> extension_paths; + for (size_t i = 0; i < extension_directories.size(); ++i) { + extension_paths.push_back(extension_directories[i].ToWStringHack()); + } + std::wstring tab_delimited = JoinString(extension_paths, L'\t'); + + std::string res = WideToUTF8(tab_delimited); + + ScopedNpVariant result; + NPVariant param; + STRINGN_TO_NPVARIANT(res.c_str(), res.length(), param); + + NPObject* func = reinterpret_cast<NPObject*>(user_data); + InvokeDefault(func, param, &result); + npapi::ReleaseObject(func); +} + void ChromeFrameNPAPI::FireEvent(const std::string& event_type, const std::string& data) { NPVariant arg; diff --git a/chrome_frame/chrome_frame_npapi.h b/chrome_frame/chrome_frame_npapi.h index d78f3d9..e7e9fc4 100644 --- a/chrome_frame/chrome_frame_npapi.h +++ b/chrome_frame/chrome_frame_npapi.h @@ -151,6 +151,9 @@ END_MSG_MAP() AutomationLaunchResult reason, const std::string& server_version); virtual void OnExtensionInstalled(const FilePath& path, void* user_data, AutomationMsg_ExtensionResponseValues response); + virtual void OnGetEnabledExtensionsComplete( + void* user_data, + const std::vector<FilePath>& extension_directories); private: void SubscribeToFocusEvents(); @@ -208,6 +211,10 @@ END_MSG_MAP() bool enableExtensionAutomation(NPObject* npobject, const NPVariant* args, uint32_t arg_count, NPVariant* result); + // This method is only available when the control is in privileged mode. + bool getEnabledExtensions(NPObject* npobject, const NPVariant* args, + uint32_t arg_count, NPVariant* result); + // Pointers to method implementations. static PluginMethod plugin_methods_[]; diff --git a/chrome_frame/chrome_tab.idl b/chrome_frame/chrome_tab.idl index 31f9472..7a8d03a 100644 --- a/chrome_frame/chrome_tab.idl +++ b/chrome_frame/chrome_tab.idl @@ -73,6 +73,10 @@ interface IChromeFrame : IDispatch { [id(13), hidden] // This method is available only when the control is in privileged mode. HRESULT loadExtension([in] BSTR extension_path); + + [id(14), hidden] + // This method is available only when the control is in privileged mode. + HRESULT getEnabledExtensions(); }; [ @@ -108,6 +112,7 @@ typedef enum { CF_EVENT_DISPID_ONMESSAGE, CF_EVENT_DISPID_ONPRIVATEMESSAGE, CF_EVENT_DISPID_ONEXTENSIONREADY, + CF_EVENT_DISPID_ONGETENABLEDEXTENSIONSCOMPLETE, CF_EVENT_DISPID_ONREADYSTATECHANGED = DISPID_READYSTATECHANGE, } ChromeFrameEventDispId; @@ -127,19 +132,30 @@ library ChromeTabLib { methods: [id(CF_EVENT_DISPID_ONLOAD)] void onload(); + [id(CF_EVENT_DISPID_ONLOADERROR)] void onloaderror(); + [id(CF_EVENT_DISPID_ONMESSAGE)] void onmessage([in] IDispatch* event); + [id(CF_EVENT_DISPID_ONREADYSTATECHANGED)] void onreadystatechanged(); + [id(CF_EVENT_DISPID_ONPRIVATEMESSAGE)] // This event is only fired when the control is in privileged mode. void onprivatemessage([in] IDispatch* event, [in] BSTR target); + [id(CF_EVENT_DISPID_ONEXTENSIONREADY)] // This event is only fired when the control is in privileged mode. // response is one of AutomationMsg_ExtensionResponseValues. void onextensionready([in] BSTR path, [in] long response); + + [id(CF_EVENT_DISPID_ONGETENABLEDEXTENSIONSCOMPLETE)] + // This event is only fired when the control is in privileged mode. + // extension_paths is an array of BSTRs of the base directories of + // enabled extensions. + void ongetenabledextensionscomplete([in] SAFEARRAY(BSTR) extension_paths); }; [uuid(BB1176EE-20DD-41DC-9D1E-AC1335C7BBB0)] |