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

Side by Side Diff: chrome/browser/extensions/extension_function_dispatcher.cc

Issue 11886084: Revert 177235 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 11 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
« no previous file with comments | « chrome/browser/extensions/blocked_actions.cc ('k') | chrome/browser/extensions/tab_helper.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:mergeinfo
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_function_dispatcher.h" 5 #include "chrome/browser/extensions/extension_function_dispatcher.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h"
10 #include "base/json/json_string_value_serializer.h" 9 #include "base/json/json_string_value_serializer.h"
11 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
12 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
13 #include "base/process_util.h" 12 #include "base/process_util.h"
14 #include "base/values.h" 13 #include "base/values.h"
15 #include "build/build_config.h" 14 #include "build/build_config.h"
16 #include "chrome/browser/extensions/activity_log.h" 15 #include "chrome/browser/extensions/activity_log.h"
17 #include "chrome/browser/extensions/extension_function.h" 16 #include "chrome/browser/extensions/extension_function.h"
18 #include "chrome/browser/extensions/extension_function_registry.h" 17 #include "chrome/browser/extensions/extension_function_registry.h"
19 #include "chrome/browser/extensions/extension_service.h" 18 #include "chrome/browser/extensions/extension_service.h"
20 #include "chrome/browser/extensions/extension_system.h" 19 #include "chrome/browser/extensions/extension_system.h"
21 #include "chrome/browser/extensions/extension_web_ui.h" 20 #include "chrome/browser/extensions/extension_web_ui.h"
22 #include "chrome/browser/extensions/extensions_quota_service.h" 21 #include "chrome/browser/extensions/extensions_quota_service.h"
23 #include "chrome/browser/extensions/process_map.h" 22 #include "chrome/browser/extensions/process_map.h"
24 #include "chrome/browser/external_protocol/external_protocol_handler.h" 23 #include "chrome/browser/external_protocol/external_protocol_handler.h"
25 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" 25 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
27 #include "chrome/common/extensions/api/extension_api.h" 26 #include "chrome/common/extensions/api/extension_api.h"
28 #include "chrome/common/extensions/extension_messages.h" 27 #include "chrome/common/extensions/extension_messages.h"
29 #include "chrome/common/extensions/extension_set.h" 28 #include "chrome/common/extensions/extension_set.h"
30 #include "chrome/common/url_constants.h" 29 #include "chrome/common/url_constants.h"
31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/render_process_host.h" 30 #include "content/public/browser/render_process_host.h"
33 #include "content/public/browser/render_view_host.h" 31 #include "content/public/browser/render_view_host.h"
34 #include "ipc/ipc_message.h" 32 #include "ipc/ipc_message.h"
35 #include "ipc/ipc_message_macros.h" 33 #include "ipc/ipc_message_macros.h"
36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
37 #include "webkit/glue/resource_type.h" 35 #include "webkit/glue/resource_type.h"
38 36
39 using extensions::Extension; 37 using extensions::Extension;
40 using extensions::ExtensionAPI; 38 using extensions::ExtensionAPI;
41 using content::RenderViewHost; 39 using content::RenderViewHost;
42 using WebKit::WebSecurityOrigin; 40 using WebKit::WebSecurityOrigin;
43 41
44 namespace { 42 namespace {
45 43
46 const char kAccessDenied[] = "access denied"; 44 const char kAccessDenied[] = "access denied";
47 const char kQuotaExceeded[] = "quota exceeded"; 45 const char kQuotaExceeded[] = "quota exceeded";
48 46
49 void LogSuccess(const Extension* extension, 47 void LogSuccess(const Extension* extension,
50 const std::string& api_name, 48 const ExtensionHostMsg_Request_Params& params) {
51 scoped_ptr<ListValue> args, 49 extensions::ActivityLog* activity_log =
52 Profile* profile) { 50 extensions::ActivityLog::GetInstance();
53 // The ActivityLog can only be accessed from the main (UI) thread. If we're 51 if (activity_log->HasObservers(extension)) {
54 // running on the wrong thread, re-dispatch from the main thread. 52 std::string call_signature = params.name + "(";
55 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 53 ListValue::const_iterator it = params.arguments.begin();
56 BrowserThread::PostTask(BrowserThread::UI, 54 for (; it != params.arguments.end(); ++it) {
57 FROM_HERE, 55 std::string arg;
58 base::Bind(&LogSuccess, 56 JSONStringValueSerializer serializer(&arg);
59 extension, 57 if (serializer.SerializeAndOmitBinaryValues(**it)) {
60 api_name, 58 if (it != params.arguments.begin())
61 Passed(args.Pass()), 59 call_signature += ", ";
62 profile)); 60 call_signature += arg;
63 } else { 61 }
64 extensions::ActivityLog* activity_log = 62 }
65 extensions::ActivityLog::GetInstance(profile); 63 call_signature += ")";
66 if (activity_log->HasObservers(extension)) 64
67 activity_log->LogAPIAction(extension, api_name, args.get(), ""); 65 activity_log->Log(extension,
66 extensions::ActivityLog::ACTIVITY_EXTENSION_API_CALL,
67 call_signature);
68 } 68 }
69 } 69 }
70 70
71 void LogFailure(const Extension* extension, 71 void LogFailure(const Extension* extension,
72 const std::string& api_name, 72 const std::string& func_name,
73 scoped_ptr<ListValue> args, 73 const char* reason) {
74 const char* reason, 74 extensions::ActivityLog* activity_log =
75 Profile* profile) { 75 extensions::ActivityLog::GetInstance();
76 // The ActivityLog can only be accessed from the main (UI) thread. If we're 76 if (activity_log->HasObservers(extension)) {
77 // running on the wrong thread, re-dispatch from the main thread. 77 activity_log->Log(extension,
78 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 78 extensions::ActivityLog::ACTIVITY_EXTENSION_API_BLOCK,
79 BrowserThread::PostTask(BrowserThread::UI, 79 func_name + ": " + reason);
80 FROM_HERE,
81 base::Bind(&LogFailure,
82 extension,
83 api_name,
84 Passed(args.Pass()),
85 reason,
86 profile));
87 } else {
88 extensions::ActivityLog* activity_log =
89 extensions::ActivityLog::GetInstance(profile);
90 if (activity_log->HasObservers(extension))
91 activity_log->LogBlockedAction(extension,
92 api_name,
93 args.get(),
94 reason,
95 "");
96 } 80 }
97 } 81 }
98 82
99
100 // Separate copy of ExtensionAPI used for IO thread extension functions. We need 83 // Separate copy of ExtensionAPI used for IO thread extension functions. We need
101 // this because ExtensionAPI has mutable data. It should be possible to remove 84 // this because ExtensionAPI has mutable data. It should be possible to remove
102 // this once all the extension APIs are updated to the feature system. 85 // this once all the extension APIs are updated to the feature system.
103 struct Static { 86 struct Static {
104 Static() 87 Static()
105 : api(extensions::ExtensionAPI::CreateWithDefaultConfiguration()) { 88 : api(extensions::ExtensionAPI::CreateWithDefaultConfiguration()) {
106 } 89 }
107 scoped_ptr<extensions::ExtensionAPI> api; 90 scoped_ptr<extensions::ExtensionAPI> api;
108 }; 91 };
109 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; 92 base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER;
(...skipping 29 matching lines...) Expand all
139 // static 122 // static
140 void ExtensionFunctionDispatcher::DispatchOnIOThread( 123 void ExtensionFunctionDispatcher::DispatchOnIOThread(
141 ExtensionInfoMap* extension_info_map, 124 ExtensionInfoMap* extension_info_map,
142 void* profile, 125 void* profile,
143 int render_process_id, 126 int render_process_id,
144 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender, 127 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender,
145 int routing_id, 128 int routing_id,
146 const ExtensionHostMsg_Request_Params& params) { 129 const ExtensionHostMsg_Request_Params& params) {
147 const Extension* extension = 130 const Extension* extension =
148 extension_info_map->extensions().GetByID(params.extension_id); 131 extension_info_map->extensions().GetByID(params.extension_id);
149 Profile* profile_cast = static_cast<Profile*>(profile); 132
150 scoped_refptr<ExtensionFunction> function( 133 scoped_refptr<ExtensionFunction> function(
151 CreateExtensionFunction(params, extension, render_process_id, 134 CreateExtensionFunction(params, extension, render_process_id,
152 extension_info_map->process_map(), 135 extension_info_map->process_map(),
153 g_global_io_data.Get().api.get(), 136 g_global_io_data.Get().api.get(),
154 profile, 137 profile,
155 ipc_sender, NULL, routing_id)); 138 ipc_sender, NULL, routing_id));
156 scoped_ptr<ListValue> args(params.arguments.DeepCopy());
157
158 if (!function) { 139 if (!function) {
159 LogFailure(extension, 140 LogFailure(extension, params.name, kAccessDenied);
160 params.name,
161 args.Pass(),
162 kAccessDenied,
163 profile_cast);
164 return; 141 return;
165 } 142 }
166 143
167 IOThreadExtensionFunction* function_io = 144 IOThreadExtensionFunction* function_io =
168 function->AsIOThreadExtensionFunction(); 145 function->AsIOThreadExtensionFunction();
169 if (!function_io) { 146 if (!function_io) {
170 NOTREACHED(); 147 NOTREACHED();
171 return; 148 return;
172 } 149 }
173 function_io->set_ipc_sender(ipc_sender, routing_id); 150 function_io->set_ipc_sender(ipc_sender, routing_id);
174 function_io->set_extension_info_map(extension_info_map); 151 function_io->set_extension_info_map(extension_info_map);
175 function->set_include_incognito( 152 function->set_include_incognito(
176 extension_info_map->IsIncognitoEnabled(extension->id())); 153 extension_info_map->IsIncognitoEnabled(extension->id()));
177 154
178 if (!CheckPermissions(function, extension, params, ipc_sender, routing_id)) { 155 if (!CheckPermissions(function, extension, params, ipc_sender, routing_id)) {
179 LogFailure(extension, 156 LogFailure(extension, params.name, kAccessDenied);
180 params.name,
181 args.Pass(),
182 kAccessDenied,
183 profile_cast);
184 return; 157 return;
185 } 158 }
186 159
187 ExtensionsQuotaService* quota = extension_info_map->GetQuotaService(); 160 ExtensionsQuotaService* quota = extension_info_map->GetQuotaService();
188 std::string violation_error = quota->Assess(extension->id(), 161 std::string violation_error = quota->Assess(extension->id(),
189 function, 162 function,
190 &params.arguments, 163 &params.arguments,
191 base::TimeTicks::Now()); 164 base::TimeTicks::Now());
192 if (violation_error.empty()) { 165 if (violation_error.empty()) {
193 LogSuccess(extension,
194 params.name,
195 args.Pass(),
196 profile_cast);
197 function->Run(); 166 function->Run();
167 LogSuccess(extension, params);
198 } else { 168 } else {
199 LogFailure(extension,
200 params.name,
201 args.Pass(),
202 kQuotaExceeded,
203 profile_cast);
204 function->OnQuotaExceeded(violation_error); 169 function->OnQuotaExceeded(violation_error);
170 LogFailure(extension, params.name, kQuotaExceeded);
205 } 171 }
206 } 172 }
207 173
208 ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(Profile* profile, 174 ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(Profile* profile,
209 Delegate* delegate) 175 Delegate* delegate)
210 : profile_(profile), 176 : profile_(profile),
211 delegate_(delegate) { 177 delegate_(delegate) {
212 } 178 }
213 179
214 ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() { 180 ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() {
(...skipping 16 matching lines...) Expand all
231 WebSecurityOrigin::createFromString(params.source_origin), 197 WebSecurityOrigin::createFromString(params.source_origin),
232 params.source_url)); 198 params.source_url));
233 199
234 scoped_refptr<ExtensionFunction> function( 200 scoped_refptr<ExtensionFunction> function(
235 CreateExtensionFunction(params, extension, 201 CreateExtensionFunction(params, extension,
236 render_view_host->GetProcess()->GetID(), 202 render_view_host->GetProcess()->GetID(),
237 *(service->process_map()), 203 *(service->process_map()),
238 extensions::ExtensionAPI::GetSharedInstance(), 204 extensions::ExtensionAPI::GetSharedInstance(),
239 profile(), render_view_host, render_view_host, 205 profile(), render_view_host, render_view_host,
240 render_view_host->GetRoutingID())); 206 render_view_host->GetRoutingID()));
241 scoped_ptr<ListValue> args(params.arguments.DeepCopy());
242
243 if (!function) { 207 if (!function) {
244 LogFailure(extension, 208 LogFailure(extension, params.name, kAccessDenied);
245 params.name,
246 args.Pass(),
247 kAccessDenied,
248 profile());
249 return; 209 return;
250 } 210 }
251 211
252 UIThreadExtensionFunction* function_ui = 212 UIThreadExtensionFunction* function_ui =
253 function->AsUIThreadExtensionFunction(); 213 function->AsUIThreadExtensionFunction();
254 if (!function_ui) { 214 if (!function_ui) {
255 NOTREACHED(); 215 NOTREACHED();
256 return; 216 return;
257 } 217 }
258 function_ui->set_dispatcher(AsWeakPtr()); 218 function_ui->set_dispatcher(AsWeakPtr());
259 function_ui->set_profile(profile_); 219 function_ui->set_profile(profile_);
260 function->set_include_incognito(service->CanCrossIncognito(extension)); 220 function->set_include_incognito(service->CanCrossIncognito(extension));
261 221
262 if (!CheckPermissions(function, extension, params, render_view_host, 222 if (!CheckPermissions(function, extension, params, render_view_host,
263 render_view_host->GetRoutingID())) { 223 render_view_host->GetRoutingID())) {
264 LogFailure(extension, 224 LogFailure(extension, params.name, kAccessDenied);
265 params.name,
266 args.Pass(),
267 kAccessDenied,
268 profile());
269 return; 225 return;
270 } 226 }
271 227
272 ExtensionsQuotaService* quota = service->quota_service(); 228 ExtensionsQuotaService* quota = service->quota_service();
273 std::string violation_error = quota->Assess(extension->id(), 229 std::string violation_error = quota->Assess(extension->id(),
274 function, 230 function,
275 &params.arguments, 231 &params.arguments,
276 base::TimeTicks::Now()); 232 base::TimeTicks::Now());
277 if (violation_error.empty()) { 233 if (violation_error.empty()) {
278 // See crbug.com/39178. 234 // See crbug.com/39178.
279 ExternalProtocolHandler::PermitLaunchUrl(); 235 ExternalProtocolHandler::PermitLaunchUrl();
280 LogSuccess(extension, params.name, args.Pass(), profile()); 236
281 function->Run(); 237 function->Run();
238 LogSuccess(extension, params);
282 } else { 239 } else {
283 LogFailure(extension,
284 params.name,
285 args.Pass(),
286 kQuotaExceeded,
287 profile());
288 function->OnQuotaExceeded(violation_error); 240 function->OnQuotaExceeded(violation_error);
241 LogFailure(extension, params.name, kQuotaExceeded);
289 } 242 }
290 243
291 // Note: do not access |this| after this point. We may have been deleted 244 // Note: do not access |this| after this point. We may have been deleted
292 // if function->Run() ended up closing the tab that owns us. 245 // if function->Run() ended up closing the tab that owns us.
293 246
294 // Check if extension was uninstalled by management.uninstall. 247 // Check if extension was uninstalled by management.uninstall.
295 if (!service->extensions()->GetByID(params.extension_id)) 248 if (!service->extensions()->GetByID(params.extension_id))
296 return; 249 return;
297 250
298 // We only adjust the keepalive count for UIThreadExtensionFunction for 251 // We only adjust the keepalive count for UIThreadExtensionFunction for
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 } 323 }
371 324
372 // static 325 // static
373 void ExtensionFunctionDispatcher::SendAccessDenied( 326 void ExtensionFunctionDispatcher::SendAccessDenied(
374 IPC::Sender* ipc_sender, int routing_id, int request_id) { 327 IPC::Sender* ipc_sender, int routing_id, int request_id) {
375 ListValue empty_list; 328 ListValue empty_list;
376 ipc_sender->Send(new ExtensionMsg_Response( 329 ipc_sender->Send(new ExtensionMsg_Response(
377 routing_id, request_id, false, empty_list, 330 routing_id, request_id, false, empty_list,
378 "Access to extension API denied.")); 331 "Access to extension API denied."));
379 } 332 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/blocked_actions.cc ('k') | chrome/browser/extensions/tab_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698