Upstream version 5.34.92.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 "base/command_line.h"
8 #include "chrome/common/chrome_switches.h"
9 #include "chrome/common/render_messages.h"
10 #include "chrome/common/search_provider.h"
11 #include "content/public/renderer/render_view.h"
12 #include "third_party/WebKit/public/web/WebDocument.h"
13 #include "third_party/WebKit/public/web/WebFrame.h"
14 #include "third_party/WebKit/public/web/WebView.h"
15 #include "v8/include/v8.h"
16
17 using blink::WebFrame;
18 using blink::WebView;
19 using content::RenderView;
20
21 namespace extensions_v8 {
22
23 static 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* const kExternalExtensionName = "v8/External";
37
38 class ExternalExtensionWrapper : public v8::Extension {
39  public:
40   ExternalExtensionWrapper();
41
42   // Allows v8's javascript code to call the native functions defined
43   // in this class for window.external.
44   virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
45       v8::Isolate* isolate,
46       v8::Handle<v8::String> name) OVERRIDE;
47
48   // Helper function to find the RenderView. May return NULL.
49   static RenderView* GetRenderView();
50
51   // Implementation of window.external.AddSearchProvider.
52   static void AddSearchProvider(
53       const v8::FunctionCallbackInfo<v8::Value>& args);
54
55   // Implementation of window.external.IsSearchProviderInstalled.
56   static void IsSearchProviderInstalled(
57       const v8::FunctionCallbackInfo<v8::Value>& args);
58
59  private:
60   DISALLOW_COPY_AND_ASSIGN(ExternalExtensionWrapper);
61 };
62
63 ExternalExtensionWrapper::ExternalExtensionWrapper()
64     : v8::Extension(
65         kExternalExtensionName,
66         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(
77           v8::String::NewFromUtf8(isolate, "NativeIsSearchProviderInstalled")))
78     return v8::FunctionTemplate::New(isolate, IsSearchProviderInstalled);
79
80   return v8::Handle<v8::FunctionTemplate>();
81 }
82
83 // static
84 RenderView* ExternalExtensionWrapper::GetRenderView() {
85   WebFrame* webframe = WebFrame::frameForCurrentContext();
86   DCHECK(webframe) << "There should be an active frame since we just got "
87       "a native function called.";
88   if (!webframe) return NULL;
89
90   WebView* webview = webframe->view();
91   if (!webview) return NULL;  // can happen during closing
92
93   return RenderView::FromWebView(webview);
94 }
95
96 // static
97 void ExternalExtensionWrapper::AddSearchProvider(
98     const v8::FunctionCallbackInfo<v8::Value>& args) {
99   if (!args.Length()) return;
100
101   std::string name = std::string(*v8::String::Utf8Value(args[0]));
102   if (!name.length()) return;
103
104   RenderView* render_view = GetRenderView();
105   if (!render_view) return;
106
107   GURL osd_url(name);
108   if (!osd_url.is_empty() && osd_url.is_valid()) {
109     render_view->Send(new ChromeViewHostMsg_PageHasOSDD(
110         render_view->GetRoutingID(), render_view->GetPageId(), osd_url,
111         search_provider::EXPLICIT_PROVIDER));
112   }
113 }
114
115 // static
116 void ExternalExtensionWrapper::IsSearchProviderInstalled(
117     const v8::FunctionCallbackInfo<v8::Value>& args) {
118   if (!args.Length()) return;
119   v8::String::Utf8Value utf8name(args[0]);
120   if (!utf8name.length()) return;
121
122   std::string name = std::string(*utf8name);
123   RenderView* render_view = GetRenderView();
124   if (!render_view) return;
125
126   WebFrame* webframe = WebFrame::frameForCurrentContext();
127   if (!webframe) return;
128
129   search_provider::InstallState install = search_provider::DENIED;
130   GURL inquiry_url = GURL(name);
131   if (!inquiry_url.is_empty()) {
132       render_view->Send(new ChromeViewHostMsg_GetSearchProviderInstallState(
133           render_view->GetRoutingID(),
134           webframe->document().url(),
135           inquiry_url,
136           &install));
137   }
138
139   if (install == search_provider::DENIED) {
140     // FIXME: throw access denied exception.
141     v8::Isolate* isolate = args.GetIsolate();
142     isolate->ThrowException(v8::Exception::Error(v8::String::Empty(isolate)));
143     return;
144   }
145   args.GetReturnValue().Set(static_cast<int32_t>(install));
146 }
147
148 v8::Extension* ExternalExtension::Get() {
149   return new ExternalExtensionWrapper();
150 }
151
152 }  // namespace extensions_v8