blob: f63d4fdb242858be289230842e13ded2450e2287 [file] [log] [blame]
[email protected]60aad9c2012-01-13 19:55:321// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]703e807a2009-03-28 19:56:512// 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/browser/extensions/extension_function.h"
6
[email protected]73404a372009-04-17 23:09:107#include "base/logging.h"
[email protected]07ad9622013-01-18 23:00:338#include "base/metrics/histogram.h"
[email protected]703e807a2009-03-28 19:56:519#include "chrome/browser/extensions/extension_function_dispatcher.h"
[email protected]eaa7dd182010-12-14 11:09:0010#include "chrome/browser/extensions/extension_service.h"
[email protected]c357acb42011-06-09 20:52:4211#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
[email protected]b5b26b72013-08-02 00:25:1112#include "chrome/common/extensions/api/extension_api.h"
[email protected]c5dbef02011-05-13 05:06:0913#include "chrome/common/extensions/extension_messages.h"
[email protected]86ab86b2011-10-19 03:07:5514#include "content/public/browser/notification_source.h"
[email protected]0d6e9bd2011-10-18 04:29:1615#include "content/public/browser/notification_types.h"
[email protected]9c1662b2012-03-06 15:44:3316#include "content/public/browser/render_view_host.h"
[email protected]bc0ee242013-10-22 03:46:1417#include "content/public/browser/web_contents.h"
18#include "content/public/browser/web_contents_observer.h"
[email protected]c5dbef02011-05-13 05:06:0919
[email protected]631bb742011-11-02 11:29:3920using content::BrowserThread;
[email protected]eaabba22012-03-07 15:02:1121using content::RenderViewHost;
[email protected]bc0ee242013-10-22 03:46:1422using content::WebContents;
[email protected]b5b26b72013-08-02 00:25:1123using extensions::ExtensionAPI;
24using extensions::Feature;
[email protected]631bb742011-11-02 11:29:3925
[email protected]a2aef2e2011-05-26 22:48:1226// static
27void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) {
28 x->Destruct();
29}
30
[email protected]bc0ee242013-10-22 03:46:1431// Helper class to track the lifetime of ExtensionFunction's RenderViewHost
32// pointer and NULL it out when it dies. It also allows us to filter IPC
33// messages coming from the RenderViewHost.
34class UIThreadExtensionFunction::RenderViewHostTracker
35 : public content::WebContentsObserver {
36 public:
37 explicit RenderViewHostTracker(UIThreadExtensionFunction* function)
38 : content::WebContentsObserver(
39 WebContents::FromRenderViewHost(function->render_view_host())),
40 function_(function) {
41 }
[email protected]942690b132010-05-11 06:42:1442
[email protected]bc0ee242013-10-22 03:46:1443 private:
44 // content::WebContentsObserver:
45 virtual void RenderViewDeleted(
46 content::RenderViewHost* render_view_host) OVERRIDE {
47 if (render_view_host != function_->render_view_host())
48 return;
[email protected]ce0e2602013-03-15 20:53:2749
[email protected]bc0ee242013-10-22 03:46:1450 function_->SetRenderViewHost(NULL);
51 }
[email protected]0f7daaa2011-11-22 18:34:5652
[email protected]bc0ee242013-10-22 03:46:1453 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
54 return function_->OnMessageReceivedFromRenderView(message);
55 }
56
57 UIThreadExtensionFunction* function_;
58
59 DISALLOW_COPY_AND_ASSIGN(RenderViewHostTracker);
60};
[email protected]0f7daaa2011-11-22 18:34:5661
[email protected]3a3d47472010-07-15 21:03:5462ExtensionFunction::ExtensionFunction()
[email protected]9931fbfc2010-07-23 09:15:5163 : request_id_(-1),
[email protected]637bf322011-10-01 20:46:3264 profile_id_(NULL),
[email protected]9931fbfc2010-07-23 09:15:5165 has_callback_(false),
[email protected]6451e332010-10-05 00:14:5366 include_incognito_(false),
[email protected]a2aef2e2011-05-26 22:48:1267 user_gesture_(false),
[email protected]07ad9622013-01-18 23:00:3368 bad_message_(false),
[email protected]4b4c0132013-06-12 17:58:5569 histogram_value_(extensions::functions::UNKNOWN) {}
[email protected]3a3d47472010-07-15 21:03:5470
71ExtensionFunction::~ExtensionFunction() {
72}
73
[email protected]2ad65b32011-05-26 23:39:2074UIThreadExtensionFunction* ExtensionFunction::AsUIThreadExtensionFunction() {
75 return NULL;
76}
77
[email protected]c357acb42011-06-09 20:52:4278IOThreadExtensionFunction* ExtensionFunction::AsIOThreadExtensionFunction() {
79 return NULL;
80}
81
[email protected]3d0e2262012-08-02 15:32:1682bool ExtensionFunction::HasPermission() {
[email protected]b5b26b72013-08-02 00:25:1183 Feature::Availability availability =
84 ExtensionAPI::GetSharedInstance()->IsAvailable(
85 name_, extension_, Feature::BLESSED_EXTENSION_CONTEXT, source_url());
86 return availability.is_available();
[email protected]3d0e2262012-08-02 15:32:1687}
88
[email protected]85231d72012-08-31 09:45:2989void ExtensionFunction::OnQuotaExceeded(const std::string& violation_error) {
90 error_ = violation_error;
[email protected]fd50e7b2011-11-03 09:20:2591 SendResponse(false);
92}
93
[email protected]602542d2012-04-20 02:48:0194void ExtensionFunction::SetArgs(const base::ListValue* args) {
[email protected]30294edf2009-11-10 00:24:3895 DCHECK(!args_.get()); // Should only be called once.
[email protected]16f47e082011-01-18 02:16:5996 args_.reset(args->DeepCopy());
[email protected]b83e4602009-05-15 22:58:3397}
98
[email protected]07ff5fd2012-07-12 22:39:0999void ExtensionFunction::SetResult(base::Value* result) {
100 results_.reset(new base::ListValue());
101 results_->Append(result);
102}
103
[email protected]aeca23f2013-06-21 22:34:41104const base::ListValue* ExtensionFunction::GetResultList() {
[email protected]07ff5fd2012-07-12 22:39:09105 return results_.get();
[email protected]637bf322011-10-01 20:46:32106}
107
[email protected]a2aef2e2011-05-26 22:48:12108const std::string ExtensionFunction::GetError() {
[email protected]3a3d47472010-07-15 21:03:54109 return error_;
110}
111
[email protected]60aad9c2012-01-13 19:55:32112void ExtensionFunction::SetError(const std::string& error) {
113 error_ = error;
114}
115
[email protected]a2aef2e2011-05-26 22:48:12116void ExtensionFunction::Run() {
[email protected]07ad9622013-01-18 23:00:33117 UMA_HISTOGRAM_ENUMERATION("Extensions.FunctionCalls", histogram_value(),
118 extensions::functions::ENUM_BOUNDARY);
119
[email protected]3a3d47472010-07-15 21:03:54120 if (!RunImpl())
121 SendResponse(false);
122}
123
[email protected]712627bf2012-04-30 03:21:04124bool ExtensionFunction::ShouldSkipQuotaLimiting() const {
125 return false;
126}
127
[email protected]a2aef2e2011-05-26 22:48:12128bool ExtensionFunction::HasOptionalArgument(size_t index) {
129 Value* value;
130 return args_->Get(index, &value) && !value->IsType(Value::TYPE_NULL);
131}
132
[email protected]35548ab2013-05-15 08:59:47133void ExtensionFunction::SendResponseImpl(bool success) {
134 DCHECK(!response_callback_.is_null());
135
136 ResponseType type = success ? SUCCEEDED : FAILED;
[email protected]c357acb42011-06-09 20:52:42137 if (bad_message_) {
[email protected]35548ab2013-05-15 08:59:47138 type = BAD_MESSAGE;
139 LOG(ERROR) << "Bad extension message " << name_;
[email protected]c357acb42011-06-09 20:52:42140 }
141
[email protected]07ff5fd2012-07-12 22:39:09142 // If results were never set, we send an empty argument list.
[email protected]3eeddd892013-04-17 17:00:11143 if (!results_)
[email protected]aeca23f2013-06-21 22:34:41144 results_.reset(new base::ListValue());
[email protected]602542d2012-04-20 02:48:01145
[email protected]35548ab2013-05-15 08:59:47146 response_callback_.Run(type, *results_, GetError());
[email protected]c357acb42011-06-09 20:52:42147}
148
[email protected]a2aef2e2011-05-26 22:48:12149UIThreadExtensionFunction::UIThreadExtensionFunction()
[email protected]21a40082013-10-28 21:19:23150 : render_view_host_(NULL), context_(NULL), delegate_(NULL) {}
[email protected]a2aef2e2011-05-26 22:48:12151
152UIThreadExtensionFunction::~UIThreadExtensionFunction() {
[email protected]7042b682012-04-19 22:57:51153 if (dispatcher() && render_view_host())
[email protected]720ad1312012-02-27 23:07:36154 dispatcher()->OnExtensionFunctionCompleted(GetExtension());
[email protected]a2aef2e2011-05-26 22:48:12155}
156
[email protected]2ad65b32011-05-26 23:39:20157UIThreadExtensionFunction*
158UIThreadExtensionFunction::AsUIThreadExtensionFunction() {
159 return this;
160}
161
[email protected]0f7daaa2011-11-22 18:34:56162bool UIThreadExtensionFunction::OnMessageReceivedFromRenderView(
163 const IPC::Message& message) {
164 return false;
165}
166
[email protected]a2aef2e2011-05-26 22:48:12167void UIThreadExtensionFunction::Destruct() const {
168 BrowserThread::DeleteOnUIThread::Destruct(this);
169}
170
171void UIThreadExtensionFunction::SetRenderViewHost(
172 RenderViewHost* render_view_host) {
173 render_view_host_ = render_view_host;
[email protected]ce0e2602013-03-15 20:53:27174 tracker_.reset(render_view_host ? new RenderViewHostTracker(this) : NULL);
[email protected]a2aef2e2011-05-26 22:48:12175}
176
[email protected]91e51d612012-10-21 23:03:05177content::WebContents* UIThreadExtensionFunction::GetAssociatedWebContents() {
[email protected]21a40082013-10-28 21:19:23178 content::WebContents* web_contents = NULL;
179 if (dispatcher())
180 web_contents = dispatcher()->delegate()->GetAssociatedWebContents();
[email protected]91e51d612012-10-21 23:03:05181
[email protected]21a40082013-10-28 21:19:23182 return web_contents;
[email protected]a2aef2e2011-05-26 22:48:12183}
184
185void UIThreadExtensionFunction::SendResponse(bool success) {
[email protected]35548ab2013-05-15 08:59:47186 if (delegate_)
[email protected]ca6df682012-04-10 23:00:20187 delegate_->OnSendResponse(this, success, bad_message_);
[email protected]35548ab2013-05-15 08:59:47188 else
189 SendResponseImpl(success);
[email protected]c5dbef02011-05-13 05:06:09190}
191
[email protected]c6970072013-01-10 02:59:43192void UIThreadExtensionFunction::WriteToConsole(
193 content::ConsoleMessageLevel level,
194 const std::string& message) {
195 render_view_host_->Send(new ExtensionMsg_AddMessageToConsole(
196 render_view_host_->GetRoutingID(), level, message));
197}
198
[email protected]44295a12013-06-05 08:45:46199IOThreadExtensionFunction::IOThreadExtensionFunction()
200 : routing_id_(MSG_ROUTING_NONE) {
[email protected]c357acb42011-06-09 20:52:42201}
202
203IOThreadExtensionFunction::~IOThreadExtensionFunction() {
204}
205
206IOThreadExtensionFunction*
207IOThreadExtensionFunction::AsIOThreadExtensionFunction() {
208 return this;
209}
210
211void IOThreadExtensionFunction::Destruct() const {
212 BrowserThread::DeleteOnIOThread::Destruct(this);
213}
214
215void IOThreadExtensionFunction::SendResponse(bool success) {
[email protected]35548ab2013-05-15 08:59:47216 SendResponseImpl(success);
[email protected]703e807a2009-03-28 19:56:51217}
[email protected]73404a372009-04-17 23:09:10218
[email protected]bdfc03e2011-11-22 00:20:33219AsyncExtensionFunction::AsyncExtensionFunction() {
[email protected]a2aef2e2011-05-26 22:48:12220}
221
222AsyncExtensionFunction::~AsyncExtensionFunction() {
[email protected]35213ce92010-04-08 19:06:15223}
[email protected]3a3d47472010-07-15 21:03:54224
225SyncExtensionFunction::SyncExtensionFunction() {
226}
227
228SyncExtensionFunction::~SyncExtensionFunction() {
229}
230
231void SyncExtensionFunction::Run() {
232 SendResponse(RunImpl());
233}
[email protected]c357acb42011-06-09 20:52:42234
235SyncIOThreadExtensionFunction::SyncIOThreadExtensionFunction() {
236}
237
238SyncIOThreadExtensionFunction::~SyncIOThreadExtensionFunction() {
239}
240
241void SyncIOThreadExtensionFunction::Run() {
242 SendResponse(RunImpl());
243}