Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / external_extension.cc
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/external_extension.h"
6
7 #include "chrome/common/render_messages.h"
8 #include "chrome/common/search_provider.h"
9 #include "content/public/renderer/render_view.h"
10 #include "third_party/WebKit/public/web/WebDocument.h"
11 #include "third_party/WebKit/public/web/WebLocalFrame.h"
12 #include "third_party/WebKit/public/web/WebView.h"
13 #include "v8/include/v8.h"
14
15 using blink::WebLocalFrame;
16 using blink::WebView;
17 using content::RenderView;
18
19 namespace extensions_v8 {
20
21 namespace {
22
23 const char* const kSearchProviderApi =
24     "var external;"
25     "if (!external)"
26     "  external = {};"
27     "external.AddSearchProvider = function(name) {"
28     "  native function NativeAddSearchProvider();"
29     "  NativeAddSearchProvider(name);"
30     "};"
31     "external.IsSearchProviderInstalled = function(name) {"
32     "  native function NativeIsSearchProviderInstalled();"
33     "  return NativeIsSearchProviderInstalled(name);"
34     "};";
35
36 const char kExternalExtensionName[] = "v8/External";
37
38 }  // namespace
39
40 class ExternalExtensionWrapper : public v8::Extension {
41  public:
42   ExternalExtensionWrapper();
43
44   // Allows v8's javascript code to call the native functions defined
45   // in this class for window.external.
46   v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
47       v8::Isolate* isolate,
48       v8::Handle<v8::String> name) override;
49
50   // Helper function to find the RenderView. May return NULL.
51   static RenderView* GetRenderView();
52
53   // Implementation of window.external.AddSearchProvider.
54   static void AddSearchProvider(
55       const v8::FunctionCallbackInfo<v8::Value>& args);
56
57   // Implementation of window.external.IsSearchProviderInstalled.
58   static void IsSearchProviderInstalled(
59       const v8::FunctionCallbackInfo<v8::Value>& args);
60
61  private:
62   DISALLOW_COPY_AND_ASSIGN(ExternalExtensionWrapper);
63 };
64
65 ExternalExtensionWrapper::ExternalExtensionWrapper()
66     : v8::Extension(kExternalExtensionName, kSearchProviderApi) {
67 }
68
69 v8::Handle<v8::FunctionTemplate>
70 ExternalExtensionWrapper::GetNativeFunctionTemplate(
71     v8::Isolate* isolate,
72     v8::Handle<v8::String> name) {
73   if (name->Equals(v8::String::NewFromUtf8(isolate, "NativeAddSearchProvider")))
74     return v8::FunctionTemplate::New(isolate, AddSearchProvider);
75
76   if (name->Equals(v8::String::NewFromUtf8(
77           isolate, "NativeIsSearchProviderInstalled"))) {
78     return v8::FunctionTemplate::New(isolate, IsSearchProviderInstalled);
79   }
80
81   return v8::Handle<v8::FunctionTemplate>();
82 }
83
84 // static
85 RenderView* ExternalExtensionWrapper::GetRenderView() {
86   WebLocalFrame* webframe = WebLocalFrame::frameForCurrentContext();
87   DCHECK(webframe) << "There should be an active frame since we just got "
88       "a native function called.";
89   if (!webframe)
90     return NULL;
91
92   WebView* webview = webframe->view();
93   if (!webview)
94     return NULL;  // can happen during closing
95
96   return RenderView::FromWebView(webview);
97 }
98
99 // static
100 void ExternalExtensionWrapper::AddSearchProvider(
101     const v8::FunctionCallbackInfo<v8::Value>& args) {
102   if (!args.Length() || !args[0]->IsString())
103     return;
104
105   std::string osdd_string(*v8::String::Utf8Value(args[0]));
106   if (osdd_string.empty())
107     return;
108
109   RenderView* render_view = GetRenderView();
110   if (!render_view)
111     return;
112
113   WebLocalFrame* webframe = WebLocalFrame::frameForCurrentContext();
114   if (!webframe)
115     return;
116
117   GURL osdd_url(osdd_string);
118   if (!osdd_url.is_empty() && osdd_url.is_valid()) {
119     render_view->Send(new ChromeViewHostMsg_PageHasOSDD(
120         render_view->GetRoutingID(), webframe->document().url(), osdd_url,
121         search_provider::EXPLICIT_PROVIDER));
122   }
123 }
124
125 // static
126 void ExternalExtensionWrapper::IsSearchProviderInstalled(
127     const v8::FunctionCallbackInfo<v8::Value>& args) {
128   if (!args.Length() || !args[0]->IsString())
129     return;
130
131   v8::String::Utf8Value utf8name(args[0]);
132   if (!utf8name.length())
133     return;
134
135   std::string name(*utf8name);
136   RenderView* render_view = GetRenderView();
137   if (!render_view)
138     return;
139
140   WebLocalFrame* webframe = WebLocalFrame::frameForCurrentContext();
141   if (!webframe)
142     return;
143
144   search_provider::InstallState install = search_provider::DENIED;
145   GURL inquiry_url = GURL(name);
146   if (!inquiry_url.is_empty()) {
147       render_view->Send(new ChromeViewHostMsg_GetSearchProviderInstallState(
148           render_view->GetRoutingID(),
149           webframe->document().url(),
150           inquiry_url,
151           &install));
152   }
153
154   if (install == search_provider::DENIED) {
155     // FIXME: throw access denied exception.
156     v8::Isolate* isolate = args.GetIsolate();
157     isolate->ThrowException(v8::Exception::Error(v8::String::Empty(isolate)));
158     return;
159   }
160   args.GetReturnValue().Set(static_cast<int32_t>(install));
161 }
162
163 v8::Extension* ExternalExtension::Get() {
164   return new ExternalExtensionWrapper();
165 }
166
167 }  // namespace extensions_v8