Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(396)

Side by Side Diff: chrome/browser/extensions/extension_function.h

Issue 64273006: Move ExtensionFunction to the extensions component. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_
7
8 #include <list>
9 #include <string>
10
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/process/process.h"
17 #include "base/sequenced_task_runner_helpers.h"
18 #include "chrome/browser/extensions/extension_function_histogram_value.h"
19 #include "chrome/common/extensions/extension.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/common/console_message_level.h"
22 #include "extensions/browser/info_map.h"
23 #include "ipc/ipc_message.h"
24
25 class ChromeRenderMessageFilter;
26 class ExtensionFunction;
27 class ExtensionFunctionDispatcher;
28 class UIThreadExtensionFunction;
29 class IOThreadExtensionFunction;
30
31 namespace base {
32 class ListValue;
33 class Value;
34 }
35
36 namespace content {
37 class BrowserContext;
38 class RenderViewHost;
39 class WebContents;
40 }
41
42 namespace extensions {
43 class QuotaLimitHeuristic;
44 }
45
46 #ifdef NDEBUG
47 #define EXTENSION_FUNCTION_VALIDATE(test) do { \
48 if (!(test)) { \
49 bad_message_ = true; \
50 return false; \
51 } \
52 } while (0)
53 #else // NDEBUG
54 #define EXTENSION_FUNCTION_VALIDATE(test) CHECK(test)
55 #endif // NDEBUG
56
57 #define EXTENSION_FUNCTION_ERROR(error) do { \
58 error_ = error; \
59 bad_message_ = true; \
60 return false; \
61 } while (0)
62
63 // Declares a callable extension function with the given |name|. You must also
64 // supply a unique |histogramvalue| used for histograms of extension function
65 // invocation (add new ones at the end of the enum in
66 // extension_function_histogram_value.h).
67 #define DECLARE_EXTENSION_FUNCTION(name, histogramvalue) \
68 public: static const char* function_name() { return name; } \
69 public: static extensions::functions::HistogramValue histogram_value() \
70 { return extensions::functions::histogramvalue; }
71
72 // Traits that describe how ExtensionFunction should be deleted. This just calls
73 // the virtual "Destruct" method on ExtensionFunction, allowing derived classes
74 // to override the behavior.
75 struct ExtensionFunctionDeleteTraits {
76 public:
77 static void Destruct(const ExtensionFunction* x);
78 };
79
80 // Abstract base class for extension functions the ExtensionFunctionDispatcher
81 // knows how to dispatch to.
82 class ExtensionFunction
83 : public base::RefCountedThreadSafe<ExtensionFunction,
84 ExtensionFunctionDeleteTraits> {
85 public:
86 enum ResponseType {
87 // The function has succeeded.
88 SUCCEEDED,
89 // The function has failed.
90 FAILED,
91 // The input message is malformed.
92 BAD_MESSAGE
93 };
94
95 typedef base::Callback<void(ResponseType type,
96 const base::ListValue& results,
97 const std::string& error)> ResponseCallback;
98
99 ExtensionFunction();
100
101 virtual UIThreadExtensionFunction* AsUIThreadExtensionFunction();
102 virtual IOThreadExtensionFunction* AsIOThreadExtensionFunction();
103
104 // Returns true if the function has permission to run.
105 //
106 // The default implementation is to check the Extension's permissions against
107 // what this function requires to run, but some APIs may require finer
108 // grained control, such as tabs.executeScript being allowed for active tabs.
109 //
110 // This will be run after the function has been set up but before Run().
111 virtual bool HasPermission();
112
113 // Execute the API. Clients should initialize the ExtensionFunction using
114 // SetArgs(), set_request_id(), and the other setters before calling this
115 // method. Derived classes should be ready to return GetResultList() and
116 // GetError() before returning from this function.
117 // Note that once Run() returns, dispatcher() can be NULL, so be sure to
118 // NULL-check.
119 virtual void Run();
120
121 // Gets whether quota should be applied to this individual function
122 // invocation. This is different to GetQuotaLimitHeuristics which is only
123 // invoked once and then cached.
124 //
125 // Returns false by default.
126 virtual bool ShouldSkipQuotaLimiting() const;
127
128 // Optionally adds one or multiple QuotaLimitHeuristic instances suitable for
129 // this function to |heuristics|. The ownership of the new QuotaLimitHeuristic
130 // instances is passed to the owner of |heuristics|.
131 // No quota limiting by default.
132 //
133 // Only called once per lifetime of the QuotaService.
134 virtual void GetQuotaLimitHeuristics(
135 extensions::QuotaLimitHeuristics* heuristics) const {}
136
137 // Called when the quota limit has been exceeded. The default implementation
138 // returns an error.
139 virtual void OnQuotaExceeded(const std::string& violation_error);
140
141 // Specifies the raw arguments to the function, as a JSON value.
142 virtual void SetArgs(const base::ListValue* args);
143
144 // Sets a single Value as the results of the function.
145 void SetResult(base::Value* result);
146
147 // Retrieves the results of the function as a ListValue.
148 const base::ListValue* GetResultList();
149
150 // Retrieves any error string from the function.
151 virtual const std::string GetError();
152
153 // Sets the function's error string.
154 virtual void SetError(const std::string& error);
155
156 // Specifies the name of the function.
157 void set_name(const std::string& name) { name_ = name; }
158 const std::string& name() const { return name_; }
159
160 void set_profile_id(void* profile_id) { profile_id_ = profile_id; }
161 void* profile_id() const { return profile_id_; }
162
163 void set_extension(const extensions::Extension* extension) {
164 extension_ = extension;
165 }
166 const extensions::Extension* GetExtension() const { return extension_.get(); }
167 const std::string& extension_id() const { return extension_->id(); }
168
169 void set_request_id(int request_id) { request_id_ = request_id; }
170 int request_id() { return request_id_; }
171
172 void set_source_url(const GURL& source_url) { source_url_ = source_url; }
173 const GURL& source_url() { return source_url_; }
174
175 void set_has_callback(bool has_callback) { has_callback_ = has_callback; }
176 bool has_callback() { return has_callback_; }
177
178 void set_include_incognito(bool include) { include_incognito_ = include; }
179 bool include_incognito() const { return include_incognito_; }
180
181 void set_user_gesture(bool user_gesture) { user_gesture_ = user_gesture; }
182 bool user_gesture() const { return user_gesture_; }
183
184 void set_histogram_value(
185 extensions::functions::HistogramValue histogram_value) {
186 histogram_value_ = histogram_value; }
187 extensions::functions::HistogramValue histogram_value() const {
188 return histogram_value_; }
189
190 void set_response_callback(const ResponseCallback& callback) {
191 response_callback_ = callback;
192 }
193
194 protected:
195 friend struct ExtensionFunctionDeleteTraits;
196
197 virtual ~ExtensionFunction();
198
199 // Helper method for ExtensionFunctionDeleteTraits. Deletes this object.
200 virtual void Destruct() const = 0;
201
202 // Derived classes should implement this method to do their work and return
203 // success/failure.
204 virtual bool RunImpl() = 0;
205
206 // Sends the result back to the extension.
207 virtual void SendResponse(bool success) = 0;
208
209 // Common implementation for SendResponse.
210 void SendResponseImpl(bool success);
211
212 // Return true if the argument to this function at |index| was provided and
213 // is non-null.
214 bool HasOptionalArgument(size_t index);
215
216 // Id of this request, used to map the response back to the caller.
217 int request_id_;
218
219 // The id of the profile of this function's extension.
220 void* profile_id_;
221
222 // The extension that called this function.
223 scoped_refptr<const extensions::Extension> extension_;
224
225 // The name of this function.
226 std::string name_;
227
228 // The URL of the frame which is making this request
229 GURL source_url_;
230
231 // True if the js caller provides a callback function to receive the response
232 // of this call.
233 bool has_callback_;
234
235 // True if this callback should include information from incognito contexts
236 // even if our profile_ is non-incognito. Note that in the case of a "split"
237 // mode extension, this will always be false, and we will limit access to
238 // data from within the same profile_ (either incognito or not).
239 bool include_incognito_;
240
241 // True if the call was made in response of user gesture.
242 bool user_gesture_;
243
244 // The arguments to the API. Only non-null if argument were specified.
245 scoped_ptr<base::ListValue> args_;
246
247 // The results of the API. This should be populated by the derived class
248 // before SendResponse() is called.
249 scoped_ptr<base::ListValue> results_;
250
251 // Any detailed error from the API. This should be populated by the derived
252 // class before Run() returns.
253 std::string error_;
254
255 // Any class that gets a malformed message should set this to true before
256 // returning. Usually we want to kill the message sending process.
257 bool bad_message_;
258
259 // The sample value to record with the histogram API when the function
260 // is invoked.
261 extensions::functions::HistogramValue histogram_value_;
262
263 // The callback to run once the function has done execution.
264 ResponseCallback response_callback_;
265
266 DISALLOW_COPY_AND_ASSIGN(ExtensionFunction);
267 };
268
269 // Extension functions that run on the UI thread. Most functions fall into
270 // this category.
271 class UIThreadExtensionFunction : public ExtensionFunction {
272 public:
273 // TODO(yzshen): We should be able to remove this interface now that we
274 // support overriding the response callback.
275 // A delegate for use in testing, to intercept the call to SendResponse.
276 class DelegateForTests {
277 public:
278 virtual void OnSendResponse(UIThreadExtensionFunction* function,
279 bool success,
280 bool bad_message) = 0;
281 };
282
283 UIThreadExtensionFunction();
284
285 virtual UIThreadExtensionFunction* AsUIThreadExtensionFunction() OVERRIDE;
286
287 void set_test_delegate(DelegateForTests* delegate) {
288 delegate_ = delegate;
289 }
290
291 // Called when a message was received.
292 // Should return true if it processed the message.
293 virtual bool OnMessageReceivedFromRenderView(const IPC::Message& message);
294
295 // Set the browser context which contains the extension that has originated
296 // this function call.
297 void set_context(content::BrowserContext* context) { context_ = context; }
298 content::BrowserContext* context() const { return context_; }
299
300 void SetRenderViewHost(content::RenderViewHost* render_view_host);
301 content::RenderViewHost* render_view_host() const {
302 return render_view_host_;
303 }
304
305 void set_dispatcher(
306 const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher) {
307 dispatcher_ = dispatcher;
308 }
309 ExtensionFunctionDispatcher* dispatcher() const {
310 return dispatcher_.get();
311 }
312
313 // Gets the "current" web contents if any. If there is no associated web
314 // contents then defaults to the foremost one.
315 virtual content::WebContents* GetAssociatedWebContents();
316
317 protected:
318 // Emits a message to the extension's devtools console.
319 void WriteToConsole(content::ConsoleMessageLevel level,
320 const std::string& message);
321
322 friend struct content::BrowserThread::DeleteOnThread<
323 content::BrowserThread::UI>;
324 friend class base::DeleteHelper<UIThreadExtensionFunction>;
325
326 virtual ~UIThreadExtensionFunction();
327
328 virtual void SendResponse(bool success) OVERRIDE;
329
330 // The dispatcher that will service this extension function call.
331 base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_;
332
333 // The RenderViewHost we will send responses too.
334 content::RenderViewHost* render_view_host_;
335
336 // The content::BrowserContext of this function's extension.
337 content::BrowserContext* context_;
338
339 private:
340 class RenderViewHostTracker;
341
342 virtual void Destruct() const OVERRIDE;
343
344 scoped_ptr<RenderViewHostTracker> tracker_;
345
346 DelegateForTests* delegate_;
347 };
348
349 // Extension functions that run on the IO thread. This type of function avoids
350 // a roundtrip to and from the UI thread (because communication with the
351 // extension process happens on the IO thread). It's intended to be used when
352 // performance is critical (e.g. the webRequest API which can block network
353 // requests). Generally, UIThreadExtensionFunction is more appropriate and will
354 // be easier to use and interface with the rest of the browser.
355 class IOThreadExtensionFunction : public ExtensionFunction {
356 public:
357 IOThreadExtensionFunction();
358
359 virtual IOThreadExtensionFunction* AsIOThreadExtensionFunction() OVERRIDE;
360
361 void set_ipc_sender(base::WeakPtr<ChromeRenderMessageFilter> ipc_sender,
362 int routing_id) {
363 ipc_sender_ = ipc_sender;
364 routing_id_ = routing_id;
365 }
366
367 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender_weak() const {
368 return ipc_sender_;
369 }
370
371 int routing_id() const { return routing_id_; }
372
373 void set_extension_info_map(const extensions::InfoMap* extension_info_map) {
374 extension_info_map_ = extension_info_map;
375 }
376 const extensions::InfoMap* extension_info_map() const {
377 return extension_info_map_.get();
378 }
379
380 protected:
381 friend struct content::BrowserThread::DeleteOnThread<
382 content::BrowserThread::IO>;
383 friend class base::DeleteHelper<IOThreadExtensionFunction>;
384
385 virtual ~IOThreadExtensionFunction();
386
387 virtual void Destruct() const OVERRIDE;
388
389 virtual void SendResponse(bool success) OVERRIDE;
390
391 private:
392 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender_;
393 int routing_id_;
394
395 scoped_refptr<const extensions::InfoMap> extension_info_map_;
396 };
397
398 // Base class for an extension function that runs asynchronously *relative to
399 // the browser's UI thread*.
400 class AsyncExtensionFunction : public UIThreadExtensionFunction {
401 public:
402 AsyncExtensionFunction();
403
404 protected:
405 virtual ~AsyncExtensionFunction();
406 };
407
408 // A SyncExtensionFunction is an ExtensionFunction that runs synchronously
409 // *relative to the browser's UI thread*. Note that this has nothing to do with
410 // running synchronously relative to the extension process. From the extension
411 // process's point of view, the function is still asynchronous.
412 //
413 // This kind of function is convenient for implementing simple APIs that just
414 // need to interact with things on the browser UI thread.
415 class SyncExtensionFunction : public UIThreadExtensionFunction {
416 public:
417 SyncExtensionFunction();
418
419 virtual void Run() OVERRIDE;
420
421 protected:
422 virtual ~SyncExtensionFunction();
423 };
424
425 class SyncIOThreadExtensionFunction : public IOThreadExtensionFunction {
426 public:
427 SyncIOThreadExtensionFunction();
428
429 virtual void Run() OVERRIDE;
430
431 protected:
432 virtual ~SyncIOThreadExtensionFunction();
433 };
434
435 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_
OLDNEW
« no previous file with comments | « chrome/browser/extensions/chrome_extension_function.h ('k') | chrome/browser/extensions/extension_function.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698