Revert 264226 "Reduce dependency of TiclInvalidationService on P..."
[chromium-blink-merge.git] / extensions / browser / extension_function.cc
blobed33a8fbcdc5c15f1fdbcdd6e7f1bb5fb0898c6a
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;
25 // static
26 void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) {
27 x->Destruct();
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 {
35 public:
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())),
42 function_(function) {
45 private:
46 // content::WebContentsObserver:
47 virtual void RenderViewDeleted(
48 content::RenderViewHost* render_view_host) OVERRIDE {
49 if (render_view_host != function_->render_view_host())
50 return;
52 function_->SetRenderViewHost(NULL);
54 virtual void RenderFrameDeleted(
55 content::RenderFrameHost* render_frame_host) OVERRIDE {
56 if (render_frame_host != function_->render_frame_host())
57 return;
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()
72 : request_id_(-1),
73 profile_id_(NULL),
74 has_callback_(false),
75 include_incognito_(false),
76 user_gesture_(false),
77 bad_message_(false),
78 histogram_value_(extensions::functions::UNKNOWN),
79 source_tab_id_(-1) {
82 ExtensionFunction::~ExtensionFunction() {
85 UIThreadExtensionFunction* ExtensionFunction::AsUIThreadExtensionFunction() {
86 return NULL;
89 IOThreadExtensionFunction* ExtensionFunction::AsIOThreadExtensionFunction() {
90 return NULL;
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;
102 SendResponse(false);
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() {
120 return error_;
123 void ExtensionFunction::SetError(const std::string& error) {
124 error_ = error;
127 void ExtensionFunction::Run() {
128 if (!RunImpl())
129 SendResponse(false);
132 bool ExtensionFunction::ShouldSkipQuotaLimiting() const {
133 return false;
136 bool ExtensionFunction::HasOptionalArgument(size_t index) {
137 base::Value* value;
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;
145 if (bad_message_) {
146 type = BAD_MESSAGE;
147 LOG(ERROR) << "Bad extension message " << name_;
150 // If results were never set, we send an empty argument list.
151 if (!results_)
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),
160 context_(NULL),
161 delegate_(NULL) {
164 UIThreadExtensionFunction::~UIThreadExtensionFunction() {
165 if (dispatcher() && render_view_host())
166 dispatcher()->OnExtensionFunctionCompleted(GetExtension());
169 UIThreadExtensionFunction*
170 UIThreadExtensionFunction::AsUIThreadExtensionFunction() {
171 return this;
174 bool UIThreadExtensionFunction::OnMessageReceived(const IPC::Message& message) {
175 return false;
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;
198 if (dispatcher())
199 web_contents = dispatcher()->delegate()->GetAssociatedWebContents();
201 return web_contents;
204 void UIThreadExtensionFunction::SendResponse(bool success) {
205 if (delegate_)
206 delegate_->OnSendResponse(this, success, bad_message_);
207 else
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));
217 } else {
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() {
232 return this;
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());