diff options
Diffstat (limited to 'chrome/browser/automation')
5 files changed, 247 insertions, 223 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, ¤t_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, ¤t_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(); |