Index: chrome/renderer/extensions/extension_process_bindings.cc |
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc |
deleted file mode 100644 |
index c1aa392ec2ef07f16ce53f9f891f86a7a65ccbbb..0000000000000000000000000000000000000000 |
--- a/chrome/renderer/extensions/extension_process_bindings.cc |
+++ /dev/null |
@@ -1,665 +0,0 @@ |
-// Copyright (c) 2011 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/renderer/extensions/extension_process_bindings.h" |
- |
-#include <map> |
-#include <set> |
-#include <string> |
-#include <vector> |
- |
-#include "base/callback.h" |
-#include "base/command_line.h" |
-#include "base/json/json_reader.h" |
-#include "base/lazy_instance.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/string_number_conversions.h" |
-#include "base/string_util.h" |
-#include "base/utf_string_conversions.h" |
-#include "chrome/common/extensions/extension.h" |
-#include "chrome/common/extensions/extension_action.h" |
-#include "chrome/common/extensions/extension_constants.h" |
-#include "chrome/common/extensions/extension_messages.h" |
-#include "chrome/common/extensions/extension_set.h" |
-#include "chrome/common/extensions/url_pattern.h" |
-#include "chrome/common/render_messages.h" |
-#include "chrome/common/url_constants.h" |
-#include "chrome/common/chrome_view_types.h" |
-#include "content/public/renderer/render_view.h" |
-#include "content/public/renderer/render_view_visitor.h" |
-#include "chrome/renderer/chrome_render_process_observer.h" |
-#include "chrome/renderer/extensions/chrome_v8_context.h" |
-#include "chrome/renderer/extensions/chrome_v8_context_set.h" |
-#include "chrome/renderer/extensions/chrome_v8_extension.h" |
-#include "chrome/renderer/extensions/event_bindings.h" |
-#include "chrome/renderer/extensions/extension_dispatcher.h" |
-#include "chrome/renderer/extensions/extension_helper.h" |
-#include "chrome/renderer/extensions/renderer_extension_bindings.h" |
-#include "chrome/renderer/extensions/user_script_slave.h" |
-#include "chrome/renderer/static_v8_external_string_resource.h" |
-#include "content/public/renderer/render_view.h" |
-#include "grit/common_resources.h" |
-#include "grit/renderer_resources.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebBlob.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
-#include "third_party/skia/include/core/SkBitmap.h" |
-#include "third_party/skia/include/core/SkColor.h" |
-#include "ui/base/resource/resource_bundle.h" |
-#include "v8/include/v8.h" |
-#include "webkit/glue/webkit_glue.h" |
- |
-using WebKit::WebFrame; |
-using WebKit::WebView; |
- |
-namespace { |
- |
-const char* kExtensionDeps[] = { |
- "extensions/event.js", |
- "extensions/json_schema.js", |
- "extensions/renderer_extension_bindings.js", |
- "extensions/apitest.js" |
-}; |
- |
-// Contains info relevant to a pending API request. |
-struct PendingRequest { |
- public : |
- PendingRequest(v8::Persistent<v8::Context> context, const std::string& name, |
- const std::string& extension_id) |
- : context(context), name(name), extension_id(extension_id) { |
- } |
- v8::Persistent<v8::Context> context; |
- std::string name; |
- std::string extension_id; |
-}; |
-typedef std::map<int, linked_ptr<PendingRequest> > PendingRequestMap; |
- |
-base::LazyInstance<PendingRequestMap> g_pending_requests( |
- base::LINKER_INITIALIZED); |
- |
-// A RenderViewVisitor class that iterates through the set of available |
-// views, looking for a view of the given type, in the given browser window |
-// and within the given extension. |
-// Used to accumulate the list of views associated with an extension. |
-class ExtensionViewAccumulator : public content::RenderViewVisitor { |
- public: |
- ExtensionViewAccumulator(const std::string& extension_id, |
- int browser_window_id, |
- content::ViewType view_type) |
- : extension_id_(extension_id), |
- browser_window_id_(browser_window_id), |
- view_type_(view_type), |
- views_(v8::Array::New()), |
- index_(0) { |
- } |
- |
- v8::Local<v8::Array> views() { return views_; } |
- |
- virtual bool Visit(content::RenderView* render_view) { |
- ExtensionHelper* helper = ExtensionHelper::Get(render_view); |
- if (!ViewTypeMatches(helper->view_type(), view_type_)) |
- return true; |
- |
- GURL url = render_view->GetWebView()->mainFrame()->document().url(); |
- if (!url.SchemeIs(chrome::kExtensionScheme)) |
- return true; |
- const std::string& extension_id = url.host(); |
- if (extension_id != extension_id_) |
- return true; |
- |
- if (browser_window_id_ != extension_misc::kUnknownWindowId && |
- helper->browser_window_id() != browser_window_id_) { |
- return true; |
- } |
- |
- v8::Local<v8::Context> context = |
- render_view->GetWebView()->mainFrame()->mainWorldScriptContext(); |
- if (!context.IsEmpty()) { |
- v8::Local<v8::Value> window = context->Global(); |
- DCHECK(!window.IsEmpty()); |
- |
- if (!OnMatchedView(window)) |
- return false; |
- } |
- return true; |
- } |
- |
- private: |
- // Called on each view found matching the search criteria. Returns false |
- // to terminate the iteration. |
- bool OnMatchedView(v8::Local<v8::Value> view_window) { |
- views_->Set(v8::Integer::New(index_), view_window); |
- index_++; |
- |
- if (view_type_ == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) |
- return false; // There can be only one... |
- |
- return true; |
- } |
- |
- // Returns true is |type| "isa" |match|. |
- static bool ViewTypeMatches(content::ViewType type, content::ViewType match) { |
- if (type == match) |
- return true; |
- |
- // INVALID means match all. |
- if (match == content::VIEW_TYPE_INVALID) |
- return true; |
- |
- return false; |
- } |
- |
- std::string extension_id_; |
- int browser_window_id_; |
- content::ViewType view_type_; |
- v8::Local<v8::Array> views_; |
- int index_; |
-}; |
- |
-class ExtensionImpl : public ChromeV8Extension { |
- public: |
- explicit ExtensionImpl(ExtensionDispatcher* extension_dispatcher) |
- : ChromeV8Extension("extensions/extension_process_bindings.js", |
- IDR_EXTENSION_PROCESS_BINDINGS_JS, |
- arraysize(kExtensionDeps), |
- kExtensionDeps, |
- extension_dispatcher) { |
- } |
- ~ExtensionImpl() {} |
- |
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( |
- v8::Handle<v8::String> name) { |
- if (name->Equals(v8::String::New("GetExtensionAPIDefinition"))) { |
- return v8::FunctionTemplate::New(GetExtensionAPIDefinition); |
- } else if (name->Equals(v8::String::New("GetExtensionViews"))) { |
- return v8::FunctionTemplate::New(GetExtensionViews, |
- v8::External::New(this)); |
- } else if (name->Equals(v8::String::New("GetNextRequestId"))) { |
- return v8::FunctionTemplate::New(GetNextRequestId); |
- } else if (name->Equals(v8::String::New("OpenChannelToTab"))) { |
- return v8::FunctionTemplate::New(OpenChannelToTab); |
- } else if (name->Equals(v8::String::New("GetNextContextMenuId"))) { |
- return v8::FunctionTemplate::New(GetNextContextMenuId); |
- } else if (name->Equals(v8::String::New("GetNextTtsEventId"))) { |
- return v8::FunctionTemplate::New(GetNextTtsEventId); |
- } else if (name->Equals(v8::String::New("GetCurrentPageActions"))) { |
- return v8::FunctionTemplate::New(GetCurrentPageActions, |
- v8::External::New(this)); |
- } else if (name->Equals(v8::String::New("StartRequest"))) { |
- return v8::FunctionTemplate::New(StartRequest, |
- v8::External::New(this)); |
- } else if (name->Equals(v8::String::New("GetRenderViewId"))) { |
- return v8::FunctionTemplate::New(GetRenderViewId); |
- } else if (name->Equals(v8::String::New("SetIconCommon"))) { |
- return v8::FunctionTemplate::New(SetIconCommon, |
- v8::External::New(this)); |
- } else if (name->Equals(v8::String::New("GetUniqueSubEventName"))) { |
- return v8::FunctionTemplate::New(GetUniqueSubEventName); |
- } else if (name->Equals(v8::String::New("GetLocalFileSystem"))) { |
- return v8::FunctionTemplate::New(GetLocalFileSystem); |
- } else if (name->Equals(v8::String::New("DecodeJPEG"))) { |
- return v8::FunctionTemplate::New(DecodeJPEG, v8::External::New(this)); |
- } else if (name->Equals(v8::String::New("CreateBlob"))) { |
- return v8::FunctionTemplate::New(CreateBlob, v8::External::New(this)); |
- } |
- |
- return ChromeV8Extension::GetNativeFunction(name); |
- } |
- |
- private: |
- static v8::Handle<v8::Value> GetExtensionAPIDefinition( |
- const v8::Arguments& args) { |
- return v8::String::NewExternal( |
- new StaticV8ExternalAsciiStringResource( |
- ResourceBundle::GetSharedInstance().GetRawDataResource( |
- IDR_EXTENSION_API_JSON))); |
- } |
- |
- static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) { |
- if (args.Length() != 2) |
- return v8::Undefined(); |
- |
- if (!args[0]->IsInt32() || !args[1]->IsString()) |
- return v8::Undefined(); |
- |
- // |browser_window_id| == extension_misc::kUnknownWindowId means getting |
- // views attached to any browser window. |
- int browser_window_id = args[0]->Int32Value(); |
- |
- std::string view_type_string = *v8::String::Utf8Value(args[1]->ToString()); |
- StringToUpperASCII(&view_type_string); |
- // |view_type| == content::VIEW_TYPE_INVALID means getting any type of |
- // views. |
- content::ViewType view_type = content::VIEW_TYPE_INVALID; |
- if (view_type_string == chrome::kViewTypeBackgroundPage) { |
- view_type = chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE; |
- } else if (view_type_string == chrome::kViewTypeInfobar) { |
- view_type = chrome::VIEW_TYPE_EXTENSION_INFOBAR; |
- } else if (view_type_string == chrome::kViewTypeNotification) { |
- view_type = chrome::VIEW_TYPE_NOTIFICATION; |
- } else if (view_type_string == chrome::kViewTypeTabContents) { |
- view_type = content::VIEW_TYPE_TAB_CONTENTS; |
- } else if (view_type_string == chrome::kViewTypePopup) { |
- view_type = chrome::VIEW_TYPE_EXTENSION_POPUP; |
- } else if (view_type_string == chrome::kViewTypeExtensionDialog) { |
- view_type = chrome::VIEW_TYPE_EXTENSION_DIALOG; |
- } else if (view_type_string != chrome::kViewTypeAll) { |
- return v8::Undefined(); |
- } |
- |
- ExtensionImpl* v8_extension = GetFromArguments<ExtensionImpl>(args); |
- const ::Extension* extension = |
- v8_extension->GetExtensionForCurrentRenderView(); |
- if (!extension) |
- return v8::Undefined(); |
- |
- ExtensionViewAccumulator accumulator(extension->id(), browser_window_id, |
- view_type); |
- content::RenderView::ForEach(&accumulator); |
- return accumulator.views(); |
- } |
- |
- static v8::Handle<v8::Value> GetNextRequestId(const v8::Arguments& args) { |
- static int next_request_id = 0; |
- return v8::Integer::New(next_request_id++); |
- } |
- |
- // Attach an event name to an object. |
- static v8::Handle<v8::Value> GetUniqueSubEventName( |
- const v8::Arguments& args) { |
- static int next_event_id = 0; |
- DCHECK(args.Length() == 1); |
- DCHECK(args[0]->IsString()); |
- std::string event_name(*v8::String::AsciiValue(args[0])); |
- std::string unique_event_name = |
- event_name + "/" + base::IntToString(++next_event_id); |
- return v8::String::New(unique_event_name.c_str()); |
- } |
- |
- static v8::Handle<v8::Value> GetLocalFileSystem( |
- const v8::Arguments& args) { |
- DCHECK(args.Length() == 2); |
- DCHECK(args[0]->IsString()); |
- DCHECK(args[1]->IsString()); |
- std::string name(*v8::String::Utf8Value(args[0])); |
- std::string path(*v8::String::Utf8Value(args[1])); |
- |
- WebFrame* webframe = WebFrame::frameForCurrentContext(); |
- return webframe->createFileSystem(WebKit::WebFileSystem::TypeExternal, |
- WebKit::WebString::fromUTF8(name.c_str()), |
- WebKit::WebString::fromUTF8(path.c_str())); |
- } |
- |
- // Decodes supplied JPEG byte array to image pixel array. |
- static v8::Handle<v8::Value> DecodeJPEG(const v8::Arguments& args) { |
- static const char* kAllowedIds[] = { |
- "haiffjcadagjlijoggckpgfnoeiflnem", |
- "gnedhmakppccajfpfiihfcdlnpgomkcf", |
- "fjcibdnjlbfnbfdjneajpipnlcppleek", |
- "oflbaaikkabfdfkimeclgkackhdkpnip" // Testing extension. |
- }; |
- static const std::vector<std::string> allowed_ids( |
- kAllowedIds, kAllowedIds + arraysize(kAllowedIds)); |
- |
- ExtensionImpl* v8_extension = GetFromArguments<ExtensionImpl>(args); |
- const ::Extension* extension = |
- v8_extension->GetExtensionForCurrentRenderView(); |
- if (!extension) |
- return v8::Undefined(); |
- if (allowed_ids.end() == std::find( |
- allowed_ids.begin(), allowed_ids.end(), extension->id())) { |
- return v8::Undefined(); |
- } |
- |
- DCHECK(args.Length() == 1); |
- DCHECK(args[0]->IsArray()); |
- v8::Local<v8::Object> jpeg_array = args[0]->ToObject(); |
- size_t jpeg_length = |
- jpeg_array->Get(v8::String::New("length"))->Int32Value(); |
- |
- // Put input JPEG array into string for DecodeImage(). |
- std::string jpeg_array_string; |
- jpeg_array_string.reserve(jpeg_length); |
- |
- // Unfortunately we cannot request continuous backing store of the |
- // |jpeg_array| object as it might not have one. So we make |
- // element copy here. |
- // Note(mnaganov): If it is not fast enough |
- // (and main constraints might be in repetition of v8 API calls), |
- // change the argument type from Array to String and use |
- // String::Write(). |
- // Note(vitalyr): Another option is to use Int8Array for inputs and |
- // Int32Array for output. |
- for (size_t i = 0; i != jpeg_length; ++i) { |
- jpeg_array_string.push_back( |
- jpeg_array->Get(v8::Integer::New(i))->Int32Value()); |
- } |
- |
- // Decode and verify resulting image metrics. |
- SkBitmap bitmap; |
- if (!webkit_glue::DecodeImage(jpeg_array_string, &bitmap)) |
- return v8::Undefined(); |
- if (bitmap.config() != SkBitmap::kARGB_8888_Config) |
- return v8::Undefined(); |
- const int width = bitmap.width(); |
- const int height = bitmap.height(); |
- SkAutoLockPixels lockpixels(bitmap); |
- const uint32_t* pixels = static_cast<uint32_t*>(bitmap.getPixels()); |
- if (!pixels) |
- return v8::Undefined(); |
- |
- // Compose output array. This API call only accepts kARGB_8888_Config images |
- // so we rely on each pixel occupying 4 bytes. |
- // Note(mnaganov): to speed this up, you may use backing store |
- // technique from CreateExternalArray() of v8/src/d8.cc. |
- v8::Local<v8::Array> bitmap_array(v8::Array::New(width * height)); |
- for (int i = 0; i != width * height; ++i) { |
- bitmap_array->Set(v8::Integer::New(i), |
- v8::Integer::New(pixels[i] & 0xFFFFFF)); |
- } |
- return bitmap_array; |
- } |
- |
- // Creates a Blob with the content of the specified file. |
- static v8::Handle<v8::Value> CreateBlob(const v8::Arguments& args) { |
- CHECK(args.Length() == 2); |
- CHECK(args[0]->IsString()); |
- CHECK(args[1]->IsInt32()); |
- WebKit::WebString path(UTF8ToUTF16(*v8::String::Utf8Value(args[0]))); |
- WebKit::WebBlob blob = |
- WebKit::WebBlob::createFromFile(path, args[1]->Int32Value()); |
- return blob.toV8Value(); |
- } |
- |
- // Creates a new messaging channel to the tab with the given ID. |
- static v8::Handle<v8::Value> OpenChannelToTab(const v8::Arguments& args) { |
- // Get the current RenderView so that we can send a routed IPC message from |
- // the correct source. |
- content::RenderView* renderview = GetCurrentRenderView(); |
- if (!renderview) |
- return v8::Undefined(); |
- |
- if (args.Length() >= 3 && args[0]->IsInt32() && args[1]->IsString() && |
- args[2]->IsString()) { |
- int tab_id = args[0]->Int32Value(); |
- std::string extension_id = *v8::String::Utf8Value(args[1]->ToString()); |
- std::string channel_name = *v8::String::Utf8Value(args[2]->ToString()); |
- int port_id = -1; |
- renderview->Send(new ExtensionHostMsg_OpenChannelToTab( |
- renderview->GetRoutingId(), tab_id, extension_id, channel_name, |
- &port_id)); |
- return v8::Integer::New(port_id); |
- } |
- return v8::Undefined(); |
- } |
- |
- static v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) { |
- // Note: this works because contextMenus.create() only works in the |
- // extension process. If that API is opened up to content scripts, this |
- // will need to change. See crbug.com/77023 |
- static int next_context_menu_id = 1; |
- return v8::Integer::New(next_context_menu_id++); |
- } |
- |
- static v8::Handle<v8::Value> GetNextTtsEventId(const v8::Arguments& args) { |
- // Note: this works because the TTS API only works in the |
- // extension process, not content scripts. |
- static int next_tts_event_id = 1; |
- return v8::Integer::New(next_tts_event_id++); |
- } |
- |
- static v8::Handle<v8::Value> GetCurrentPageActions( |
- const v8::Arguments& args) { |
- ExtensionImpl* v8_extension = GetFromArguments<ExtensionImpl>(args); |
- std::string extension_id = *v8::String::Utf8Value(args[0]->ToString()); |
- const ::Extension* extension = |
- v8_extension->extension_dispatcher_->extensions()->GetByID( |
- extension_id); |
- CHECK(!extension_id.empty()); |
- if (!extension) |
- return v8::Undefined(); |
- |
- v8::Local<v8::Array> page_action_vector = v8::Array::New(); |
- if (extension->page_action()) { |
- std::string id = extension->page_action()->id(); |
- page_action_vector->Set(v8::Integer::New(0), |
- v8::String::New(id.c_str(), id.size())); |
- } |
- |
- return page_action_vector; |
- } |
- |
- // Common code for starting an API request to the browser. |value_args| |
- // contains the request's arguments. |
- // Steals value_args contents for efficiency. |
- static v8::Handle<v8::Value> StartRequestCommon( |
- const v8::Arguments& args, ListValue* value_args) { |
- ExtensionImpl* v8_extension = GetFromArguments<ExtensionImpl>(args); |
- |
- const ChromeV8ContextSet& contexts = |
- v8_extension->extension_dispatcher()->v8_context_set(); |
- ChromeV8Context* current_context = contexts.GetCurrent(); |
- if (!current_context) |
- return v8::Undefined(); |
- |
- // Get the current RenderView so that we can send a routed IPC message from |
- // the correct source. |
- content::RenderView* renderview = current_context->GetRenderView(); |
- if (!renderview) |
- return v8::Undefined(); |
- |
- std::string name = *v8::String::AsciiValue(args[0]); |
- const std::set<std::string>& function_names = |
- v8_extension->extension_dispatcher_->function_names(); |
- if (function_names.find(name) == function_names.end()) { |
- NOTREACHED() << "Unexpected function " << name; |
- return v8::Undefined(); |
- } |
- |
- // TODO(aa): add this to ChromeV8Context. |
- if (!v8_extension->CheckPermissionForCurrentRenderView(name)) |
- return v8::Undefined(); |
- |
- GURL source_url; |
- WebFrame* webframe = current_context->web_frame(); |
- if (webframe) |
- source_url = webframe->document().url(); |
- |
- int request_id = args[2]->Int32Value(); |
- bool has_callback = args[3]->BooleanValue(); |
- bool for_io_thread = args[4]->BooleanValue(); |
- |
- v8::Persistent<v8::Context> v8_context = |
- v8::Persistent<v8::Context>::New(v8::Context::GetCurrent()); |
- DCHECK(!v8_context.IsEmpty()); |
- g_pending_requests.Get()[request_id].reset(new PendingRequest( |
- v8_context, name, current_context->extension_id())); |
- |
- ExtensionHostMsg_Request_Params params; |
- params.name = name; |
- params.arguments.Swap(value_args); |
- params.source_url = source_url; |
- params.request_id = request_id; |
- params.has_callback = has_callback; |
- params.user_gesture = |
- webframe ? webframe->isProcessingUserGesture() : false; |
- if (for_io_thread) { |
- renderview->Send(new ExtensionHostMsg_RequestForIOThread( |
- renderview->GetRoutingId(), params)); |
- } else { |
- renderview->Send(new ExtensionHostMsg_Request( |
- renderview->GetRoutingId(), params)); |
- } |
- |
- return v8::Undefined(); |
- } |
- |
- // Starts an API request to the browser, with an optional callback. The |
- // callback will be dispatched to EventBindings::HandleResponse. |
- static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) { |
- std::string str_args = *v8::String::Utf8Value(args[1]); |
- base::JSONReader reader; |
- scoped_ptr<Value> value_args; |
- value_args.reset(reader.JsonToValue(str_args, false, false)); |
- |
- // Since we do the serialization in the v8 extension, we should always get |
- // valid JSON. |
- if (!value_args.get() || !value_args->IsType(Value::TYPE_LIST)) { |
- NOTREACHED() << "Invalid JSON passed to StartRequest."; |
- return v8::Undefined(); |
- } |
- |
- return StartRequestCommon(args, static_cast<ListValue*>(value_args.get())); |
- } |
- |
- static bool ConvertImageDataToBitmapValue( |
- const v8::Arguments& args, Value** bitmap_value) { |
- v8::Local<v8::Object> extension_args = args[1]->ToObject(); |
- v8::Local<v8::Object> details = |
- extension_args->Get(v8::String::New("0"))->ToObject(); |
- v8::Local<v8::Object> image_data = |
- details->Get(v8::String::New("imageData"))->ToObject(); |
- v8::Local<v8::Object> data = |
- image_data->Get(v8::String::New("data"))->ToObject(); |
- int width = image_data->Get(v8::String::New("width"))->Int32Value(); |
- int height = image_data->Get(v8::String::New("height"))->Int32Value(); |
- |
- int data_length = data->Get(v8::String::New("length"))->Int32Value(); |
- if (data_length != 4 * width * height) { |
- NOTREACHED() << "Invalid argument to setIcon. Expecting ImageData."; |
- return false; |
- } |
- |
- SkBitmap bitmap; |
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); |
- bitmap.allocPixels(); |
- bitmap.eraseARGB(0, 0, 0, 0); |
- |
- uint32_t* pixels = bitmap.getAddr32(0, 0); |
- for (int t = 0; t < width*height; t++) { |
- // |data| is RGBA, pixels is ARGB. |
- pixels[t] = SkPreMultiplyColor( |
- ((data->Get(v8::Integer::New(4*t + 3))->Int32Value() & 0xFF) << 24) | |
- ((data->Get(v8::Integer::New(4*t + 0))->Int32Value() & 0xFF) << 16) | |
- ((data->Get(v8::Integer::New(4*t + 1))->Int32Value() & 0xFF) << 8) | |
- ((data->Get(v8::Integer::New(4*t + 2))->Int32Value() & 0xFF) << 0)); |
- } |
- |
- // Construct the Value object. |
- IPC::Message bitmap_pickle; |
- IPC::WriteParam(&bitmap_pickle, bitmap); |
- *bitmap_value = base::BinaryValue::CreateWithCopiedBuffer( |
- static_cast<const char*>(bitmap_pickle.data()), bitmap_pickle.size()); |
- |
- return true; |
- } |
- |
- // A special request for setting the extension action icon and the sidebar |
- // mini tab icon. This function accepts a canvas ImageData object, so it needs |
- // to do extra processing before sending the request to the browser. |
- static v8::Handle<v8::Value> SetIconCommon( |
- const v8::Arguments& args) { |
- Value* bitmap_value = NULL; |
- if (!ConvertImageDataToBitmapValue(args, &bitmap_value)) |
- return v8::Undefined(); |
- |
- v8::Local<v8::Object> extension_args = args[1]->ToObject(); |
- v8::Local<v8::Object> details = |
- extension_args->Get(v8::String::New("0"))->ToObject(); |
- |
- DictionaryValue* dict = new DictionaryValue(); |
- dict->Set("imageData", bitmap_value); |
- |
- if (details->Has(v8::String::New("tabId"))) { |
- dict->SetInteger("tabId", |
- details->Get(v8::String::New("tabId"))->Int32Value()); |
- } |
- |
- ListValue list_value; |
- list_value.Append(dict); |
- |
- return StartRequestCommon(args, &list_value); |
- } |
- |
- static v8::Handle<v8::Value> GetRenderViewId(const v8::Arguments& args) { |
- content::RenderView* renderview = GetCurrentRenderView(); |
- if (!renderview) |
- return v8::Undefined(); |
- return v8::Integer::New(renderview->GetRoutingId()); |
- } |
-}; |
- |
-} // namespace |
- |
-v8::Extension* ExtensionProcessBindings::Get( |
- ExtensionDispatcher* extension_dispatcher) { |
- static v8::Extension* extension = new ExtensionImpl(extension_dispatcher); |
- CHECK_EQ(extension_dispatcher, |
- static_cast<ExtensionImpl*>(extension)->extension_dispatcher()); |
- return extension; |
-} |
- |
-// static |
-void ExtensionProcessBindings::HandleResponse( |
- const ChromeV8ContextSet& contexts, |
- int request_id, |
- bool success, |
- const std::string& response, |
- const std::string& error, |
- std::string* extension_id) { |
- PendingRequestMap::iterator request = |
- g_pending_requests.Get().find(request_id); |
- if (request == g_pending_requests.Get().end()) { |
- // This should not be able to happen since we only remove requests when they |
- // are handled. |
- LOG(ERROR) << "Could not find specified request id: " << request_id; |
- return; |
- } |
- |
- ChromeV8Context* v8_context = |
- contexts.GetByV8Context(request->second->context); |
- if (!v8_context) |
- return; // The frame went away. |
- |
- v8::HandleScope handle_scope; |
- v8::Handle<v8::Value> argv[5]; |
- argv[0] = v8::Integer::New(request_id); |
- argv[1] = v8::String::New(request->second->name.c_str()); |
- argv[2] = v8::Boolean::New(success); |
- argv[3] = v8::String::New(response.c_str()); |
- argv[4] = v8::String::New(error.c_str()); |
- |
- v8::Handle<v8::Value> retval; |
- CHECK(v8_context->CallChromeHiddenMethod("handleResponse", |
- arraysize(argv), |
- argv, |
- &retval)); |
- // In debug, the js will validate the callback parameters and return a |
- // string if a validation error has occured. |
-#ifndef NDEBUG |
- if (!retval.IsEmpty() && !retval->IsUndefined()) { |
- std::string error = *v8::String::AsciiValue(retval); |
- DCHECK(false) << error; |
- } |
-#endif |
- |
- // Save the extension id before erasing the request. |
- *extension_id = request->second->extension_id; |
- |
- request->second->context.Dispose(); |
- request->second->context.Clear(); |
- g_pending_requests.Get().erase(request); |
-} |
- |
-// static |
-bool ExtensionProcessBindings::HasPendingRequests( |
- const std::string& extension_id) { |
- for (PendingRequestMap::const_iterator it = g_pending_requests.Get().begin(); |
- it != g_pending_requests.Get().end(); ++it) { |
- if (it->second->extension_id == extension_id) |
- return true; |
- } |
- return false; |
-} |