Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(792)

Side by Side Diff: chrome/browser/automation/automation_extension_function.cc

Issue 6756044: Remove extension automation support that was used only by CEEE. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge to head. Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2009 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 // Implements AutomationExtensionFunction.
6
7 #include "chrome/browser/automation/automation_extension_function.h"
8
9 #include "base/json/json_reader.h"
10 #include "base/json/json_writer.h"
11 #include "base/values.h"
12 #include "chrome/browser/automation/extension_automation_constants.h"
13 #include "chrome/browser/extensions/extension_function_dispatcher.h"
14 #include "chrome/browser/extensions/extension_tabs_module.h"
15 #include "content/browser/renderer_host/render_view_host.h"
16 #include "content/browser/renderer_host/render_view_host_delegate.h"
17 #include "content/browser/tab_contents/tab_contents.h"
18 #include "content/browser/tab_contents/tab_contents_delegate.h"
19
20 TabContents* AutomationExtensionFunction::api_handler_tab_ = NULL;
21 AutomationExtensionFunction::PendingFunctionsMap
22 AutomationExtensionFunction::pending_functions_;
23
24 AutomationExtensionFunction::AutomationExtensionFunction() {
25 }
26
27 void AutomationExtensionFunction::SetArgs(const ListValue* args) {
28 // Need to JSON-encode for sending over the wire to the automation user.
29 base::JSONWriter::Write(args, false, &args_);
30 }
31
32 const std::string AutomationExtensionFunction::GetResult() {
33 // Already JSON-encoded, so override the base class's implementation.
34 return json_result_;
35 }
36
37 bool AutomationExtensionFunction::RunImpl() {
38 namespace keys = extension_automation_constants;
39
40 DCHECK(api_handler_tab_) <<
41 "Why is this function still enabled if no target tab?";
42 if (!api_handler_tab_) {
43 error_ = "No longer automating functions.";
44 return false;
45 }
46
47 // We are being driven through automation, so we send the extension API
48 // request over to the automation host. We do this before decoding the
49 // 'args' JSON, otherwise we'd be decoding it only to encode it again.
50 DictionaryValue message_to_host;
51 message_to_host.SetString(keys::kAutomationNameKey, name_);
52 message_to_host.SetString(keys::kAutomationArgsKey, args_);
53 message_to_host.SetInteger(keys::kAutomationRequestIdKey, request_id_);
54 message_to_host.SetBoolean(keys::kAutomationHasCallbackKey, has_callback_);
55 // Send the API request's associated tab along to the automation client, so
56 // that it can determine the execution context of the API call.
57 TabContents* contents = NULL;
58 ExtensionFunctionDispatcher* function_dispatcher = dispatcher();
59 if (function_dispatcher && function_dispatcher->delegate()) {
60 contents = function_dispatcher->delegate()->associated_tab_contents();
61 } else {
62 NOTREACHED() << "Extension function dispatcher delegate not found.";
63 }
64 if (contents)
65 message_to_host.Set(keys::kAutomationTabJsonKey,
66 ExtensionTabUtil::CreateTabValue(contents));
67
68 std::string message;
69 base::JSONWriter::Write(&message_to_host, false, &message);
70 if (api_handler_tab_->delegate()) {
71 api_handler_tab_->delegate()->ForwardMessageToExternalHost(
72 message, keys::kAutomationOrigin, keys::kAutomationRequestTarget);
73 } else {
74 NOTREACHED() << "ExternalTabContainer is supposed to correctly manage "
75 "lifetime of api_handler_tab_.";
76 }
77
78 // Automation APIs are asynchronous so we need to stick around until
79 // our response comes back. Add ourselves to a static hash map keyed
80 // by request ID. The hash map keeps a reference count on us.
81 DCHECK(pending_functions_.find(request_id_) == pending_functions_.end());
82 pending_functions_[request_id_] = this;
83
84 return true;
85 }
86
87 ExtensionFunction* AutomationExtensionFunction::Factory() {
88 return new AutomationExtensionFunction();
89 }
90
91 void AutomationExtensionFunction::Enable(
92 TabContents* api_handler_tab,
93 const std::vector<std::string>& functions_enabled) {
94 DCHECK(api_handler_tab);
95 if (api_handler_tab_ && api_handler_tab != api_handler_tab_) {
96 NOTREACHED() << "Don't call with different API handler.";
97 return;
98 }
99 api_handler_tab_ = api_handler_tab;
100
101 std::vector<std::string> function_names;
102 if (functions_enabled.size() == 1 && functions_enabled[0] == "*") {
103 ExtensionFunctionDispatcher::GetAllFunctionNames(&function_names);
104 } else {
105 function_names = functions_enabled;
106 }
107
108 for (std::vector<std::string>::iterator it = function_names.begin();
109 it != function_names.end(); it++) {
110 // TODO(joi) Could make this a per-profile change rather than a global
111 // change. Could e.g. have the AutomationExtensionFunction store the
112 // profile pointer and dispatch to the original ExtensionFunction when the
113 // current profile is not that.
114 bool result = ExtensionFunctionDispatcher::OverrideFunction(
115 *it, AutomationExtensionFunction::Factory);
116 LOG_IF(WARNING, !result) << "Failed to override API function: " << *it;
117 }
118 }
119
120 void AutomationExtensionFunction::Disable() {
121 api_handler_tab_ = NULL;
122 ExtensionFunctionDispatcher::ResetFunctions();
123 }
124
125 bool AutomationExtensionFunction::InterceptMessageFromExternalHost(
126 RenderViewHost* view_host,
127 const std::string& message,
128 const std::string& origin,
129 const std::string& target) {
130 namespace keys = extension_automation_constants;
131
132 // We want only specially-tagged messages passed via the conduit tab.
133 if (api_handler_tab_ &&
134 view_host == api_handler_tab_->render_view_host() &&
135 origin == keys::kAutomationOrigin &&
136 target == keys::kAutomationResponseTarget) {
137 // This is an extension API response being sent back via postMessage,
138 // so redirect it.
139 scoped_ptr<Value> message_value(base::JSONReader::Read(message, false));
140 DCHECK(message_value->IsType(Value::TYPE_DICTIONARY));
141 if (message_value->IsType(Value::TYPE_DICTIONARY)) {
142 DictionaryValue* message_dict =
143 reinterpret_cast<DictionaryValue*>(message_value.get());
144
145 int request_id = -1;
146 bool got_value = message_dict->GetInteger(keys::kAutomationRequestIdKey,
147 &request_id);
148 DCHECK(got_value);
149 if (got_value) {
150 std::string error;
151 bool success = !message_dict->GetString(keys::kAutomationErrorKey,
152 &error);
153
154 std::string response;
155 got_value = message_dict->GetString(keys::kAutomationResponseKey,
156 &response);
157 DCHECK(!success || got_value);
158
159 PendingFunctionsMap::iterator it = pending_functions_.find(request_id);
160 DCHECK(it != pending_functions_.end());
161
162 if (it != pending_functions_.end()) {
163 scoped_refptr<AutomationExtensionFunction> func = it->second;
164 pending_functions_.erase(it);
165
166 // Our local ref should be the last remaining.
167 DCHECK(func && func->HasOneRef());
168
169 if (func) {
170 func->json_result_ = response;
171 func->error_ = error;
172
173 func->SendResponse(success);
174 }
175 }
176 return true;
177 }
178 }
179 }
180
181 return false;
182 }
183
184 AutomationExtensionFunction::~AutomationExtensionFunction() {
185 }
OLDNEW
« no previous file with comments | « chrome/browser/automation/automation_extension_function.h ('k') | chrome/browser/automation/automation_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698