Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / extension_function.cc
1 // Copyright 2013 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 "extensions/browser/extension_function.h"
6
7 #include "base/logging.h"
8 #include "base/metrics/sparse_histogram.h"
9 #include "chrome/browser/extensions/extension_function_dispatcher.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
12 #include "chrome/common/extensions/extension_messages.h"
13 #include "content/public/browser/notification_source.h"
14 #include "content/public/browser/notification_types.h"
15 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/render_view_host.h"
17 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_observer.h"
19 #include "extensions/common/extension_api.h"
20
21 using content::BrowserThread;
22 using content::RenderViewHost;
23 using content::WebContents;
24 using extensions::ExtensionAPI;
25 using extensions::Feature;
26
27 // static
28 void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) {
29   x->Destruct();
30 }
31
32 // Helper class to track the lifetime of ExtensionFunction's RenderViewHost or
33 // RenderFrameHost  pointer and NULL it out when it dies. It also allows us to
34 // filter IPC messages coming from the RenderViewHost/RenderFrameHost.
35 class UIThreadExtensionFunction::RenderHostTracker
36     : public content::WebContentsObserver {
37  public:
38   explicit RenderHostTracker(UIThreadExtensionFunction* function)
39       : content::WebContentsObserver(
40             function->render_view_host() ?
41                 WebContents::FromRenderViewHost(function->render_view_host()) :
42                 WebContents::FromRenderFrameHost(
43                     function->render_frame_host())),
44         function_(function) {
45   }
46
47  private:
48   // content::WebContentsObserver:
49   virtual void RenderViewDeleted(
50       content::RenderViewHost* render_view_host) OVERRIDE {
51     if (render_view_host != function_->render_view_host())
52       return;
53
54     function_->SetRenderViewHost(NULL);
55   }
56   virtual void RenderFrameDeleted(
57       content::RenderFrameHost* render_frame_host) OVERRIDE {
58     if (render_frame_host != function_->render_frame_host())
59       return;
60
61     function_->SetRenderFrameHost(NULL);
62   }
63
64   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
65     return function_->OnMessageReceived(message);
66   }
67
68   UIThreadExtensionFunction* function_;
69
70   DISALLOW_COPY_AND_ASSIGN(RenderHostTracker);
71 };
72
73 ExtensionFunction::ExtensionFunction()
74     : request_id_(-1),
75       profile_id_(NULL),
76       has_callback_(false),
77       include_incognito_(false),
78       user_gesture_(false),
79       bad_message_(false),
80       histogram_value_(extensions::functions::UNKNOWN),
81       source_tab_id_(-1) {
82 }
83
84 ExtensionFunction::~ExtensionFunction() {
85 }
86
87 UIThreadExtensionFunction* ExtensionFunction::AsUIThreadExtensionFunction() {
88   return NULL;
89 }
90
91 IOThreadExtensionFunction* ExtensionFunction::AsIOThreadExtensionFunction() {
92   return NULL;
93 }
94
95 bool ExtensionFunction::HasPermission() {
96   Feature::Availability availability =
97       ExtensionAPI::GetSharedInstance()->IsAvailable(
98           name_, extension_, Feature::BLESSED_EXTENSION_CONTEXT, source_url());
99   return availability.is_available();
100 }
101
102 void ExtensionFunction::OnQuotaExceeded(const std::string& violation_error) {
103   error_ = violation_error;
104   SendResponse(false);
105 }
106
107 void ExtensionFunction::SetArgs(const base::ListValue* args) {
108   DCHECK(!args_.get());  // Should only be called once.
109   args_.reset(args->DeepCopy());
110 }
111
112 void ExtensionFunction::SetResult(base::Value* result) {
113   results_.reset(new base::ListValue());
114   results_->Append(result);
115 }
116
117 const base::ListValue* ExtensionFunction::GetResultList() {
118   return results_.get();
119 }
120
121 const std::string ExtensionFunction::GetError() {
122   return error_;
123 }
124
125 void ExtensionFunction::SetError(const std::string& error) {
126   error_ = error;
127 }
128
129 void ExtensionFunction::Run() {
130   UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls", histogram_value());
131
132   if (!RunImpl())
133     SendResponse(false);
134 }
135
136 bool ExtensionFunction::ShouldSkipQuotaLimiting() const {
137   return false;
138 }
139
140 bool ExtensionFunction::HasOptionalArgument(size_t index) {
141   base::Value* value;
142   return args_->Get(index, &value) && !value->IsType(base::Value::TYPE_NULL);
143 }
144
145 void ExtensionFunction::SendResponseImpl(bool success) {
146   DCHECK(!response_callback_.is_null());
147
148   ResponseType type = success ? SUCCEEDED : FAILED;
149   if (bad_message_) {
150     type = BAD_MESSAGE;
151     LOG(ERROR) << "Bad extension message " << name_;
152   }
153
154   // If results were never set, we send an empty argument list.
155   if (!results_)
156     results_.reset(new base::ListValue());
157
158   response_callback_.Run(type, *results_, GetError());
159 }
160
161 UIThreadExtensionFunction::UIThreadExtensionFunction()
162     : render_view_host_(NULL),
163       render_frame_host_(NULL),
164       context_(NULL),
165       delegate_(NULL) {
166 }
167
168 UIThreadExtensionFunction::~UIThreadExtensionFunction() {
169   if (dispatcher() && render_view_host())
170     dispatcher()->OnExtensionFunctionCompleted(GetExtension());
171 }
172
173 UIThreadExtensionFunction*
174 UIThreadExtensionFunction::AsUIThreadExtensionFunction() {
175   return this;
176 }
177
178 bool UIThreadExtensionFunction::OnMessageReceived(const IPC::Message& message) {
179   return false;
180 }
181
182 void UIThreadExtensionFunction::Destruct() const {
183   BrowserThread::DeleteOnUIThread::Destruct(this);
184 }
185
186 void UIThreadExtensionFunction::SetRenderViewHost(
187     RenderViewHost* render_view_host) {
188   DCHECK(!render_frame_host_);
189   render_view_host_ = render_view_host;
190   tracker_.reset(render_view_host ? new RenderHostTracker(this) : NULL);
191 }
192
193 void UIThreadExtensionFunction::SetRenderFrameHost(
194     content::RenderFrameHost* render_frame_host) {
195   DCHECK(!render_view_host_);
196   render_frame_host_ = render_frame_host;
197   tracker_.reset(render_frame_host ? new RenderHostTracker(this) : NULL);
198 }
199
200 content::WebContents* UIThreadExtensionFunction::GetAssociatedWebContents() {
201   content::WebContents* web_contents = NULL;
202   if (dispatcher())
203     web_contents = dispatcher()->delegate()->GetAssociatedWebContents();
204
205   return web_contents;
206 }
207
208 void UIThreadExtensionFunction::SendResponse(bool success) {
209   if (delegate_)
210     delegate_->OnSendResponse(this, success, bad_message_);
211   else
212     SendResponseImpl(success);
213 }
214
215 void UIThreadExtensionFunction::WriteToConsole(
216     content::ConsoleMessageLevel level,
217     const std::string& message) {
218   if (render_view_host_) {
219     render_view_host_->Send(new ExtensionMsg_AddMessageToConsole(
220         render_view_host_->GetRoutingID(), level, message));
221   } else {
222     render_frame_host_->Send(new ExtensionMsg_AddMessageToConsole(
223         render_frame_host_->GetRoutingID(), level, message));
224   }
225 }
226
227 IOThreadExtensionFunction::IOThreadExtensionFunction()
228     : routing_id_(MSG_ROUTING_NONE) {
229 }
230
231 IOThreadExtensionFunction::~IOThreadExtensionFunction() {
232 }
233
234 IOThreadExtensionFunction*
235 IOThreadExtensionFunction::AsIOThreadExtensionFunction() {
236   return this;
237 }
238
239 void IOThreadExtensionFunction::Destruct() const {
240   BrowserThread::DeleteOnIOThread::Destruct(this);
241 }
242
243 void IOThreadExtensionFunction::SendResponse(bool success) {
244   SendResponseImpl(success);
245 }
246
247 AsyncExtensionFunction::AsyncExtensionFunction() {
248 }
249
250 AsyncExtensionFunction::~AsyncExtensionFunction() {
251 }
252
253 SyncExtensionFunction::SyncExtensionFunction() {
254 }
255
256 SyncExtensionFunction::~SyncExtensionFunction() {
257 }
258
259 void SyncExtensionFunction::Run() {
260   SendResponse(RunImpl());
261 }
262
263 SyncIOThreadExtensionFunction::SyncIOThreadExtensionFunction() {
264 }
265
266 SyncIOThreadExtensionFunction::~SyncIOThreadExtensionFunction() {
267 }
268
269 void SyncIOThreadExtensionFunction::Run() {
270   SendResponse(RunImpl());
271 }