diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 469 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 10 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_json.cc | 55 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_json.h | 40 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.cc | 29 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/test/pyautolib/pyauto.py | 105 |
7 files changed, 318 insertions, 392 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index cbc6cd4..16d5090a 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -31,6 +31,7 @@ #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" @@ -1714,9 +1715,7 @@ void AutomationProvider::SetWindowDimensions(Browser* browser, if (args->GetInteger(L"height", &height)) rect.set_height(height); browser->window()->SetBounds(rect); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, std::string("{}"), true); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendSuccess(NULL); } // Sample json input: { "command": "GetBrowserInfo" } @@ -1725,9 +1724,6 @@ 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", @@ -1838,11 +1834,7 @@ void AutomationProvider::GetBrowserInfo(Browser* browser, } } return_value->Set(L"extension_processes", extension_processes); - - base::JSONWriter::Write(return_value.get(), false, &json_return); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendSuccess(return_value.get()); } // Sample json input: { "command": "GetHistoryInfo", @@ -1879,46 +1871,40 @@ 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); - item->GetString("title", &title); // Don't care if it fails. - int it; - double dt; - if (item->GetInteger(L"time", &it)) - time = base::Time::FromTimeT(it); - else if (item->GetReal(L"time", &dt)) - time = base::Time::FromDoubleT(dt); - - // Ideas for "dummy" values (e.g. id_scope) came from - // chrome/browser/autocomplete/history_contents_provider_unittest.cc - HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); - const void* id_scope = reinterpret_cast<void*>(1); - hs->AddPage(gurl, time, - id_scope, - 0, - GURL(), - PageTransition::LINK, - history::RedirectList(), - false); - if (title.length()) - hs->SetPageTitle(gurl, title); - } else { - json_return = JSONErrorString("bad args (no URL in dict?)"); - reply_return = false; + if (!item->GetString("url", &url_text)) { + reply.SendError("bad args (no URL in dict?)"); + return; } - - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + GURL gurl(url_text); + item->GetString("title", &title); // Don't care if it fails. + int it; + double dt; + if (item->GetInteger(L"time", &it)) + time = base::Time::FromTimeT(it); + else if (item->GetReal(L"time", &dt)) + time = base::Time::FromDoubleT(dt); + + // Ideas for "dummy" values (e.g. id_scope) came from + // chrome/browser/autocomplete/history_contents_provider_unittest.cc + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); + const void* id_scope = reinterpret_cast<void*>(1); + hs->AddPage(gurl, time, + id_scope, + 0, + GURL(), + PageTransition::LINK, + history::RedirectList(), + false); + if (title.length()) + hs->SetPageTitle(gurl, title); + reply.SendSuccess(NULL); } // Sample json input: { "command": "GetDownloadsInfo" } @@ -1926,22 +1912,20 @@ 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()) { - 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 - // the current download queue too soon to be noticed. - profile_->GetDownloadManager()->GetDownloads(&observer, L""); - downloads = observer.Downloads(); + reply.SendError("no download manager"); + return; } + // Use DownloadManager's GetDownloads() method and not GetCurrentDownloads() + // since that would be transient; a download might enter and empty out + // the current download queue too soon to be noticed. + profile_->GetDownloadManager()->GetDownloads(&observer, L""); + downloads = observer.Downloads(); std::map<DownloadItem::DownloadState, std::string> state_to_string; state_to_string[DownloadItem::IN_PROGRESS] = std::string("IN_PROGRESS"); @@ -1979,11 +1963,8 @@ 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); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + reply.SendSuccess(return_value.get()); // All value objects allocated above are owned by |return_value| // and get freed by it. } @@ -1992,27 +1973,19 @@ 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()) { - json_return = JSONErrorString("no download manager"); - reply_return = false; - } else { - profile_->GetDownloadManager()->GetCurrentDownloads(&observer, - FilePath()); - downloads = observer.Downloads(); - if (downloads.size() == 0) { - json_return = "{}"; - } + reply.SendSuccess(NULL); // No download manager. + return; } - if (!json_return.empty()) { - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + profile_->GetDownloadManager()->GetCurrentDownloads(&observer, FilePath()); + downloads = observer.Downloads(); + if (downloads.size() == 0) { + reply.SendSuccess(NULL); return; } @@ -2033,9 +2006,6 @@ 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; @@ -2045,42 +2015,35 @@ void AutomationProvider::GetPrefsInfo(Browser* browser, } scoped_ptr<DictionaryValue> return_value(new DictionaryValue); return_value->Set(L"prefs", items); // return_value owns items. - - base::JSONWriter::Write(return_value.get(), false, &json_return); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendSuccess(return_value.get()); } // 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. - json_return = JSONErrorString("pref not registered."); - reply_return = false; + reply.SendError("pref not registered."); + return; } else if (pref->IsManaged()) { // Do not attempt to change a managed pref. - json_return = JSONErrorString("pref is managed. cannot be changed."); - reply_return = false; + reply.SendError("pref is managed. cannot be changed."); + return; } else { // Set the pref. pref_service->Set(path.c_str(), *val); } } else { - json_return = JSONErrorString("no pref path or value given."); - reply_return = false; + reply.SendError("no pref path or value given."); + return; } - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + reply.SendSuccess(NULL); } // Sample json input: { "command": "GetOmniboxInfo" } @@ -2088,8 +2051,6 @@ 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(); @@ -2120,10 +2081,7 @@ void AutomationProvider::GetOmniboxInfo(Browser* browser, properties->SetString(L"text", edit_view->GetText()); return_value->Set(L"properties", properties); - base::JSONWriter::Write(return_value.get(), false, &json_return); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendSuccess(return_value.get()); } // Sample json input: { "command": "SetOmniboxText", @@ -2131,24 +2089,18 @@ 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)) { - json_return = JSONErrorString("text missing"); - reply_return = false; - } else { - browser->FocusLocationBar(); - LocationBar* loc_bar = browser->window()->GetLocationBar(); - AutocompleteEditView* edit_view = loc_bar->location_entry(); - edit_view->model()->OnSetFocus(false); - edit_view->SetUserText(text); + reply.SendError("text missing"); + return; } - - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + browser->FocusLocationBar(); + LocationBar* loc_bar = browser->window()->GetLocationBar(); + AutocompleteEditView* edit_view = loc_bar->location_entry(); + edit_view->model()->OnSetFocus(false); + edit_view->SetUserText(text); + reply.SendSuccess(NULL); } // Sample json input: { "command": "OmniboxMovePopupSelection", @@ -2159,22 +2111,16 @@ 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)) { - 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.SendError("count missing"); + return; } - - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + LocationBar* loc_bar = browser->window()->GetLocationBar(); + AutocompleteEditModel* model = loc_bar->location_entry()->model(); + model->OnUpOrDownKeyPressed(count); + reply.SendSuccess(NULL); } // Sample json input: { "command": "OmniboxAcceptInput" } @@ -2212,9 +2158,6 @@ 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; @@ -2254,10 +2197,7 @@ void AutomationProvider::GetPluginsInfo(Browser* browser, scoped_ptr<DictionaryValue> return_value(new DictionaryValue); return_value->Set(L"plugins", items); // return_value owns items. - base::JSONWriter::Write(return_value.get(), false, &json_return); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendSuccess(return_value.get()); } // Sample json input: @@ -2266,21 +2206,17 @@ 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)) { - json_return = JSONErrorString("path not specified."); - reply_return = false; + reply.SendError("path not specified."); + return; } 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; + reply.SendError(StringPrintf("Could not enable plugin for path %s.", + path.c_str())); + return; } - - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + reply.SendSuccess(NULL); } // Sample json input: @@ -2289,21 +2225,17 @@ 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)) { - json_return = JSONErrorString("path not specified."); - reply_return = false; + reply.SendError("path not specified."); + return; } 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; + reply.SendError(StringPrintf("Could not disable plugin for path %s.", + path.c_str())); + return; } - - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + reply.SendSuccess(NULL); } // Sample json input: @@ -2315,41 +2247,34 @@ 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)) { - json_return = JSONErrorString("tab_index or filename param missing"); + reply.SendError("tab_index or filename param missing"); + return; } 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); + reply.SendError("no tab at tab_index"); return; } } - - // If we get here, error. - DCHECK(!json_return.empty()); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, false); - Send(reply_message); + // 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; + } + // The observer will delete itself when done. + new SavePackageNotificationObserver(tab_contents->save_package(), + this, reply_message); } // Refer to ImportSettings() in chrome/test/pyautolib/pyauto.py for sample @@ -2358,8 +2283,6 @@ void AutomationProvider::SaveTabContents(Browser* browser, void AutomationProvider::ImportSettings(Browser* browser, DictionaryValue* args, IPC::Message* reply_message) { - std::string json_return = "{}"; - // Map from the json string passed over to the import item masks. std::map<std::string, ImportItem> string_to_import_item; string_to_import_item["HISTORY"] = importer::HISTORY; @@ -2378,11 +2301,8 @@ void AutomationProvider::ImportSettings(Browser* browser, if (!args->GetString(L"import_from", &browser_name) || !args->GetBoolean(L"first_run", &first_run) || !args->GetList(L"import_items", &import_items_list)) { - std::string json_return = - JSONErrorString("Incorrect type for one or more of the arguments."); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, false); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendError( + "Incorrect type for one or more of the arguments."); return; } @@ -2392,11 +2312,8 @@ void AutomationProvider::ImportSettings(Browser* browser, import_items_list->GetString(i, &item); // If the provided string is not part of the map, error out. if (!ContainsKey(string_to_import_item, item)) { - json_return = - JSONErrorString("Invalid item string found in import_items."); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, false); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendError( + "Invalid item string found in import_items."); return; } import_items |= string_to_import_item[item]; @@ -2416,11 +2333,8 @@ void AutomationProvider::ImportSettings(Browser* browser, } // If we made it to the end of the loop, then the input was bad. if (i == num_browsers) { - json_return = - JSONErrorString("Invalid browser name string found."); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, false); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendError( + "Invalid browser name string found."); return; } @@ -2438,8 +2352,6 @@ void AutomationProvider::ImportSettings(Browser* browser, void AutomationProvider::ClearBrowsingData(Browser* browser, DictionaryValue* args, IPC::Message* reply_message) { - std::string json_return = "{}"; - std::map<std::string, BrowsingDataRemover::TimePeriod> string_to_time_period; string_to_time_period["LAST_HOUR"] = BrowsingDataRemover::LAST_HOUR; string_to_time_period["LAST_DAY"] = BrowsingDataRemover::LAST_DAY; @@ -2459,12 +2371,8 @@ void AutomationProvider::ClearBrowsingData(Browser* browser, ListValue* to_remove; if (!args->GetString(L"time_period", &time_period) || !args->GetList(L"to_remove", &to_remove)) { - // TODO(nirnimesh): Here and below refactor returns with pending CL. - std::string json_return = - JSONErrorString("time_period must be a string and to_remove a list."); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, false); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendError( + "time_period must be a string and to_remove a list."); return; } @@ -2475,22 +2383,16 @@ void AutomationProvider::ClearBrowsingData(Browser* browser, to_remove->GetString(i, &removal); // If the provided string is not part of the map, then error out. if (!ContainsKey(string_to_mask_value, removal)) { - std::string json_return = - JSONErrorString("Invalid browsing data string found in to_remove."); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, false); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendError( + "Invalid browsing data string found in to_remove."); return; } remove_mask |= string_to_mask_value[removal]; } if (!ContainsKey(string_to_time_period, time_period)) { - std::string json_return = - JSONErrorString("Invalid string for time_period."); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, false); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendError( + "Invalid string for time_period."); return; } @@ -2517,12 +2419,7 @@ void AutomationProvider::GetThemeInfo(Browser* browser, return_value->Set(L"colors", theme->GetThemeColors()->DeepCopy()); return_value->Set(L"tints", theme->GetThemeTints()->DeepCopy()); } - - std::string json_return; - base::JSONWriter::Write(return_value.get(), false, &json_return); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, true); - Send(reply_message); + AutomationJSONReply(this, reply_message).SendSuccess(return_value.get()); } // Sample json input: @@ -2532,13 +2429,11 @@ 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() @@ -2554,20 +2449,15 @@ void AutomationProvider::GetAutoFillProfile(Browser* browser, return_value->Set(L"profiles", profiles); return_value->Set(L"credit_cards", cards); - - base::JSONWriter::Write(return_value.get(), false, &json_return); + reply.SendSuccess(return_value.get()); } else { - json_return = JSONErrorString("No PersonalDataManager."); - reply_return = false; + reply.SendError("No PersonalDataManager."); + return; } } else { - json_return = JSONErrorString("No tab at that index."); - reply_return = false; + reply.SendError("No tab at that index."); + return; } - - AutomationMsg_SendJSONRequest::WriteReplyParams(reply_message, json_return, - reply_return); - Send(reply_message); } // Refer to FillAutoFillProfile() in chrome/test/pyautolib/pyauto.py for sample @@ -2576,23 +2466,26 @@ void AutomationProvider::GetAutoFillProfile(Browser* browser, void AutomationProvider::FillAutoFillProfile(Browser* browser, DictionaryValue* args, IPC::Message* reply_message) { - std::string json_return = "{}"; - bool reply_return = true; - + AutomationJSONReply reply(this, reply_message); 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, &json_return); + autofill_profiles = GetAutoFillProfilesFromList(*profiles, &error_mesg); } // Create a CreditCard for each of the dictionary values. if (cards) { - credit_cards = GetCreditCardsFromList(*cards, &json_return); + credit_cards = GetCreditCardsFromList(*cards, &error_mesg); + } + if (!error_mesg.empty()) { + reply.SendError(error_mesg); + return; } // Save the AutoFillProfiles. @@ -2607,16 +2500,14 @@ void AutomationProvider::FillAutoFillProfile(Browser* browser, pdm->OnAutoFillDialogApply(profiles? &autofill_profiles : NULL, cards? &credit_cards : NULL); } else { - json_return = JSONErrorString("No PersonalDataManager."); - reply_return = false; + reply.SendError("No PersonalDataManager."); + return; } } else { - json_return = JSONErrorString("No tab at that index."); - reply_return = false; + reply.SendError("No tab at that index."); + return; } - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message, json_return, reply_return); - Send(reply_message); + reply.SendSuccess(NULL); } /* static */ @@ -2678,7 +2569,7 @@ ListValue* AutomationProvider::GetListFromCreditCards( /* static */ std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList( - const ListValue& profiles, std::string* json_return) { + const ListValue& profiles, std::string* error_message) { std::vector<AutoFillProfile> autofill_profiles; DictionaryValue* profile_info = NULL; string16 profile_label; @@ -2701,7 +2592,7 @@ std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList( if (profile_info->GetStringAsUTF16(type_it->second, ¤t_value)) { profile.SetInfo(AutoFillType(type_it->first), current_value); } else { - *json_return = JSONErrorString("All values must be strings"); + *error_message= "All values must be strings"; break; } } @@ -2713,7 +2604,7 @@ std::vector<AutoFillProfile> AutomationProvider::GetAutoFillProfilesFromList( /* static */ std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList( - const ListValue& cards, std::string* json_return) { + const ListValue& cards, std::string* error_message) { std::vector<CreditCard> credit_cards; DictionaryValue* card_info = NULL; string16 card_label; @@ -2735,7 +2626,7 @@ std::vector<CreditCard> AutomationProvider::GetCreditCardsFromList( if (card_info->GetStringAsUTF16(type_it->second, ¤t_value)) { card.SetInfo(AutoFillType(type_it->first), current_value); } else { - *json_return = JSONErrorString("All values must be strings"); + *error_message= "All values must be strings"; break; } } @@ -2779,51 +2670,41 @@ 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) { - error_string = "no browser object"; - } else { - base::JSONReader reader; - std::string error; - values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error)); - if (!error.empty()) { - error_string = error; - } + reply.SendError("no browser object"); + return; + } + base::JSONReader reader; + std::string error; + values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error)); + if (!error.empty()) { + reply.SendError(error); + return; } // 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 (values->GetType() != Value::TYPE_DICTIONARY) { + reply.SendError("not a dict"); + return; + } + // 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; } // Map json commands to their handlers. @@ -2833,6 +2714,7 @@ 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; @@ -2865,35 +2747,16 @@ void AutomationProvider::SendJSONRequest(int handle, handler_map["GetAutoFillProfile"] = &AutomationProvider::GetAutoFillProfile; handler_map["FillAutoFillProfile"] = &AutomationProvider::FillAutoFillProfile; - 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 + ", "; - } - } - } - - // 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; + if (handler_map.find(std::string(command)) != handler_map.end()) { + (this->*handler_map[command])(browser, dict_value, reply_message); } else { - json_string = "{}"; + 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 + ", "; + } + reply.SendError(error_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 a0d2dd7..524fd62 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -476,11 +476,11 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, // data structure used in the browser. // Args: // profiles/cards: the ListValue of profiles/credit cards to translate. - // json_return: a pointer to the return string in case of error. + // error_message: a pointer to the return string in case of error. static std::vector<AutoFillProfile> GetAutoFillProfilesFromList( - const ListValue& profiles, std::string* json_return); + const ListValue& profiles, std::string* error_message); static std::vector<CreditCard> GetCreditCardsFromList( - const ListValue& cards, std::string* json_return); + const ListValue& cards, std::string* error_message); // The opposite of the above: translates from the internal data structure // for profiles and credit cards to a ListValue of DictionaryValues. The @@ -497,10 +497,6 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, static std::map<AutoFillFieldType, std::wstring> GetCreditCardFieldToStringMap(); - // 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); - // Generic pattern for pyautolib // Uses the JSON interface for input/output. void SendJSONRequest(int handle, diff --git a/chrome/browser/automation/automation_provider_json.cc b/chrome/browser/automation/automation_provider_json.cc new file mode 100644 index 0000000..05f3a1b --- /dev/null +++ b/chrome/browser/automation/automation_provider_json.cc @@ -0,0 +1,55 @@ +// 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" + +namespace { + +// Util for creating a JSON error return string (dict with key +// 'error' and error string value). No need to quote input. +std::string 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; +} + +} // namespace + +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_message) { + DCHECK(message_) << "Resending reply for JSON automation request"; + std::string json_string = JSONErrorString(error_message); + AutomationMsg_SendJSONRequest::WriteReplyParams( + message_, json_string, false); + provider_->Send(message_); + message_ = NULL; +} + diff --git a/chrome/browser/automation/automation_provider_json.h b/chrome/browser/automation/automation_provider_json.h new file mode 100644 index 0000000..a203c58 --- /dev/null +++ b/chrome/browser/automation/automation_provider_json.h @@ -0,0 +1,40 @@ +// 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. + +#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" + +// Helper to ensure we always send a reply message for JSON automation requests. +class AutomationJSONReply { + public: + // Creates a new reply object for the IPC message |reply_message| for + // |provider|. The caller is expected to call SendSuccess() or SendError() + // before destroying this object. + 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_message|. + void SendError(const std::string& error_message); + + private: + 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 0076047..0745a90 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -9,6 +9,7 @@ #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" @@ -974,9 +975,7 @@ void AutomationProviderDownloadItemObserver::OnDownloadFileCompleted( DownloadItem* download) { download->RemoveObserver(this); if (--downloads_ == 0) { - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message_, std::string("{}"), true); - provider_->Send(reply_message_); + AutomationJSONReply(provider_, reply_message_).SendSuccess(NULL); delete this; } } @@ -984,8 +983,6 @@ 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; @@ -1005,26 +1002,20 @@ void AutomationProviderHistoryObserver::HistoryQueryComplete( return_value->Set(L"history", history_list); // Return history info. - base::JSONWriter::Write(return_value.get(), false, &json_return); - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message_, json_return, reply_return); - provider_->Send(reply_message_); + AutomationJSONReply reply(provider_, reply_message_); + reply.SendSuccess(return_value.get()); delete this; } void AutomationProviderImportSettingsObserver::ImportEnded() { // Send back an empty success message. - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message_, std::string("{}"), true); - provider_->Send(reply_message_); + AutomationJSONReply(provider_, reply_message_).SendSuccess(NULL); delete this; } void AutomationProviderBrowsingDataObserver::OnBrowsingDataRemoverDone() { // Send back an empty success message - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message_, std::string("{}"), true); - provider_->Send(reply_message_); + AutomationJSONReply(provider_, reply_message_).SendSuccess(NULL); delete this; } @@ -1051,9 +1042,7 @@ void OmniboxAcceptNotificationObserver::Observe( const NotificationDetails& details) { if (type == NotificationType::LOAD_STOP || type == NotificationType::AUTH_NEEDED) { - AutomationMsg_SendJSONRequest::WriteReplyParams( - reply_message_, std::string("{}"), false); - automation_->Send(reply_message_); + AutomationJSONReply(automation_, reply_message_).SendSuccess(NULL); delete this; } else { NOTREACHED(); @@ -1075,9 +1064,7 @@ void SavePackageNotificationObserver::Observe( 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_); + AutomationJSONReply(automation_, reply_message_).SendSuccess(NULL); delete this; } else { NOTREACHED(); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 00fb53b..d9175e6 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -198,6 +198,8 @@ '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 72304d5..10a4504 100644 --- a/chrome/test/pyautolib/pyauto.py +++ b/chrome/test/pyautolib/pyauto.py @@ -28,7 +28,6 @@ to unittest.py import logging import optparse import os -import re import shutil import sys import tempfile @@ -260,6 +259,33 @@ 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. @@ -318,9 +344,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'command': 'SetOmniboxText', 'text': text, } - ret_dict = json.loads(self._SendJSONRequest(windex, json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict, windex=windex) def WaitUntilOmniboxQueryDone(self, windex=0): """Wait until omnibox has finished populating results. @@ -348,9 +372,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'command': 'OmniboxMovePopupSelection', 'count': count, } - ret_dict = json.loads(self._SendJSONRequest(windex, json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict, windex=windex) def OmniboxAcceptInput(self, windex=0): """Accepts the current string of text in the omnibox. @@ -365,9 +387,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): cmd_dict = { 'command': 'OmniboxAcceptInput', } - ret_dict = json.loads(self._SendJSONRequest(windex, json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict, windex=windex) def GetPrefsInfo(self): """Return info about preferences. @@ -409,16 +429,13 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'path': path, 'value': value, } - ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict) def WaitForAllDownloadsToComplete(self): """Wait for all downloads to complete.""" # Implementation detail: uses the generic "JSON command" model # (experimental) - self._SendJSONRequest(0, json.dumps({'command': - 'WaitForAllDownloadsToComplete'})) + self._GetResultFromJSONRequest({'command': 'WaitForAllDownloadsToComplete'}) def DownloadAndWaitForStart(self, file_url): """Trigger download for the given url and wait for downloads to start. @@ -461,10 +478,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): cmd_dict['width'] = width if height: cmd_dict['height'] = height - 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 + self._GetResultFromJSONRequest(cmd_dict, windex=windex) def GetBrowserInfo(self): """Return info about the browser. @@ -524,10 +538,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): cmd_dict = { # Prepare command for the json interface 'command': 'GetBrowserInfo', } - 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 + return self._GetResultFromJSONRequest(cmd_dict) def GetHistoryInfo(self, search_text=''): """Return info about browsing history. @@ -626,10 +637,7 @@ 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') - ret_dict = json.loads(self._SendJSONRequest(window_index, - json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict, windex=window_index) def GetAutoFillProfile(self, tab_index=0, window_index=0): """Return the profile including all profiles and credit cards currently @@ -651,11 +659,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'command': 'GetAutoFillProfile', 'tab_index': tab_index } - 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 + return self._GetResultFromJSONRequest(cmd_dict, windex=window_index) def AddHistoryItem(self, item): """Forge a history item for Chrome. @@ -679,9 +683,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): } if not 'url' in item: raise JSONInterfaceError('must specify url') - ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict) def GetPluginsInfo(self): """Return info about plugins. @@ -706,9 +708,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'command': 'EnablePlugin', 'path': path, } - ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict) def DisablePlugin(self, path): """Disable the plugin at the given path. @@ -722,9 +722,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'command': 'DisablePlugin', 'path': path, } - ret_dict = json.loads(self._SendJSONRequest(0, json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict) def GetTabContents(self, tab_index=0, window_index=0): """Get the html contents of a tab (a la "view source"). @@ -745,10 +743,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'tab_index': tab_index, 'filename': filename } - ret_dict = json.loads(self._SendJSONRequest(window_index, - json.dumps(cmd_dict))) - if ret_dict.has_key('error'): - raise JSONInterfaceError(ret_dict['error']) + self._GetResultFromJSONRequest(cmd_dict, windex=window_index) try: f = open(filename) all_data = f.read() @@ -787,10 +782,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'first_run': first_run, 'import_items': import_items } - 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 + return self._GetResultFromJSONRequest(cmd_dict) def ClearBrowsingData(self, to_remove, time_period): """Clear the specified browsing data. Implements the features available in @@ -812,10 +804,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): 'to_remove': to_remove, 'time_period': time_period } - 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 + return self._GetResultFromJSONRequest(cmd_dict) def SetTheme(self, crx_file_path): """Installs the given theme synchronously. @@ -843,10 +832,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): cmd_dict = { 'command': 'ClearTheme', } - 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 + self._GetResultFromJSONRequest(cmd_dict) def GetThemeInfo(self): """Get info about theme. @@ -874,10 +860,7 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): cmd_dict = { 'command': 'GetThemeInfo', } - 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 + return self._GetResultFromJSONRequest(cmd_dict) class PyUITestSuite(pyautolib.PyUITestSuiteBase, unittest.TestSuite): |