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/renderer/extensions/runtime_custom_bindings.h" 6 7#include "base/bind.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/values.h" 10#include "chrome/common/extensions/extension.h" 11#include "chrome/common/extensions/extension_messages.h" 12#include "chrome/common/extensions/features/feature.h" 13#include "chrome/common/extensions/manifest.h" 14#include "chrome/renderer/extensions/api_activity_logger.h" 15#include "chrome/renderer/extensions/chrome_v8_context.h" 16#include "chrome/renderer/extensions/dispatcher.h" 17#include "content/public/renderer/render_view.h" 18#include "content/public/renderer/v8_value_converter.h" 19#include "extensions/common/features/feature_provider.h" 20#include "third_party/WebKit/public/web/WebDocument.h" 21#include "third_party/WebKit/public/web/WebFrame.h" 22#include "third_party/WebKit/public/web/WebView.h" 23 24using content::V8ValueConverter; 25 26namespace extensions { 27 28RuntimeCustomBindings::RuntimeCustomBindings(Dispatcher* dispatcher, 29 ChromeV8Context* context) 30 : ChromeV8Extension(dispatcher, context) { 31 RouteFunction("GetManifest", 32 base::Bind(&RuntimeCustomBindings::GetManifest, 33 base::Unretained(this))); 34 RouteFunction("OpenChannelToExtension", 35 base::Bind(&RuntimeCustomBindings::OpenChannelToExtension, 36 base::Unretained(this))); 37 RouteFunction("OpenChannelToNativeApp", 38 base::Bind(&RuntimeCustomBindings::OpenChannelToNativeApp, 39 base::Unretained(this))); 40} 41 42RuntimeCustomBindings::~RuntimeCustomBindings() {} 43 44void RuntimeCustomBindings::OpenChannelToExtension( 45 const v8::FunctionCallbackInfo<v8::Value>& args) { 46 // Get the current RenderView so that we can send a routed IPC message from 47 // the correct source. 48 content::RenderView* renderview = GetRenderView(); 49 if (!renderview) 50 return; 51 52 // The Javascript code should validate/fill the arguments. 53 CHECK_EQ(2, args.Length()); 54 CHECK(args[0]->IsString() && args[1]->IsString()); 55 56 ExtensionMsg_ExternalConnectionInfo info; 57 info.source_id = context()->extension() ? context()->extension()->id() : ""; 58 info.target_id = *v8::String::Utf8Value(args[0]->ToString()); 59 info.source_url = renderview->GetWebView()->mainFrame()->document().url(); 60 std::string channel_name = *v8::String::Utf8Value(args[1]->ToString()); 61 int port_id = -1; 62 renderview->Send(new ExtensionHostMsg_OpenChannelToExtension( 63 renderview->GetRoutingID(), info, channel_name, &port_id)); 64 args.GetReturnValue().Set(static_cast<int32_t>(port_id)); 65} 66 67void RuntimeCustomBindings::OpenChannelToNativeApp( 68 const v8::FunctionCallbackInfo<v8::Value>& args) { 69 // Verify that the extension has permission to use native messaging. 70 Feature::Availability availability = 71 FeatureProvider::GetByName("permission")-> 72 GetFeature("nativeMessaging")->IsAvailableToContext( 73 GetExtensionForRenderView(), 74 context()->context_type(), 75 context()->GetURL()); 76 if (!availability.is_available()) { 77 APIActivityLogger::LogBlockedCall(context()->extension()->id(), 78 "nativeMessaging", 79 availability.result()); 80 return; 81 } 82 83 // Get the current RenderView so that we can send a routed IPC message from 84 // the correct source. 85 content::RenderView* renderview = GetRenderView(); 86 if (!renderview) 87 return; 88 89 // The Javascript code should validate/fill the arguments. 90 CHECK(args.Length() >= 2 && 91 args[0]->IsString() && 92 args[1]->IsString()); 93 94 std::string extension_id = *v8::String::Utf8Value(args[0]->ToString()); 95 std::string native_app_name = *v8::String::Utf8Value(args[1]->ToString()); 96 97 int port_id = -1; 98 renderview->Send(new ExtensionHostMsg_OpenChannelToNativeApp( 99 renderview->GetRoutingID(), 100 extension_id, 101 native_app_name, 102 &port_id)); 103 args.GetReturnValue().Set(static_cast<int32_t>(port_id)); 104} 105 106void RuntimeCustomBindings::GetManifest( 107 const v8::FunctionCallbackInfo<v8::Value>& args) { 108 CHECK(context()->extension()); 109 110 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); 111 args.GetReturnValue().Set( 112 converter->ToV8Value(context()->extension()->manifest()->value(), 113 context()->v8_context())); 114} 115 116} // namespace extensions 117