summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorvandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-11 22:41:43 +0000
committervandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-11 22:41:43 +0000
commitf6ff0dfd962666d79e4919e23c0078283fed2922 (patch)
tree88a7462b11dc1463ef7cc728ccabaf7012cb188d /chrome
parentb3839a6adf2c4ec9572852577b2c270b9266820a (diff)
downloadchromium_src-f6ff0dfd962666d79e4919e23c0078283fed2922.zip
chromium_src-f6ff0dfd962666d79e4919e23c0078283fed2922.tar.gz
chromium_src-f6ff0dfd962666d79e4919e23c0078283fed2922.tar.bz2
Revert 52054: causing startup tests to fail on Vista and XP perf dbg
Revert 52054 - Refactor json automation interface for pyauto hooks. Reduces the number of lines you need to add per new automation hook. Shaves off several lines of code. Refactor pyauto.py to obviate raising exception in case the json interfaces produces an error string. Review URL: http://codereview.chromium.org/2898001 TBR=nirnimesh@chromium.org Review URL: http://codereview.chromium.org/2977001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52067 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider.cc345
-rw-r--r--chrome/browser/automation/automation_provider.h6
-rw-r--r--chrome/browser/automation/automation_provider_json.cc51
-rw-r--r--chrome/browser/automation/automation_provider_json.h47
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc21
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/test/pyautolib/pyauto.py90
7 files changed, 296 insertions, 266 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index b4bc595..5fdce54 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -31,7 +31,6 @@
#include "chrome/browser/app_modal_dialog_queue.h"
#include "chrome/browser/autofill/autofill_manager.h"
#include "chrome/browser/automation/automation_extension_tracker.h"
-#include "chrome/browser/automation/automation_provider_json.h"
#include "chrome/browser/automation/automation_provider_list.h"
#include "chrome/browser/automation/automation_provider_observers.h"
#include "chrome/browser/automation/extension_port_container.h"
@@ -1711,7 +1710,9 @@ void AutomationProvider::SetWindowDimensions(Browser* browser,
if (args->GetInteger(L"height", &height))
rect.set_height(height);
browser->window()->SetBounds(rect);
- AutomationJSONReply(this, reply_message).SendSuccess(NULL);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, std::string("{}"), true);
+ Send(reply_message);
}
// Sample json input: { "command": "GetBrowserInfo" }
@@ -1720,6 +1721,9 @@ void AutomationProvider::SetWindowDimensions(Browser* browser,
void AutomationProvider::GetBrowserInfo(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
+
DictionaryValue* properties = new DictionaryValue;
properties->SetString(L"ChromeVersion", chrome::kChromeVersion);
properties->SetString(L"BrowserProcessExecutableName",
@@ -1830,7 +1834,11 @@ void AutomationProvider::GetBrowserInfo(Browser* browser,
}
}
return_value->Set(L"extension_processes", extension_processes);
- AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
+
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input: { "command": "GetHistoryInfo",
@@ -1867,12 +1875,14 @@ void AutomationProvider::GetHistoryInfo(Browser* browser,
void AutomationProvider::AddHistoryItem(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ bool reply_return = true;
+ std::string json_return = "{}";
+
DictionaryValue* item = NULL;
args->GetDictionary(L"item", &item);
string16 url_text;
string16 title;
base::Time time = base::Time::Now();
- AutomationJSONReply reply(this, reply_message);
if (item->GetString("url", &url_text)) {
GURL gurl(url_text);
@@ -1898,10 +1908,13 @@ void AutomationProvider::AddHistoryItem(Browser* browser,
if (title.length())
hs->SetPageTitle(gurl, title);
} else {
- reply.SendError("bad args (no URL in dict?)");
- return;
+ json_return = JSONErrorString("bad args (no URL in dict?)");
+ reply_return = false;
}
- reply.SendSuccess(NULL);
+
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input: { "command": "GetDownloadsInfo" }
@@ -1909,14 +1922,15 @@ void AutomationProvider::AddHistoryItem(Browser* browser,
void AutomationProvider::GetDownloadsInfo(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
AutomationProviderDownloadManagerObserver observer;
std::vector<DownloadItem*> downloads;
scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
- AutomationJSONReply reply(this, reply_message);
if (!profile_->HasCreatedDownloadManager()) {
- reply.SendError("no download manager");
- return;
+ json_return = JSONErrorString("no download manager");
+ reply_return = false;
} else {
// Use DownloadManager's GetDownloads() method and not GetCurrentDownloads()
// since that would be transient; a download might enter and empty out
@@ -1961,8 +1975,11 @@ void AutomationProvider::GetDownloadsInfo(Browser* browser,
list_of_downloads->Append(dl_item_value);
}
return_value->Set(L"downloads", list_of_downloads);
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
- reply.SendSuccess(return_value.get());
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
// All value objects allocated above are owned by |return_value|
// and get freed by it.
}
@@ -1971,22 +1988,29 @@ void AutomationProvider::WaitForDownloadsToComplete(
Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
AutomationProviderDownloadManagerObserver observer;
std::vector<DownloadItem*> downloads;
- AutomationJSONReply reply(this, reply_message);
// Look for a quick return.
if (!profile_->HasCreatedDownloadManager()) {
- reply.SendSuccess(NULL); // No download manager.
- return;
+ json_return = JSONErrorString("no download manager");
+ reply_return = false;
} else {
- profile_->GetDownloadManager()->GetCurrentDownloads(&observer, FilePath());
+ profile_->GetDownloadManager()->GetCurrentDownloads(&observer,
+ FilePath());
downloads = observer.Downloads();
if (downloads.size() == 0) {
- reply.SendSuccess(NULL);
- return;
+ json_return = "{}";
}
}
+ if (!json_return.empty()) {
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
+ return;
+ }
// The observer owns itself. When the last observed item pings, it
// deletes itself.
@@ -2005,6 +2029,9 @@ void AutomationProvider::WaitForDownloadsToComplete(
void AutomationProvider::GetPrefsInfo(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
+
const PrefService::PreferenceSet& prefs =
profile_->GetPrefs()->preference_set();
DictionaryValue* items = new DictionaryValue;
@@ -2014,35 +2041,42 @@ void AutomationProvider::GetPrefsInfo(Browser* browser,
}
scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
return_value->Set(L"prefs", items); // return_value owns items.
- AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
+
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input: { "command": "SetPrefs", "path": path, "value": value }
void AutomationProvider::SetPrefs(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ bool reply_return = true;
+ std::string json_return = "{}";
std::wstring path;
Value* val;
- AutomationJSONReply reply(this, reply_message);
if (args->GetString(L"path", &path) && args->Get(L"value", &val)) {
PrefService* pref_service = profile_->GetPrefs();
const PrefService::Preference* pref =
pref_service->FindPreference(path.c_str());
if (!pref) { // Not a registered pref.
- reply.SendError("pref not registered.");
- return;
+ json_return = JSONErrorString("pref not registered.");
+ reply_return = false;
} else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
- reply.SendError("pref is managed. cannot be changed.");
- return;
+ json_return = JSONErrorString("pref is managed. cannot be changed.");
+ reply_return = false;
} else { // Set the pref.
pref_service->Set(path.c_str(), *val);
}
} else {
- reply.SendError("no pref path or value given.");
- return;
+ json_return = JSONErrorString("no pref path or value given.");
+ reply_return = false;
}
- reply.SendSuccess(NULL);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input: { "command": "GetOmniboxInfo" }
@@ -2050,6 +2084,8 @@ void AutomationProvider::SetPrefs(Browser* browser,
void AutomationProvider::GetOmniboxInfo(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
LocationBar* loc_bar = browser->window()->GetLocationBar();
@@ -2080,7 +2116,10 @@ void AutomationProvider::GetOmniboxInfo(Browser* browser,
properties->SetString(L"text", edit_view->GetText());
return_value->Set(L"properties", properties);
- AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input: { "command": "SetOmniboxText",
@@ -2088,11 +2127,13 @@ void AutomationProvider::GetOmniboxInfo(Browser* browser,
void AutomationProvider::SetOmniboxText(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return = "{}";
+ bool reply_return = true;
std::wstring text;
- AutomationJSONReply reply(this, reply_message);
+
if (!args->GetString(L"text", &text)) {
- reply.SendError("text missing");
- return;
+ json_return = JSONErrorString("text missing");
+ reply_return = false;
} else {
browser->FocusLocationBar();
LocationBar* loc_bar = browser->window()->GetLocationBar();
@@ -2101,7 +2142,9 @@ void AutomationProvider::SetOmniboxText(Browser* browser,
edit_view->SetUserText(text);
}
- reply.SendSuccess(NULL);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input: { "command": "OmniboxMovePopupSelection",
@@ -2112,18 +2155,22 @@ void AutomationProvider::OmniboxMovePopupSelection(
Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return = "{}";
+ bool reply_return = true;
int count;
- AutomationJSONReply reply(this, reply_message);
+
if (!args->GetInteger(L"count", &count)) {
- reply.SendError("count missing");
- return;
+ json_return = JSONErrorString("count missing");
+ reply_return = false;
} else {
LocationBar* loc_bar = browser->window()->GetLocationBar();
AutocompleteEditModel* model = loc_bar->location_entry()->model();
model->OnUpOrDownKeyPressed(count);
}
- reply.SendSuccess(NULL);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input: { "command": "OmniboxAcceptInput" }
@@ -2148,7 +2195,12 @@ void AutomationProvider::GetInitialLoadTimes(
IPC::Message* reply_message) {
scoped_ptr<DictionaryValue> return_value(
initial_load_observer_->GetTimingInformation());
- AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
+
+ std::string json_return;
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, true);
+ Send(reply_message);
}
// Sample json input: { "command": "GetPluginsInfo" }
@@ -2156,6 +2208,9 @@ void AutomationProvider::GetInitialLoadTimes(
void AutomationProvider::GetPluginsInfo(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
+
std::vector<WebPluginInfo> plugins;
NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
ListValue* items = new ListValue;
@@ -2195,7 +2250,10 @@ void AutomationProvider::GetPluginsInfo(Browser* browser,
scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
return_value->Set(L"plugins", items); // return_value owns items.
- AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input:
@@ -2204,15 +2262,21 @@ void AutomationProvider::GetPluginsInfo(Browser* browser,
void AutomationProvider::EnablePlugin(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return = "{}";
+ bool reply_return = true;
FilePath::StringType path;
- AutomationJSONReply reply(this, reply_message);
- if (!args->GetString(L"path", &path))
- reply.SendError("path not specified.");
- else if (!NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(path)))
- reply.SendError(StringPrintf("Could not enable plugin for path %s.",
- path.c_str()));
- else
- reply.SendSuccess(NULL);
+ if (!args->GetString(L"path", &path)) {
+ 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"
+ " for path %s.\"}", path.c_str());
+ reply_return = false;
+ }
+
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input:
@@ -2221,15 +2285,21 @@ void AutomationProvider::EnablePlugin(Browser* browser,
void AutomationProvider::DisablePlugin(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return = "{}";
+ bool reply_return = true;
FilePath::StringType path;
- AutomationJSONReply reply(this, reply_message);
- if (!args->GetString(L"path", &path))
- reply.SendError("path not specified.");
- else if (!NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(path)))
- reply.SendError(StringPrintf("Could not disable plugin for path %s.",
- path.c_str()));
- else
- reply.SendSuccess(NULL);
+ if (!args->GetString(L"path", &path)) {
+ 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"
+ " for path %s.\"}", path.c_str());
+ reply_return = false;
+ }
+
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
// Sample json input:
@@ -2241,35 +2311,41 @@ void AutomationProvider::DisablePlugin(Browser* browser,
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;
- AutomationJSONReply reply(this, reply_message);
if (!args->GetInteger(L"tab_index", &tab_index) ||
!args->GetString(L"filename", &filename)) {
- reply.SendError("tab_index or filename param missing");
- return;
+ json_return = JSONErrorString("tab_index or filename param missing");
} else {
tab_contents = browser->GetTabContentsAt(tab_index);
if (!tab_contents) {
- reply.SendError("no tab at tab_index");
- return;
+ json_return = JSONErrorString("no tab at tab_index");
}
}
- // 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)) {
- reply.SendError("Could not initiate SavePage");
- return;
- } else {
- // The observer will delete itself when done.
- new SavePackageNotificationObserver(tab_contents->save_package(),
- this, reply_message);
+ 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);
}
// Sample json input: { "command": "GetThemeInfo" }
@@ -2285,7 +2361,12 @@ void AutomationProvider::GetThemeInfo(Browser* browser,
return_value->Set(L"colors", theme->GetThemeColors()->DeepCopy());
return_value->Set(L"tints", theme->GetThemeTints()->DeepCopy());
}
- AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
+
+ std::string json_return;
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, true);
+ Send(reply_message);
}
// Sample json input:
@@ -2295,11 +2376,13 @@ void AutomationProvider::GetThemeInfo(Browser* browser,
void AutomationProvider::GetAutoFillProfile(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
+ std::string json_return;
+ bool reply_return = true;
+
// Get the AutoFillProfiles currently in the database.
int tab_index = 0;
args->GetInteger(L"tab_index", &tab_index);
TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
- AutomationJSONReply reply(this, reply_message);
if (tab_contents) {
PersonalDataManager* pdm = tab_contents->profile()->GetOriginalProfile()
@@ -2315,15 +2398,20 @@ void AutomationProvider::GetAutoFillProfile(Browser* browser,
return_value->Set(L"profiles", profiles);
return_value->Set(L"credit_cards", cards);
- reply.SendSuccess(return_value.get());
+
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
} else {
- reply.SendError("No PersonalDataManager.");
- return;
+ json_return = JSONErrorString("No PersonalDataManager.");
+ reply_return = false;
}
} else {
- reply.SendError("No tab at that index.");
- return;
+ json_return = JSONErrorString("No tab at that index.");
+ reply_return = false;
}
+
+ AutomationMsg_SendJSONRequest::WriteReplyParams(reply_message, json_return,
+ reply_return);
+ Send(reply_message);
}
// Refer to FillAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample
@@ -2332,26 +2420,23 @@ void AutomationProvider::GetAutoFillProfile(Browser* browser,
void AutomationProvider::FillAutoFillProfile(Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message) {
- AutomationJSONReply reply(this, reply_message);
+ std::string json_return = "{}";
+ bool reply_return = true;
+
ListValue* profiles = NULL;
ListValue* cards = NULL;
args->GetList(L"profiles", &profiles);
args->GetList(L"credit_cards", &cards);
- std::string error_mesg;
std::vector<AutoFillProfile> autofill_profiles;
std::vector<CreditCard> credit_cards;
// Create an AutoFillProfile for each of the dictionary profiles.
if (profiles) {
- autofill_profiles = GetAutoFillProfilesFromList(*profiles, &error_mesg);
+ autofill_profiles = GetAutoFillProfilesFromList(*profiles, &json_return);
}
// Create a CreditCard for each of the dictionary values.
if (cards) {
- credit_cards = GetCreditCardsFromList(*cards, &error_mesg);
- }
- if (!error_mesg.empty()) {
- reply.SendError(error_mesg);
- return;
+ credit_cards = GetCreditCardsFromList(*cards, &json_return);
}
// Save the AutoFillProfiles.
@@ -2366,14 +2451,16 @@ void AutomationProvider::FillAutoFillProfile(Browser* browser,
pdm->OnAutoFillDialogApply(profiles? &autofill_profiles : NULL,
cards? &credit_cards : NULL);
} else {
- reply.SendError("No PersonalDataManager.");
- return;
+ json_return = JSONErrorString("No PersonalDataManager.");
+ reply_return = false;
}
} else {
- reply.SendError("No tab at that index.");
- return;
+ json_return = JSONErrorString("No tab at that index.");
+ reply_return = false;
}
- reply.SendSuccess(NULL);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message, json_return, reply_return);
+ Send(reply_message);
}
/* static */
@@ -2435,7 +2522,7 @@ ListValue* AutomationProvider::GetListFromCreditCards(
/* static */
std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList(
- const ListValue& profiles, std::string* err_mesg) {
+ const ListValue& profiles, std::string* json_return) {
std::vector<AutoFillProfile> autofill_profiles;
DictionaryValue* profile_info = NULL;
string16 profile_label;
@@ -2458,7 +2545,7 @@ std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList(
if (profile_info->GetStringAsUTF16(type_it->second, &current_value)) {
profile.SetInfo(AutoFillType(type_it->first), current_value);
} else {
- *err_mesg= "All values must be strings";
+ *json_return = JSONErrorString("All values must be strings");
break;
}
}
@@ -2470,7 +2557,7 @@ std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList(
/* static */
std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList(
- const ListValue& cards, std::string* err_mesg) {
+ const ListValue& cards, std::string* json_return) {
std::vector<CreditCard> credit_cards;
DictionaryValue* card_info = NULL;
string16 card_label;
@@ -2492,7 +2579,7 @@ std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList(
if (card_info->GetStringAsUTF16(type_it->second, &current_value)) {
card.SetInfo(AutoFillType(type_it->first), current_value);
} else {
- *err_mesg= "All values must be strings";
+ *json_return = JSONErrorString("All values must be strings");
break;
}
}
@@ -2536,42 +2623,50 @@ std::map<AutoFillFieldType, std::wstring>
return credit_card_type_to_string;
}
+/* static */
+std::string AutomationProvider::JSONErrorString(const std::string& err) {
+ std::string prefix = "{\"error\": \"";
+ std::string no_quote_err;
+ std::string suffix = "\"}";
+
+ base::JsonDoubleQuote(err, false, &no_quote_err);
+ return prefix + no_quote_err + suffix;
+}
+
void AutomationProvider::SendJSONRequest(int handle,
std::string json_request,
IPC::Message* reply_message) {
Browser* browser = NULL;
+ std::string error_string;
scoped_ptr<Value> values;
- AutomationJSONReply reply(this, reply_message);
// Basic error checking.
if (browser_tracker_->ContainsHandle(handle)) {
browser = browser_tracker_->GetResource(handle);
}
if (!browser) {
- reply.SendError("no browser object");
- return;
+ error_string = "no browser object";
} else {
base::JSONReader reader;
std::string error;
values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
if (!error.empty()) {
- reply.SendError(error);
- return;
+ error_string = error;
}
}
// Make sure input is a dict with a string command.
std::string command;
DictionaryValue* dict_value = NULL;
- if (values->GetType() != Value::TYPE_DICTIONARY) {
- reply.SendError("not a dict");
- return;
- } else {
- // Ownership remains with "values" variable.
- dict_value = static_cast<DictionaryValue*>(values.get());
- if (!dict_value->GetStringASCII(std::string("command"), &command)) {
- reply.SendError("no command key in dict or not a string command");
- return;
+ 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";
+ }
}
}
@@ -2582,7 +2677,6 @@ void AutomationProvider::SendJSONRequest(int handle,
handler_map["GetPluginsInfo"] = &AutomationProvider::GetPluginsInfo;
handler_map["GetBrowserInfo"] = &AutomationProvider::GetBrowserInfo;
-
handler_map["GetHistoryInfo"] = &AutomationProvider::GetHistoryInfo;
handler_map["AddHistoryItem"] = &AutomationProvider::AddHistoryItem;
@@ -2611,16 +2705,35 @@ void AutomationProvider::SendJSONRequest(int handle,
handler_map["GetAutoFillProfile"] = &AutomationProvider::GetAutoFillProfile;
handler_map["FillAutoFillProfile"] = &AutomationProvider::FillAutoFillProfile;
- if (handler_map.find(std::string(command)) != handler_map.end()) {
- (this->*handler_map[command])(browser, dict_value, reply_message);
- } else {
- std::string error_string = "Unknown command. Options: ";
- for (std::map<std::string, JsonHandler>::const_iterator it =
- handler_map.begin(); it != handler_map.end(); ++it) {
- error_string += it->first + ", ";
+ if (error_string.empty()) {
+ if (handler_map.find(std::string(command)) != handler_map.end()) {
+ (this->*handler_map[command])(browser, dict_value, reply_message);
+ return;
+ } else {
+ error_string = "Unknown command. Options: ";
+ for (std::map<std::string, JsonHandler>::const_iterator it =
+ handler_map.begin(); it != handler_map.end(); ++it) {
+ error_string += it->first + ", ";
+ }
}
- reply.SendError(error_string);
}
+
+ // 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(
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 0598179..d8e8d0b 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -463,11 +463,11 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
// data structure used in the browser.
// Args:
// profiles/cards: the ListValue of profiles/credit cards to translate.
- // err_mesg: a pointer to the return string in case of error.
+ // json_return: a pointer to the return string in case of error.
static std::vector<AutoFillProfile> GetAutoFillProfilesFromList(
- const ListValue& profiles, std::string* err_mesg);
+ const ListValue& profiles, std::string* json_return);
static std::vector<CreditCard> GetCreditCardsFromList(
- const ListValue& cards, std::string* err_mesg);
+ const ListValue& cards, std::string* json_return);
// The opposite of the above: translates from the internal data structure
// for profiles and credit cards to a ListValue of DictionaryValues. The
diff --git a/chrome/browser/automation/automation_provider_json.cc b/chrome/browser/automation/automation_provider_json.cc
deleted file mode 100644
index 3cfd5e6..0000000
--- a/chrome/browser/automation/automation_provider_json.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/automation/automation_provider_json.h"
-
-#include "base/json/json_writer.h"
-#include "base/json/string_escape.h"
-#include "chrome/test/automation/automation_messages.h"
-
-
-AutomationJSONReply::AutomationJSONReply(AutomationProvider* provider,
- IPC::Message* reply_message)
- : provider_(provider),
- message_(reply_message) {
-}
-
-AutomationJSONReply::~AutomationJSONReply() {
- DCHECK(!message_) << "JSON automation request not replied!";
-}
-
-void AutomationJSONReply::SendSuccess(const Value* value) {
- DCHECK(message_) << "Resending reply for JSON automation request";
- std::string json_string = "{}";
- if (value)
- base::JSONWriter::Write(value, false, &json_string);
- AutomationMsg_SendJSONRequest::WriteReplyParams(
- message_, json_string, true);
- provider_->Send(message_);
- message_ = NULL;
-}
-
-void AutomationJSONReply::SendError(const std::string& error_mesg) {
- DCHECK(message_) << "Resending reply for JSON automation request";
- std::string json_string = JSONErrorString(error_mesg);
- AutomationMsg_SendJSONRequest::WriteReplyParams(
- message_, json_string, false);
- provider_->Send(message_);
- message_ = NULL;
-}
-
-/* static */
-std::string AutomationJSONReply::JSONErrorString(const std::string& err) {
- std::string prefix = "{\"error\": \"";
- std::string no_quote_err;
- std::string suffix = "\"}";
-
- base::JsonDoubleQuote(err, false, &no_quote_err);
- return prefix + no_quote_err + suffix;
-}
-
diff --git a/chrome/browser/automation/automation_provider_json.h b/chrome/browser/automation/automation_provider_json.h
deleted file mode 100644
index 58f2c1f..0000000
--- a/chrome/browser/automation/automation_provider_json.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Support utilities for the JSON automation interface used by PyAuto.
-// Automation call is initiated by SendJSONRequest() in browser_proxy.h which
-// is serviced by handlers in automation_provider.cc and the resulting
-// success/error reply is sent using AutomationJSONReply defined here.
-
-#ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_JSON_H_
-#define CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_JSON_H_
-
-#include <string>
-
-#include "base/values.h"
-#include "ipc/ipc_message.h"
-#include "chrome/browser/automation/automation_provider.h"
-
-// Represent a reply on the JSON Automation interface used by PyAuto.
-class AutomationJSONReply {
-
- public:
- // Creates a new reply object for the IPC message |reply_message| for
- // |provider|.
- AutomationJSONReply(AutomationProvider* provider,
- IPC::Message* reply_message);
-
- ~AutomationJSONReply();
-
- // Send a success reply along with data contained in |value|.
- // An empty message will be sent if |value| is NULL.
- void SendSuccess(const Value* value);
-
- // Send an error reply along with error message |error_mesg|.
- void SendError(const std::string& error_mesg);
-
- private:
- // Util for creating a JSON error return string (dict with key
- // 'error' and error string value). No need to quote input.
- static std::string JSONErrorString(const std::string& err);
-
- AutomationProvider* provider_;
- IPC::Message* message_;
-};
-
-#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_JSON_H_
-
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index 3e7534b..0b7f0af 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -9,7 +9,6 @@
#include "base/string_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/automation/automation_provider.h"
-#include "chrome/browser/automation/automation_provider_json.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/download/save_package.h"
@@ -975,7 +974,9 @@ void AutomationProviderDownloadItemObserver::OnDownloadFileCompleted(
DownloadItem* download) {
download->RemoveObserver(this);
if (--downloads_ == 0) {
- AutomationJSONReply(provider_, reply_message_).SendSuccess(NULL);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message_, std::string("{}"), true);
+ provider_->Send(reply_message_);
delete this;
}
}
@@ -983,6 +984,8 @@ void AutomationProviderDownloadItemObserver::OnDownloadFileCompleted(
void AutomationProviderHistoryObserver::HistoryQueryComplete(
HistoryService::Handle request_handle,
history::QueryResults* results) {
+ std::string json_return;
+ bool reply_return = true;
scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
ListValue* history_list = new ListValue;
@@ -1002,8 +1005,10 @@ void AutomationProviderHistoryObserver::HistoryQueryComplete(
return_value->Set(L"history", history_list);
// Return history info.
- AutomationJSONReply reply(provider_, reply_message_);
- reply.SendSuccess(return_value.get());
+ base::JSONWriter::Write(return_value.get(), false, &json_return);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message_, json_return, reply_return);
+ provider_->Send(reply_message_);
delete this;
}
@@ -1030,7 +1035,9 @@ void OmniboxAcceptNotificationObserver::Observe(
const NotificationDetails& details) {
if (type == NotificationType::LOAD_STOP ||
type == NotificationType::AUTH_NEEDED) {
- AutomationJSONReply(automation_, reply_message_).SendSuccess(NULL);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message_, std::string("{}"), false);
+ automation_->Send(reply_message_);
delete this;
} else {
NOTREACHED();
@@ -1052,7 +1059,9 @@ void SavePackageNotificationObserver::Observe(
const NotificationSource& source,
const NotificationDetails& details) {
if (type == NotificationType::SAVE_PACKAGE_SUCCESSFULLY_FINISHED) {
- AutomationJSONReply(automation_, reply_message_).SendSuccess(NULL);
+ AutomationMsg_SendJSONRequest::WriteReplyParams(
+ reply_message_, std::string("{}"), true);
+ automation_->Send(reply_message_);
delete this;
} else {
NOTREACHED();
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index c50132d..809a79e 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -195,8 +195,6 @@
'browser/automation/automation_provider_win.cc',
'browser/automation/automation_provider.cc',
'browser/automation/automation_provider.h',
- 'browser/automation/automation_provider_json.h',
- 'browser/automation/automation_provider_json.cc',
'browser/automation/automation_provider_list.cc',
'browser/automation/automation_provider_list_generic.cc',
'browser/automation/automation_provider_list_mac.mm',
diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py
index 5a82c5f..4b94b3d 100644
--- a/chrome/test/pyautolib/pyauto.py
+++ b/chrome/test/pyautolib/pyauto.py
@@ -260,33 +260,6 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
time.sleep(retry_sleep)
return False
- def _GetResultFromJSONRequest(self, cmd_dict, windex=0):
- """Issue call over the JSON automation channel and fetch output.
-
- This method packages the given dictionary into a json string, sends it
- over the JSON automation channel, loads the json output string returned,
- and returns it back as a dictionary.
-
- Args:
- cmd_dict: the command dictionary. It must have a 'command' key
- Sample:
- {
- 'command': 'SetOmniboxText',
- 'text': text,
- }
- windex: 0-based window index on which to work. Default: 0 (first window)
-
- Returns:
- a dictionary for the output returned by the automation channel.
-
- Raises:
- pyauto_errors.JSONInterfaceError if the automation call returns an error.
- """
- ret_dict = json.loads(self._SendJSONRequest(windex, json.dumps(cmd_dict)))
- if ret_dict.has_key('error'):
- raise JSONInterfaceError(ret_dict['error'])
- return ret_dict
-
def GetBookmarkModel(self):
"""Return the bookmark model as a BookmarkModel object.
@@ -375,7 +348,9 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
'command': 'OmniboxMovePopupSelection',
'count': count,
}
- self._GetResultFromJSONRequest(cmd_dict, windex=windex)
+ ret_dict = json.loads(self._SendJSONRequest(windex, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
def OmniboxAcceptInput(self, windex=0):
"""Accepts the current string of text in the omnibox.
@@ -390,7 +365,9 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
cmd_dict = {
'command': 'OmniboxAcceptInput',
}
- self._GetResultFromJSONRequest(cmd_dict, windex=windex)
+ ret_dict = json.loads(self._SendJSONRequest(windex, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
def GetPrefsInfo(self):
"""Return info about preferences.
@@ -432,13 +409,16 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
'path': path,
'value': value,
}
- self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
def WaitForAllDownloadsToComplete(self):
"""Wait for all downloads to complete."""
# Implementation detail: uses the generic "JSON command" model
# (experimental)
- self._GetResultFromJSONRequest({'command': 'WaitForAllDownloadsToComplete'})
+ self._SendJSONRequest(0, json.dumps({'command':
+ 'WaitForAllDownloadsToComplete'}))
def DownloadAndWaitForStart(self, file_url):
"""Trigger download for the given url and wait for downloads to start.
@@ -481,7 +461,10 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
cmd_dict['width'] = width
if height:
cmd_dict['height'] = height
- self._GetResultFromJSONRequest(cmd_dict, windex=windex)
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
+ return ret_dict
def GetBrowserInfo(self):
"""Return info about the browser.
@@ -541,7 +524,10 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
cmd_dict = { # Prepare command for the json interface
'command': 'GetBrowserInfo',
}
- return self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
+ return ret_dict
def GetHistoryInfo(self, search_text=''):
"""Return info about browsing history.
@@ -640,7 +626,10 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
for credit_card in credit_cards:
if not 'label' in credit_card:
raise JSONInterfaceError('must specify label for all credit cards')
- self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(window_index,
+ json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
def GetAutoFillProfile(self, tab_index=0, window_index=0):
"""Return the profile including all profiles and credit cards currently
@@ -662,7 +651,11 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
'command': 'GetAutoFillProfile',
'tab_index': tab_index
}
- return self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(window_index,
+ json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
+ return ret_dict
def AddHistoryItem(self, item):
"""Forge a history item for Chrome.
@@ -686,7 +679,9 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
}
if not 'url' in item:
raise JSONInterfaceError('must specify url')
- self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
def GetPluginsInfo(self):
"""Return info about plugins.
@@ -711,7 +706,9 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
'command': 'EnablePlugin',
'path': path,
}
- self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
def DisablePlugin(self, path):
"""Disable the plugin at the given path.
@@ -725,7 +722,9 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
'command': 'DisablePlugin',
'path': path,
}
- self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
def GetTabContents(self, tab_index=0, window_index=0):
"""Get the html contents of a tab (a la "view source").
@@ -746,7 +745,10 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
'tab_index': tab_index,
'filename': filename
}
- ret_dict = self._GetResultFromJSONRequest(cmd_dict, windex=window_index)
+ ret_dict = json.loads(self._SendJSONRequest(window_index,
+ json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
try:
f = open(filename)
all_data = f.read()
@@ -781,7 +783,10 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
cmd_dict = {
'command': 'ClearTheme',
}
- self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
+ return ret_dict
def GetThemeInfo(self):
"""Get info about theme.
@@ -809,7 +814,10 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
cmd_dict = {
'command': 'GetThemeInfo',
}
- return self._GetResultFromJSONRequest(cmd_dict)
+ ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict)))
+ if ret_dict.has_key('error'):
+ raise JSONInterfaceError(ret_dict['error'])
+ return ret_dict
class PyUITestSuite(pyautolib.PyUITestSuiteBase, unittest.TestSuite):