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

Side by Side Diff: chrome/renderer/extensions/extension_process_bindings.cc

Issue 242150: Implement browserAction.setIcon(ImageData) for extensions. (Closed)
Patch Set: common function Created 11 years, 2 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 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 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 <map> 5 #include <map>
6 #include <set> 6 #include <set>
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "chrome/renderer/extensions/extension_process_bindings.h" 10 #include "chrome/renderer/extensions/extension_process_bindings.h"
11 11
12 #include "base/json_reader.h" 12 #include "base/json_reader.h"
13 #include "base/singleton.h" 13 #include "base/singleton.h"
14 #include "chrome/common/extensions/extension.h" 14 #include "chrome/common/extensions/extension.h"
15 #include "chrome/common/extensions/extension_message_bundle.h" 15 #include "chrome/common/extensions/extension_message_bundle.h"
16 #include "chrome/common/extensions/url_pattern.h" 16 #include "chrome/common/extensions/url_pattern.h"
17 #include "chrome/common/render_messages.h" 17 #include "chrome/common/render_messages.h"
18 #include "chrome/common/url_constants.h" 18 #include "chrome/common/url_constants.h"
19 #include "chrome/renderer/extensions/bindings_utils.h" 19 #include "chrome/renderer/extensions/bindings_utils.h"
20 #include "chrome/renderer/extensions/event_bindings.h" 20 #include "chrome/renderer/extensions/event_bindings.h"
21 #include "chrome/renderer/extensions/js_only_v8_extensions.h" 21 #include "chrome/renderer/extensions/js_only_v8_extensions.h"
22 #include "chrome/renderer/extensions/renderer_extension_bindings.h" 22 #include "chrome/renderer/extensions/renderer_extension_bindings.h"
23 #include "chrome/renderer/render_view.h" 23 #include "chrome/renderer/render_view.h"
24 #include "grit/common_resources.h" 24 #include "grit/common_resources.h"
25 #include "grit/renderer_resources.h" 25 #include "grit/renderer_resources.h"
26 #include "third_party/skia/include/core/SkBitmap.h"
26 #include "webkit/api/public/WebFrame.h" 27 #include "webkit/api/public/WebFrame.h"
27 #include "webkit/api/public/WebURL.h" 28 #include "webkit/api/public/WebURL.h"
28 #include "webkit/api/public/WebKit.h" 29 #include "webkit/api/public/WebKit.h"
29 30
30 using bindings_utils::GetStringResource; 31 using bindings_utils::GetStringResource;
31 using bindings_utils::ContextInfo; 32 using bindings_utils::ContextInfo;
32 using bindings_utils::ContextList; 33 using bindings_utils::ContextList;
33 using bindings_utils::GetContexts; 34 using bindings_utils::GetContexts;
34 using bindings_utils::GetPendingRequestMap; 35 using bindings_utils::GetPendingRequestMap;
35 using bindings_utils::PendingRequest; 36 using bindings_utils::PendingRequest;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 } else if (name->Equals(v8::String::New("OpenChannelToTab"))) { 134 } else if (name->Equals(v8::String::New("OpenChannelToTab"))) {
134 return v8::FunctionTemplate::New(OpenChannelToTab); 135 return v8::FunctionTemplate::New(OpenChannelToTab);
135 } else if (name->Equals(v8::String::New("GetCurrentPageActions"))) { 136 } else if (name->Equals(v8::String::New("GetCurrentPageActions"))) {
136 return v8::FunctionTemplate::New(GetCurrentPageActions); 137 return v8::FunctionTemplate::New(GetCurrentPageActions);
137 } else if (name->Equals(v8::String::New("StartRequest"))) { 138 } else if (name->Equals(v8::String::New("StartRequest"))) {
138 return v8::FunctionTemplate::New(StartRequest); 139 return v8::FunctionTemplate::New(StartRequest);
139 } else if (name->Equals(v8::String::New("GetRenderViewId"))) { 140 } else if (name->Equals(v8::String::New("GetRenderViewId"))) {
140 return v8::FunctionTemplate::New(GetRenderViewId); 141 return v8::FunctionTemplate::New(GetRenderViewId);
141 } else if (name->Equals(v8::String::New("GetL10nMessage"))) { 142 } else if (name->Equals(v8::String::New("GetL10nMessage"))) {
142 return v8::FunctionTemplate::New(GetL10nMessage); 143 return v8::FunctionTemplate::New(GetL10nMessage);
144 } else if (name->Equals(v8::String::New("SetBrowserActionIcon"))) {
145 return v8::FunctionTemplate::New(SetBrowserActionIcon);
143 } 146 }
144 147
145 return ExtensionBase::GetNativeFunction(name); 148 return ExtensionBase::GetNativeFunction(name);
146 } 149 }
147 150
148 private: 151 private:
149 static v8::Handle<v8::Value> GetExtensionAPIDefinition( 152 static v8::Handle<v8::Value> GetExtensionAPIDefinition(
150 const v8::Arguments& args) { 153 const v8::Arguments& args) {
151 return v8::String::New(GetStringResource<IDR_EXTENSION_API_JSON>()); 154 return v8::String::New(GetStringResource<IDR_EXTENSION_API_JSON>());
152 } 155 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 326 }
324 } else { 327 } else {
325 NOTREACHED() << "Couldn't parse second parameter."; 328 NOTREACHED() << "Couldn't parse second parameter.";
326 return v8::Undefined(); 329 return v8::Undefined();
327 } 330 }
328 331
329 return v8::String::New(UTF16ToUTF8(ReplaceStringPlaceholders( 332 return v8::String::New(UTF16ToUTF8(ReplaceStringPlaceholders(
330 UTF8ToUTF16(message), substitutions, NULL)).c_str()); 333 UTF8ToUTF16(message), substitutions, NULL)).c_str());
331 } 334 }
332 335
333 // Starts an API request to the browser, with an optional callback. The 336 // Common code for starting an API request to the browser. |value_args|
334 // callback will be dispatched to EventBindings::HandleResponse. 337 // contains the request's arguments.
335 static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) { 338 static v8::Handle<v8::Value> StartRequestCommon(
339 const v8::Arguments& args, Value* value_args) {
336 // Get the current RenderView so that we can send a routed IPC message from 340 // Get the current RenderView so that we can send a routed IPC message from
337 // the correct source. 341 // the correct source.
338 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext(); 342 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
339 if (!renderview) 343 if (!renderview)
340 return v8::Undefined(); 344 return v8::Undefined();
341 345
342 if (args.Length() != 4 || !args[0]->IsString() || !args[1]->IsString() ||
343 !args[2]->IsInt32() || !args[3]->IsBoolean())
344 return v8::Undefined();
345
346 std::string name = *v8::String::AsciiValue(args[0]); 346 std::string name = *v8::String::AsciiValue(args[0]);
347 if (GetFunctionNameSet()->find(name) == GetFunctionNameSet()->end()) { 347 if (GetFunctionNameSet()->find(name) == GetFunctionNameSet()->end()) {
348 NOTREACHED() << "Unexpected function " << name; 348 NOTREACHED() << "Unexpected function " << name;
349 return v8::Undefined(); 349 return v8::Undefined();
350 } 350 }
351 351
352 if (!ExtensionProcessBindings::CurrentContextHasPermission(name)) { 352 if (!ExtensionProcessBindings::CurrentContextHasPermission(name)) {
353 return ExtensionProcessBindings::ThrowPermissionDeniedException(name); 353 return ExtensionProcessBindings::ThrowPermissionDeniedException(name);
354 } 354 }
355 355
356 std::string str_args = *v8::String::Utf8Value(args[1]);
357 int request_id = args[2]->Int32Value(); 356 int request_id = args[2]->Int32Value();
358 bool has_callback = args[3]->BooleanValue(); 357 bool has_callback = args[3]->BooleanValue();
359 358
360 ListValue args_holder;
361 JSONReader reader;
362 Value* json_args = reader.JsonToValue(str_args, false, false);
363
364 // Since we do the serialization in the v8 extension, we should always get
365 // valid JSON.
366 if (!json_args) {
367 NOTREACHED() << "Invalid JSON passed to StartRequest.";
368 return v8::Undefined();
369 }
370
371 // Put the args in a 1-element list for easier serialization. Maybe all 359 // Put the args in a 1-element list for easier serialization. Maybe all
372 // requests should have a list of args? 360 // requests should have a list of args?
373 args_holder.Append(json_args); 361 ListValue args_holder;
362 args_holder.Append(value_args);
374 363
375 v8::Persistent<v8::Context> current_context = 364 v8::Persistent<v8::Context> current_context =
376 v8::Persistent<v8::Context>::New(v8::Context::GetCurrent()); 365 v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
377 DCHECK(!current_context.IsEmpty()); 366 DCHECK(!current_context.IsEmpty());
378 GetPendingRequestMap()[request_id].reset(new PendingRequest( 367 GetPendingRequestMap()[request_id].reset(new PendingRequest(
379 current_context, name)); 368 current_context, name));
380 369
381 renderview->SendExtensionRequest(name, args_holder, 370 renderview->SendExtensionRequest(name, args_holder,
382 request_id, has_callback); 371 request_id, has_callback);
383 372
384 return v8::Undefined(); 373 return v8::Undefined();
385 } 374 }
386 375
376 // Starts an API request to the browser, with an optional callback. The
377 // callback will be dispatched to EventBindings::HandleResponse.
378 static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) {
379 std::string str_args = *v8::String::Utf8Value(args[1]);
380 JSONReader reader;
381 Value* value_args = reader.JsonToValue(str_args, false, false);
382
383 // Since we do the serialization in the v8 extension, we should always get
384 // valid JSON.
385 if (!value_args) {
386 NOTREACHED() << "Invalid JSON passed to StartRequest.";
387 return v8::Undefined();
388 }
389
390 return StartRequestCommon(args, value_args);
391 }
392
393 // A special request for setting the browser action icon. This function
394 // accepts a canvas ImageData object, so it needs to do extra processing
395 // before sending the request to the browser.
396 static v8::Handle<v8::Value> SetBrowserActionIcon(const v8::Arguments& args) {
397 v8::Local<v8::Object> image_data = args[1]->ToObject();
398 v8::Local<v8::Object> data =
399 image_data->Get(v8::String::New("data"))->ToObject();
400 int width = image_data->Get(v8::String::New("width"))->Int32Value();
401 int height = image_data->Get(v8::String::New("height"))->Int32Value();
402
403 int data_length = data->Get(v8::String::New("length"))->Int32Value();
404 if (data_length != 4 * width * height) {
405 NOTREACHED() <<
406 "Invalid argument to browserAction.setIcon. Expecting ImageData.";
407 return v8::Undefined();
408 }
409
410 SkBitmap bitmap;
411 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
412 bitmap.allocPixels();
413 bitmap.eraseARGB(0, 0, 0, 0);
414
415 uint32_t* pixels = bitmap.getAddr32(0, 0);
416 for (int t = 0; t < width*height; t++) {
417 // |data| is RGBA, pixels is ARGB.
418 pixels[t] =
419 ((data->Get(v8::Integer::New(4*t + 3))->Int32Value() & 0xFF) << 24) |
420 ((data->Get(v8::Integer::New(4*t + 0))->Int32Value() & 0xFF) << 16) |
421 ((data->Get(v8::Integer::New(4*t + 1))->Int32Value() & 0xFF) << 8) |
422 ((data->Get(v8::Integer::New(4*t + 2))->Int32Value() & 0xFF) << 0);
423 }
424
425 // Construct the Value object.
426 IPC::Message bitmap_pickle;
427 IPC::WriteParam(&bitmap_pickle, bitmap);
428 Value* bitmap_value = BinaryValue::CreateWithCopiedBuffer(
429 static_cast<const char*>(bitmap_pickle.data()), bitmap_pickle.size());
430
431 return StartRequestCommon(args, bitmap_value);
432 }
433
387 static v8::Handle<v8::Value> GetRenderViewId(const v8::Arguments& args) { 434 static v8::Handle<v8::Value> GetRenderViewId(const v8::Arguments& args) {
388 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext(); 435 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
389 if (!renderview) 436 if (!renderview)
390 return v8::Undefined(); 437 return v8::Undefined();
391 return v8::Integer::New(renderview->routing_id()); 438 return v8::Integer::New(renderview->routing_id());
392 } 439 }
393 }; 440 };
394 441
395 } // namespace 442 } // namespace
396 443
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 return; 580 return;
534 581
535 v8::HandleScope handle_scope; 582 v8::HandleScope handle_scope;
536 WebFrame* frame = view->mainFrame(); 583 WebFrame* frame = view->mainFrame();
537 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); 584 v8::Local<v8::Context> context = frame->mainWorldScriptContext();
538 v8::Handle<v8::Value> argv[1]; 585 v8::Handle<v8::Value> argv[1];
539 argv[0] = v8::String::New(type_str); 586 argv[0] = v8::String::New(type_str);
540 bindings_utils::CallFunctionInContext(context, "setViewType", 587 bindings_utils::CallFunctionInContext(context, "setViewType",
541 arraysize(argv), argv); 588 arraysize(argv), argv);
542 } 589 }
OLDNEW
« no previous file with comments | « chrome/common/extensions/extension_action.h ('k') | chrome/renderer/resources/extension_process_bindings.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698