1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/automation/automation_provider_json.h" 6 7#include "base/json/json_writer.h" 8#include "base/json/string_escape.h" 9#include "base/values.h" 10#include "chrome/browser/autocomplete/autocomplete_match.h" 11#include "chrome/browser/automation/automation_provider.h" 12#include "chrome/browser/automation/automation_util.h" 13#include "chrome/browser/extensions/extension_service.h" 14#include "chrome/browser/extensions/extension_system.h" 15#include "chrome/browser/profiles/profile.h" 16#include "chrome/common/automation_messages.h" 17#include "content/public/browser/web_contents.h" 18#include "extensions/common/extension.h" 19 20using content::WebContents; 21 22AutomationJSONReply::AutomationJSONReply(AutomationProvider* provider, 23 IPC::Message* reply_message) 24 : provider_(provider), 25 message_(reply_message) { 26} 27 28AutomationJSONReply::~AutomationJSONReply() { 29 DCHECK(!message_) << "JSON automation request not replied!"; 30} 31 32void AutomationJSONReply::SendSuccess(const Value* value) { 33 DCHECK(message_) << "Resending reply for JSON automation request"; 34 std::string json_string = "{}"; 35 if (value) 36 base::JSONWriter::Write(value, &json_string); 37 AutomationMsg_SendJSONRequest::WriteReplyParams( 38 message_, json_string, true); 39 provider_->Send(message_); 40 message_ = NULL; 41} 42 43void AutomationJSONReply::SendError(const std::string& error_message) { 44 DCHECK(message_) << "Resending reply for JSON automation request"; 45 46 base::DictionaryValue dict; 47 dict.SetString("error", error_message); 48 std::string json; 49 base::JSONWriter::Write(&dict, &json); 50 51 AutomationMsg_SendJSONRequest::WriteReplyParams(message_, json, false); 52 provider_->Send(message_); 53 message_ = NULL; 54} 55 56bool GetBrowserFromJSONArgs( 57 DictionaryValue* args, 58 Browser** browser, 59 std::string* error) { 60 int browser_index; 61 if (!args->GetInteger("windex", &browser_index)) { 62 *error = "'windex' missing or invalid"; 63 return false; 64 } 65 *browser = automation_util::GetBrowserAt(browser_index); 66 if (!*browser) { 67 *error = "Cannot locate browser from given index"; 68 return false; 69 } 70 return true; 71} 72 73bool GetTabFromJSONArgs( 74 DictionaryValue* args, 75 WebContents** tab, 76 std::string* error) { 77 int browser_index, tab_index; 78 if (!args->GetInteger("windex", &browser_index)) { 79 *error = "'windex' missing or invalid"; 80 return false; 81 } 82 if (!args->GetInteger("tab_index", &tab_index)) { 83 *error = "'tab_index' missing or invalid"; 84 return false; 85 } 86 *tab = automation_util::GetWebContentsAt(browser_index, tab_index); 87 if (!*tab) { 88 *error = "Cannot locate tab from given indices"; 89 return false; 90 } 91 return true; 92} 93 94bool GetBrowserAndTabFromJSONArgs( 95 DictionaryValue* args, 96 Browser** browser, 97 WebContents** tab, 98 std::string* error) { 99 return GetBrowserFromJSONArgs(args, browser, error) && 100 GetTabFromJSONArgs(args, tab, error); 101} 102 103bool GetRenderViewFromJSONArgs( 104 DictionaryValue* args, 105 Profile* profile, 106 content::RenderViewHost** rvh, 107 std::string* error) { 108 WebContents* tab = NULL; 109 if (!GetTabFromJSONArgs(args, &tab, error)) 110 return false; 111 *rvh = tab->GetRenderViewHost(); 112 return true; 113} 114 115namespace { 116 117bool GetExtensionFromJSONArgsHelper( 118 base::DictionaryValue* args, 119 const std::string& key, 120 Profile* profile, 121 bool include_disabled, 122 const extensions::Extension** extension, 123 std::string* error) { 124 std::string id; 125 if (!args->GetString(key, &id)) { 126 *error = base::StringPrintf("Missing or invalid key: %s", key.c_str()); 127 return false; 128 } 129 ExtensionService* service = extensions::ExtensionSystem::Get(profile)-> 130 extension_service(); 131 if (!service) { 132 *error = "No extensions service."; 133 return false; 134 } 135 if (!service->GetInstalledExtension(id)) { 136 // The extension ID does not correspond to any extension, whether crashed 137 // or not. 138 *error = base::StringPrintf("Extension %s is not installed.", 139 id.c_str()); 140 return false; 141 } 142 const extensions::Extension* installed_extension = 143 service->GetExtensionById(id, include_disabled); 144 if (!installed_extension) { 145 *error = "Extension is disabled or has crashed."; 146 return false; 147 } 148 *extension = installed_extension; 149 return true; 150} 151 152} // namespace 153 154bool GetExtensionFromJSONArgs( 155 base::DictionaryValue* args, 156 const std::string& key, 157 Profile* profile, 158 const extensions::Extension** extension, 159 std::string* error) { 160 return GetExtensionFromJSONArgsHelper( 161 args, key, profile, true /* include_disabled */, extension, error); 162} 163 164bool GetEnabledExtensionFromJSONArgs( 165 base::DictionaryValue* args, 166 const std::string& key, 167 Profile* profile, 168 const extensions::Extension** extension, 169 std::string* error) { 170 return GetExtensionFromJSONArgsHelper( 171 args, key, profile, false /* include_disabled */, extension, error); 172} 173