summaryrefslogtreecommitdiffstats
path: root/chrome/browser/automation
diff options
context:
space:
mode:
authorjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-24 00:52:49 +0000
committerjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-24 00:52:49 +0000
commit7060bb292ea9e20cb0f45dadd1a2b06ef61bcc2f (patch)
tree4919709ddb82f03e87f7627f1a3b03ed1ce21af0 /chrome/browser/automation
parent26199ae574cad50fa5ac8ab222daa60843d8308f (diff)
downloadchromium_src-7060bb292ea9e20cb0f45dadd1a2b06ef61bcc2f.zip
chromium_src-7060bb292ea9e20cb0f45dadd1a2b06ef61bcc2f.tar.gz
chromium_src-7060bb292ea9e20cb0f45dadd1a2b06ef61bcc2f.tar.bz2
Enable "get html from page" functionality for PyAuto.
BUG=36184 TEST=Run PyAuto's content.py and make sure it passes. Review URL: http://codereview.chromium.org/2861019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50678 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/automation')
-rw-r--r--chrome/browser/automation/automation_provider.cc82
-rw-r--r--chrome/browser/automation/automation_provider.h10
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc24
-rw-r--r--chrome/browser/automation/automation_provider_observers.h21
4 files changed, 127 insertions, 10 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 1630f14a..6692f09 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -9,6 +9,7 @@
#include "app/l10n_util.h"
#include "app/message_box_flags.h"
#include "base/callback.h"
+#include "base/file_path.h"
#include "base/file_version_info.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
@@ -1608,6 +1609,19 @@ void AutomationProvider::SetWindowDimensions(Browser* browser,
Send(reply_message);
}
+std::string AutomationProvider::JSONErrorString(std::string err) {
+ std::string prefix = "{\"error\": \"";
+ std::string no_quote_err = err;
+ std::string suffix = "\"}";
+
+ // Don't allow input string to break JSON by embedding quotes.
+ // Try and make sure the input string won't break json quoting rules.
+ if (no_quote_err.find("\"") != std::string::npos)
+ no_quote_err = "unhappy about embedded quote in error string";
+
+ return prefix + no_quote_err + suffix;
+}
+
// Sample json input: { "command": "GetBrowserInfo" }
// Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
// sample json output.
@@ -1796,7 +1810,7 @@ void AutomationProvider::AddHistoryItem(Browser* browser,
if (title.length())
hs->SetPageTitle(gurl, title);
} else {
- json_return = "{\"error\": \"bad args (no URL in dict?).\"}";
+ json_return = JSONErrorString("bad args (no URL in dict?)");
reply_return = false;
}
@@ -1817,7 +1831,7 @@ void AutomationProvider::GetDownloadsInfo(Browser* browser,
scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
if (!profile_->HasCreatedDownloadManager()) {
- json_return = "{\"error\": \"no download manager\"}";
+ json_return = JSONErrorString("no download manager");
reply_return = false;
} else {
// Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
@@ -1883,7 +1897,7 @@ void AutomationProvider::WaitForDownloadsToComplete(
// Look for a quick return.
if (!profile_->HasCreatedDownloadManager()) {
- json_return = "{\"error\": \"no download manager\"}";
+ json_return = JSONErrorString("no download manager");
reply_return = false;
} else {
profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
@@ -1948,16 +1962,16 @@ void AutomationProvider::SetPrefs(Browser* browser,
const PrefService::Preference* pref =
pref_service->FindPreference(path.c_str());
if (!pref) { // Not a registered pref.
- json_return = "{\"error\": \"pref not registered.\"}";
+ json_return = JSONErrorString("pref not registered.");
reply_return = false;
} else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
- json_return = "{\"error\": \"pref is managed. cannot be changed.\"}";
+ json_return = JSONErrorString("pref is managed. cannot be changed.");
reply_return = false;
} else { // Set the pref.
pref_service->Set(path.c_str(), *val);
}
} else {
- json_return = "{\"error\": \"no pref path or value given.\"}";
+ json_return = JSONErrorString("no pref path or value given.");
reply_return = false;
}
@@ -2019,7 +2033,7 @@ void AutomationProvider::SetOmniboxText(Browser* browser,
std::wstring text;
if (!args->GetString(L"text", &text)) {
- json_return = "{\"error\": \"text missing\"}";
+ json_return = JSONErrorString("text missing");
reply_return = false;
} else {
browser->FocusLocationBar();
@@ -2047,7 +2061,7 @@ void AutomationProvider::OmniboxMovePopupSelection(
int count;
if (!args->GetInteger(L"count", &count)) {
- json_return = "{\"error\": \"count missing\"}";
+ json_return = JSONErrorString("count missing");
reply_return = false;
} else {
LocationBar* loc_bar = browser->window()->GetLocationBar();
@@ -2153,7 +2167,7 @@ void AutomationProvider::EnablePlugin(Browser* browser,
bool reply_return = true;
FilePath::StringType path;
if (!args->GetString(L"path", &path)) {
- json_return = "{\"error\": \"path not specified.\"}";
+ json_return = JSONErrorString("path not specified.");
reply_return = false;
} else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path))) {
json_return = StringPrintf("{\"error\": \"Could not enable plugin"
@@ -2176,7 +2190,7 @@ void AutomationProvider::DisablePlugin(Browser* browser,
bool reply_return = true;
FilePath::StringType path;
if (!args->GetString(L"path", &path)) {
- json_return = "{\"error\": \"path not specified.\"}";
+ json_return = JSONErrorString("path not specified.");
reply_return = false;
} else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path))) {
json_return = StringPrintf("{\"error\": \"Could not enable plugin"
@@ -2189,6 +2203,52 @@ void AutomationProvider::DisablePlugin(Browser* browser,
Send(reply_message);
}
+// Sample json input:
+// { "command": "SaveTabContents",
+// "tab_index": 0,
+// "filename": <a full pathname> }
+// Sample json output:
+// {}
+void AutomationProvider::SaveTabContents(Browser* browser,
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ std::string json_return;
+ int tab_index = 0;
+ FilePath::StringType filename;
+ FilePath::StringType parent_directory;
+ TabContents* tab_contents = NULL;
+
+ if (!args->GetInteger(L"tab_index", &tab_index) ||
+ !args->GetString(L"filename", &filename)) {
+ json_return = JSONErrorString("tab_index or filename param missing");
+ } else {
+ tab_contents = browser->GetTabContentsAt(tab_index);
+ if (!tab_contents) {
+ json_return = JSONErrorString("no tab at tab_index");
+ }
+ }
+ if (tab_contents) {
+ // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
+ // used. Nevertheless, SavePackage requires it be valid. Sigh.
+ parent_directory = FilePath(filename).DirName().value();
+ if (!tab_contents->SavePage(FilePath(filename), FilePath(parent_directory),
+ SavePackage::SAVE_AS_ONLY_HTML)) {
+ json_return = JSONErrorString("Could not initiate SavePage");
+ } else {
+ // The observer will delete itself when done.
+ new SavePackageNotificationObserver(tab_contents->save_package(),
+ this, reply_message);
+ return;
+ }
+ }
+
+ // if we get here, error.
+ DCHECK(!json_return.empty());
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, false);
+ Send(reply_message);
+}
+
void AutomationProvider::SendJSONRequest(int handle,
std::string json_request,
IPC::Message* reply_message) {
@@ -2254,6 +2314,8 @@ void AutomationProvider::SendJSONRequest(int handle,
handler_map["GetInitialLoadTimes"] = &AutomationProvider::GetInitialLoadTimes;
+ handler_map["SaveTabContents"] = &AutomationProvider::SaveTabContents;
+
if (error_string.empty()) {
if (handler_map.find(std::string(command)) != handler_map.end()) {
(this->*handler_map[command])(browser, dict_value, reply_message);
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index b644dd4..da32336 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -327,6 +327,10 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
int64 id,
bool* success);
+ // Util for creating a JSON error return string (dict with key
+ // 'error' and error string value). No need to quote input.
+ std::string JSONErrorString(std::string err);
+
// Set window dimensions.
// Uses the JSON interface for input/output.
void SetWindowDimensions(Browser* browser,
@@ -432,6 +436,12 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
DictionaryValue* args,
IPC::Message* reply_message);
+ // Save the contents of a tab into a file.
+ // Uses the JSON interface for input/output.
+ void SaveTabContents(Browser* browser,
+ DictionaryValue* args,
+ IPC::Message* reply_message);
+
// Generic pattern for pyautolib
// Uses the JSON interface for input/output.
void SendJSONRequest(int handle,
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index a59e8d1..0b7f0af 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/dom_operation_notification_details.h"
+#include "chrome/browser/download/save_package.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_updater.h"
@@ -1043,3 +1044,26 @@ void OmniboxAcceptNotificationObserver::Observe(
}
}
+SavePackageNotificationObserver::SavePackageNotificationObserver(
+ SavePackage* save_package,
+ AutomationProvider* automation,
+ IPC::Message* reply_message) : automation_(automation),
+ reply_message_(reply_message) {
+ Source<SavePackage> source(save_package);
+ registrar_.Add(this, NotificationType::SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
+ source);
+}
+
+void SavePackageNotificationObserver::Observe(
+ NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::SAVE_PACKAGE_SUCCESSFULLY_FINISHED) {
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message_, std::string("{}"), true);
+ automation_->Send(reply_message_);
+ delete this;
+ } else {
+ NOTREACHED();
+ }
+}
diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h
index 6bf6a26..fbe8c15 100644
--- a/chrome/browser/automation/automation_provider_observers.h
+++ b/chrome/browser/automation/automation_provider_observers.h
@@ -21,6 +21,7 @@ class Browser;
class Extension;
class ExtensionProcessManager;
class NavigationController;
+class SavePackage;
class TabContents;
namespace IPC {
@@ -632,4 +633,24 @@ class OmniboxAcceptNotificationObserver : public NotificationObserver {
DISALLOW_COPY_AND_ASSIGN(OmniboxAcceptNotificationObserver);
};
+// Allows the automation provider to wait for a save package notification.
+class SavePackageNotificationObserver : public NotificationObserver {
+ public:
+ SavePackageNotificationObserver(SavePackage* save_package,
+ AutomationProvider* automation,
+ IPC::Message* reply_message);
+ virtual ~SavePackageNotificationObserver() {}
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ NotificationRegistrar registrar_;
+ AutomationProvider* automation_;
+ IPC::Message* reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(SavePackageNotificationObserver);
+};
+
#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_OBSERVERS_H_