Upstream version 5.34.104.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/WebFrame.h"
12 #include "third_party/WebKit/public/web/WebView.h"
13 #include "v8/include/v8.h"
14
15 using blink::WebFrame;
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   virtual 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(
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(*v8::String::Utf8Value(args[0]));
102   if (name.empty()) 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(*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