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.
5 #include "extensions/browser/extension_function.h"
7 #include "base/logging.h"
8 #include "content/public/browser/notification_source.h"
9 #include "content/public/browser/notification_types.h"
10 #include "content/public/browser/render_frame_host.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/web_contents.h"
13 #include "content/public/browser/web_contents_observer.h"
14 #include "extensions/browser/extension_function_dispatcher.h"
15 #include "extensions/browser/extension_message_filter.h"
16 #include "extensions/common/extension_api.h"
17 #include "extensions/common/extension_messages.h"
19 using content::BrowserThread
;
20 using content::RenderViewHost
;
21 using content::WebContents
;
22 using extensions::ExtensionAPI
;
23 using extensions::Feature
;
26 void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction
* x
) {
30 // Helper class to track the lifetime of ExtensionFunction's RenderViewHost or
31 // RenderFrameHost pointer and NULL it out when it dies. It also allows us to
32 // filter IPC messages coming from the RenderViewHost/RenderFrameHost.
33 class UIThreadExtensionFunction::RenderHostTracker
34 : public content::WebContentsObserver
{
36 explicit RenderHostTracker(UIThreadExtensionFunction
* function
)
37 : content::WebContentsObserver(
38 function
->render_view_host() ?
39 WebContents::FromRenderViewHost(function
->render_view_host()) :
40 WebContents::FromRenderFrameHost(
41 function
->render_frame_host())),
46 // content::WebContentsObserver:
47 virtual void RenderViewDeleted(
48 content::RenderViewHost
* render_view_host
) OVERRIDE
{
49 if (render_view_host
!= function_
->render_view_host())
52 function_
->SetRenderViewHost(NULL
);
54 virtual void RenderFrameDeleted(
55 content::RenderFrameHost
* render_frame_host
) OVERRIDE
{
56 if (render_frame_host
!= function_
->render_frame_host())
59 function_
->SetRenderFrameHost(NULL
);
62 virtual bool OnMessageReceived(const IPC::Message
& message
) OVERRIDE
{
63 return function_
->OnMessageReceived(message
);
66 UIThreadExtensionFunction
* function_
;
68 DISALLOW_COPY_AND_ASSIGN(RenderHostTracker
);
71 ExtensionFunction::ExtensionFunction()
75 include_incognito_(false),
78 histogram_value_(extensions::functions::UNKNOWN
),
82 ExtensionFunction::~ExtensionFunction() {
85 UIThreadExtensionFunction
* ExtensionFunction::AsUIThreadExtensionFunction() {
89 IOThreadExtensionFunction
* ExtensionFunction::AsIOThreadExtensionFunction() {
93 bool ExtensionFunction::HasPermission() {
94 Feature::Availability availability
=
95 ExtensionAPI::GetSharedInstance()->IsAvailable(
96 name_
, extension_
, Feature::BLESSED_EXTENSION_CONTEXT
, source_url());
97 return availability
.is_available();
100 void ExtensionFunction::OnQuotaExceeded(const std::string
& violation_error
) {
101 error_
= violation_error
;
105 void ExtensionFunction::SetArgs(const base::ListValue
* args
) {
106 DCHECK(!args_
.get()); // Should only be called once.
107 args_
.reset(args
->DeepCopy());
110 void ExtensionFunction::SetResult(base::Value
* result
) {
111 results_
.reset(new base::ListValue());
112 results_
->Append(result
);
115 const base::ListValue
* ExtensionFunction::GetResultList() {
116 return results_
.get();
119 const std::string
ExtensionFunction::GetError() {
123 void ExtensionFunction::SetError(const std::string
& error
) {
127 void ExtensionFunction::Run() {
132 bool ExtensionFunction::ShouldSkipQuotaLimiting() const {
136 bool ExtensionFunction::HasOptionalArgument(size_t index
) {
138 return args_
->Get(index
, &value
) && !value
->IsType(base::Value::TYPE_NULL
);
141 void ExtensionFunction::SendResponseImpl(bool success
) {
142 DCHECK(!response_callback_
.is_null());
144 ResponseType type
= success
? SUCCEEDED
: FAILED
;
147 LOG(ERROR
) << "Bad extension message " << name_
;
150 // If results were never set, we send an empty argument list.
152 results_
.reset(new base::ListValue());
154 response_callback_
.Run(type
, *results_
, GetError());
157 UIThreadExtensionFunction::UIThreadExtensionFunction()
158 : render_view_host_(NULL
),
159 render_frame_host_(NULL
),
164 UIThreadExtensionFunction::~UIThreadExtensionFunction() {
165 if (dispatcher() && render_view_host())
166 dispatcher()->OnExtensionFunctionCompleted(GetExtension());
169 UIThreadExtensionFunction
*
170 UIThreadExtensionFunction::AsUIThreadExtensionFunction() {
174 bool UIThreadExtensionFunction::OnMessageReceived(const IPC::Message
& message
) {
178 void UIThreadExtensionFunction::Destruct() const {
179 BrowserThread::DeleteOnUIThread::Destruct(this);
182 void UIThreadExtensionFunction::SetRenderViewHost(
183 RenderViewHost
* render_view_host
) {
184 DCHECK(!render_frame_host_
);
185 render_view_host_
= render_view_host
;
186 tracker_
.reset(render_view_host
? new RenderHostTracker(this) : NULL
);
189 void UIThreadExtensionFunction::SetRenderFrameHost(
190 content::RenderFrameHost
* render_frame_host
) {
191 DCHECK(!render_view_host_
);
192 render_frame_host_
= render_frame_host
;
193 tracker_
.reset(render_frame_host
? new RenderHostTracker(this) : NULL
);
196 content::WebContents
* UIThreadExtensionFunction::GetAssociatedWebContents() {
197 content::WebContents
* web_contents
= NULL
;
199 web_contents
= dispatcher()->delegate()->GetAssociatedWebContents();
204 void UIThreadExtensionFunction::SendResponse(bool success
) {
206 delegate_
->OnSendResponse(this, success
, bad_message_
);
208 SendResponseImpl(success
);
211 void UIThreadExtensionFunction::WriteToConsole(
212 content::ConsoleMessageLevel level
,
213 const std::string
& message
) {
214 if (render_view_host_
) {
215 render_view_host_
->Send(new ExtensionMsg_AddMessageToConsole(
216 render_view_host_
->GetRoutingID(), level
, message
));
218 render_frame_host_
->Send(new ExtensionMsg_AddMessageToConsole(
219 render_frame_host_
->GetRoutingID(), level
, message
));
223 IOThreadExtensionFunction::IOThreadExtensionFunction()
224 : routing_id_(MSG_ROUTING_NONE
) {
227 IOThreadExtensionFunction::~IOThreadExtensionFunction() {
230 IOThreadExtensionFunction
*
231 IOThreadExtensionFunction::AsIOThreadExtensionFunction() {
235 void IOThreadExtensionFunction::Destruct() const {
236 BrowserThread::DeleteOnIOThread::Destruct(this);
239 void IOThreadExtensionFunction::SendResponse(bool success
) {
240 SendResponseImpl(success
);
243 AsyncExtensionFunction::AsyncExtensionFunction() {
246 AsyncExtensionFunction::~AsyncExtensionFunction() {
249 SyncExtensionFunction::SyncExtensionFunction() {
252 SyncExtensionFunction::~SyncExtensionFunction() {
255 void SyncExtensionFunction::Run() {
256 SendResponse(RunImpl());
259 SyncIOThreadExtensionFunction::SyncIOThreadExtensionFunction() {
262 SyncIOThreadExtensionFunction::~SyncIOThreadExtensionFunction() {
265 void SyncIOThreadExtensionFunction::Run() {
266 SendResponse(RunImpl());