summaryrefslogtreecommitdiffstats
path: root/chrome/browser/automation
diff options
context:
space:
mode:
authorjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-02 02:24:04 +0000
committerjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-02 02:24:04 +0000
commit59a6112447827f01c4e40ef3072819f821989570 (patch)
treebe9f7a44a64e899dd2c27fb35d5c17bacd77b088 /chrome/browser/automation
parent94953a56eb19ddef86c0264ef9cd0ac1f0f18332 (diff)
downloadchromium_src-59a6112447827f01c4e40ef3072819f821989570.zip
chromium_src-59a6112447827f01c4e40ef3072819f821989570.tar.gz
chromium_src-59a6112447827f01c4e40ef3072819f821989570.tar.bz2
Add generic "json dict" entry point for pyauto commands. Will prevent
the need to modify the automation proxy anymore. New pyauto commands will only need to edit pyauto.py (to add a new SendJSONCommand() call) and browser_proxy.cc (to implement the other side). Contrast with the normal editing of ~8 files. Also added WaitForAllDownloadsToComplete using new JSON path. BUG=http://crbug.com/39274 Review URL: http://codereview.chromium.org/1547012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43436 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/automation')
-rw-r--r--chrome/browser/automation/automation_provider.cc109
-rw-r--r--chrome/browser/automation/automation_provider.h11
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc11
-rw-r--r--chrome/browser/automation/automation_provider_observers.h47
4 files changed, 178 insertions, 0 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index c6ee650..2b88a29 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -11,6 +11,7 @@
#include "base/callback.h"
#include "base/file_version_info.h"
#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
#include "base/keyboard_codes.h"
#include "base/message_loop.h"
#include "base/path_service.h"
@@ -430,6 +431,8 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
SetBookmarkURL)
IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
RemoveBookmark)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
+ SendJSONRequest)
IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
ClickInfoBarAccept)
@@ -1500,6 +1503,112 @@ void AutomationProvider::RemoveBookmark(int handle,
*success = false;
}
+void AutomationProvider::WaitForDownloadsToComplete(
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
+ AutomationProviderDownloadManagerObserver observer;
+ std::vector<DownloadItem*> downloads;
+
+ // Look for a quick return.
+ if (!profile_->HasCreatedDownloadManager()) {
+ json_return = "{'error': 'no download manager'}";
+ reply_return = false;
+ } else {
+ profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
+ FilePath());
+ downloads = observer.Downloads();
+ if (downloads.size() == 0) {
+ json_return = "{}";
+ }
+ }
+ if (!json_return.empty()) {
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
+ }
+
+ // The observer owns itself. When the last observed item pings, it
+ // deletes itself.
+ AutomationProviderDownloadItemObserver* item_observer =
+ new AutomationProviderDownloadItemObserver(
+ this, reply_message, downloads.size());
+ for (std::vector<DownloadItem*>::iterator i = downloads.begin();
+ i != downloads.end();
+ i++) {
+ (*i)->AddObserver(item_observer);
+ }
+}
+
+void AutomationProvider::SendJSONRequest(
+ int handle,
+ std::string json_request,
+ IPC::Message* reply_message) {
+ Browser* browser = NULL;
+ std::string error_string;
+ scoped_ptr<Value> values;
+
+ // Basic error checking.
+ if (browser_tracker_->ContainsHandle(handle)) {
+ browser = browser_tracker_->GetResource(handle);
+ }
+ if (!browser) {
+ error_string = "no browser object";
+ } else {
+ base::JSONReader reader;
+ std::string error;
+ values.reset(reader.ReadAndReturnError(json_request, true, &error));
+ if (!error.empty()) {
+ error_string = error;
+ }
+ }
+
+ // Make sure input is a dict with a string command.
+ std::string command;
+ DictionaryValue* dict_value = NULL;
+ if (error_string.empty()) {
+ if (values->GetType() != Value::TYPE_DICTIONARY) {
+ error_string = "not a dict or no command key in dict";
+ } else {
+ // Ownership remains with "values" variable.
+ dict_value = static_cast<DictionaryValue*>(values.get());
+ if (!dict_value->GetStringASCII(std::string("command"), &command)) {
+ error_string = "no command key in dict or not a string command";
+ }
+ }
+ }
+
+ if (error_string.empty()) {
+ // TODO(jrg): table of calls; async gets passed reply_message,
+ // sync methods gets passed an output json dict which we package
+ // up and send. Right now we only have one.
+ if (command == "WaitForAllDownloadsToComplete") {
+ this->WaitForDownloadsToComplete(dict_value, reply_message);
+ return;
+ } else {
+ error_string = "unknown command";
+ }
+ }
+
+ // If we hit an error, return info.
+ // Return a dict of {'error', 'descriptive_string_for_error'}.
+ // Else return an empty dict.
+ std::string json_string;
+ bool success = true;
+ if (!error_string.empty()) {
+ scoped_ptr<DictionaryValue> dict(new DictionaryValue);
+ dict->SetString(L"error", error_string);
+ base::JSONWriter::Write(dict.get(), false, &json_string);
+ success = false;
+ } else {
+ json_string = "{}";
+ }
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_string, success);
+ Send(reply_message);
+}
+
void AutomationProvider::HandleInspectElementRequest(
int handle, int x, int y, IPC::Message* reply_message) {
TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 2d680b1..929bc20 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -17,6 +17,7 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
+#include "base/values.h"
#include "chrome/browser/automation/automation_autocomplete_edit_tracker.h"
#include "chrome/browser/automation/automation_browser_tracker.h"
#include "chrome/browser/automation/automation_resource_message_filter.h"
@@ -319,6 +320,16 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
int64 id,
bool* success);
+ // Wait for all downloads to complete.
+ void WaitForDownloadsToComplete(
+ DictionaryValue* args,
+ IPC::Message* reply_message);
+
+ // Generic pattern for pyautolib
+ void SendJSONRequest(int handle,
+ std::string json_request,
+ IPC::Message* reply_message);
+
// Responds to InspectElement request
void HandleInspectElementRequest(int handle,
int x,
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index 7e5ac24..da7537d 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -767,3 +767,14 @@ void AutomationProviderBookmarkModelObserver::ReplyAndDelete(bool success) {
automation_provider_->Send(reply_message_);
delete this;
}
+
+void AutomationProviderDownloadItemObserver::OnDownloadFileCompleted(
+ DownloadItem* download) {
+ download->RemoveObserver(this);
+ if (--downloads_ == 0) {
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message_, std::string("{}"), true);
+ provider_->Send(reply_message_);
+ delete this;
+ }
+}
diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h
index 0d75e70..892be51 100644
--- a/chrome/browser/automation/automation_provider_observers.h
+++ b/chrome/browser/automation/automation_provider_observers.h
@@ -9,6 +9,7 @@
#include <set>
#include "chrome/browser/bookmarks/bookmark_model_observer.h"
+#include "chrome/browser/download/download_manager.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_type.h"
@@ -452,4 +453,50 @@ class AutomationProviderBookmarkModelObserver : BookmarkModelObserver {
DISALLOW_COPY_AND_ASSIGN(AutomationProviderBookmarkModelObserver);
};
+// When asked for pending downloads, the DownloadManager places
+// results in a DownloadManager::Observer.
+class AutomationProviderDownloadManagerObserver :
+ public DownloadManager::Observer {
+ public:
+ AutomationProviderDownloadManagerObserver() : DownloadManager::Observer() {}
+ virtual ~AutomationProviderDownloadManagerObserver() {}
+ virtual void ModelChanged() {}
+ virtual void SetDownloads(std::vector<DownloadItem*>& downloads) {
+ downloads_ = downloads;
+ }
+ std::vector<DownloadItem*> Downloads() {
+ return downloads_;
+ }
+ private:
+ std::vector<DownloadItem*> downloads_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutomationProviderDownloadManagerObserver);
+};
+
+
+// Allows the automation provider to wait for all downloads to finish.
+class AutomationProviderDownloadItemObserver : public DownloadItem::Observer {
+ public:
+ AutomationProviderDownloadItemObserver(
+ AutomationProvider* provider,
+ IPC::Message* reply_message,
+ int downloads) {
+ provider_ = provider;
+ reply_message_ = reply_message;
+ downloads_ = downloads;
+ }
+ virtual ~AutomationProviderDownloadItemObserver() {}
+
+ virtual void OnDownloadUpdated(DownloadItem* download) { }
+ virtual void OnDownloadFileCompleted(DownloadItem* download);
+ virtual void OnDownloadOpened(DownloadItem* download) { }
+
+ private:
+ AutomationProvider* provider_;
+ IPC::Message* reply_message_;
+ int downloads_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutomationProviderDownloadItemObserver);
+};
+
#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_OBSERVERS_H_