blob: bbfd2f6b90edb872edabb62abdf811c8597a2d5b [file] [log] [blame]
[email protected]f55c90ee62014-04-12 00:50:031// Copyright 2014 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 EXTENSIONS_RENDERER_SCRIPT_CONTEXT_H_
6#define EXTENSIONS_RENDERER_SCRIPT_CONTEXT_H_
7
8#include <string>
dchenge59eca1602015-12-18 17:48:009#include <utility>
kalmanb0c1c502015-04-15 00:25:0610#include <vector>
[email protected]f55c90ee62014-04-12 00:50:0311
kalmanb0c1c502015-04-15 00:25:0612#include "base/callback.h"
[email protected]f55c90ee62014-04-12 00:50:0313#include "base/compiler_specific.h"
avi2d124c02015-12-23 06:36:4214#include "base/macros.h"
kalman04755302015-09-14 18:52:1115#include "base/threading/thread_checker.h"
[email protected]f55c90ee62014-04-12 00:50:0316#include "extensions/common/features/feature.h"
rockote261b162014-12-12 01:59:4717#include "extensions/common/permissions/api_permission_set.h"
[email protected]f55c90ee62014-04-12 00:50:0318#include "extensions/renderer/module_system.h"
19#include "extensions/renderer/request_sender.h"
kalman33076cb2015-08-11 19:12:0720#include "extensions/renderer/safe_builtins.h"
[email protected]d9f51dad2014-07-09 05:39:3821#include "gin/runner.h"
Sadrul Habib Chowdhury0d7ef9f2014-12-03 20:07:3022#include "url/gurl.h"
[email protected]f55c90ee62014-04-12 00:50:0323#include "v8/include/v8.h"
24
25namespace blink {
26class WebFrame;
kalmanf91cb892015-04-15 19:20:4827class WebLocalFrame;
[email protected]f55c90ee62014-04-12 00:50:0328}
29
30namespace content {
[email protected]2101c4c2014-08-22 00:16:1631class RenderFrame;
[email protected]f55c90ee62014-04-12 00:50:0332}
33
34namespace extensions {
35class Extension;
36
kalman04755302015-09-14 18:52:1137// Extensions wrapper for a v8::Context.
38//
39// v8::Contexts can be constructed on any thread, and must only be accessed or
40// destroyed that thread.
41//
42// Note that ScriptContexts bound to worker threads will not have the full
43// functionality as those bound to the main RenderThread.
sammcde54a47e2015-01-13 23:16:3444class ScriptContext : public RequestSender::Source {
[email protected]f55c90ee62014-04-12 00:50:0345 public:
annekao533482222015-08-21 23:23:5346 using RunScriptExceptionHandler = base::Callback<void(const v8::TryCatch&)>;
47
tfarinaf85316f2015-04-29 17:03:4048 ScriptContext(const v8::Local<v8::Context>& context,
kalmanf91cb892015-04-15 19:20:4849 blink::WebLocalFrame* frame,
[email protected]f55c90ee62014-04-12 00:50:0350 const Extension* extension,
mek7e1d7452014-09-08 23:55:5751 Feature::Context context_type,
52 const Extension* effective_extension,
53 Feature::Context effective_context_type);
dcheng9168b2f2014-10-21 12:38:2454 ~ScriptContext() override;
[email protected]f55c90ee62014-04-12 00:50:0355
kalmanc81508d2015-04-23 17:14:0256 // Returns whether |url| from any Extension in |extension_set| is sandboxed,
57 // as declared in each Extension's manifest.
58 // TODO(kalman): Delete this when crbug.com/466373 is fixed.
59 // See comment in HasAccessOrThrowError.
annekao6572d5c2015-08-19 16:13:3660 static bool IsSandboxedPage(const GURL& url);
kalmanf91cb892015-04-15 19:20:4861
[email protected]f55c90ee62014-04-12 00:50:0362 // Clears the WebFrame for this contexts and invalidates the associated
63 // ModuleSystem.
64 void Invalidate();
65
kalmanb0c1c502015-04-15 00:25:0666 // Registers |observer| to be run when this context is invalidated. Closures
67 // are run immediately when Invalidate() is called, not in a message loop.
68 void AddInvalidationObserver(const base::Closure& observer);
69
[email protected]f55c90ee62014-04-12 00:50:0370 // Returns true if this context is still valid, false if it isn't.
71 // A context becomes invalid via Invalidate().
kalmanb0c1c502015-04-15 00:25:0672 bool is_valid() const { return is_valid_; }
[email protected]f55c90ee62014-04-12 00:50:0373
tfarinaf85316f2015-04-29 17:03:4074 v8::Local<v8::Context> v8_context() const {
kalman078a2192015-03-09 18:19:3975 return v8::Local<v8::Context>::New(isolate_, v8_context_);
[email protected]f55c90ee62014-04-12 00:50:0376 }
77
78 const Extension* extension() const { return extension_.get(); }
79
mek7e1d7452014-09-08 23:55:5780 const Extension* effective_extension() const {
81 return effective_extension_.get();
82 }
83
kalmanf91cb892015-04-15 19:20:4884 blink::WebLocalFrame* web_frame() const { return web_frame_; }
[email protected]f55c90ee62014-04-12 00:50:0385
86 Feature::Context context_type() const { return context_type_; }
87
mek7e1d7452014-09-08 23:55:5788 Feature::Context effective_context_type() const {
89 return effective_context_type_;
90 }
91
dchengf6f80662016-04-20 20:26:0492 void set_module_system(std::unique_ptr<ModuleSystem> module_system) {
dchenge59eca1602015-12-18 17:48:0093 module_system_ = std::move(module_system);
[email protected]f55c90ee62014-04-12 00:50:0394 }
95
96 ModuleSystem* module_system() { return module_system_.get(); }
97
kalman33076cb2015-08-11 19:12:0798 SafeBuiltins* safe_builtins() { return &safe_builtins_; }
[email protected]f55c90ee62014-04-12 00:50:0399
kalman33076cb2015-08-11 19:12:07100 const SafeBuiltins* safe_builtins() const { return &safe_builtins_; }
[email protected]f55c90ee62014-04-12 00:50:03101
102 // Returns the ID of the extension associated with this context, or empty
103 // string if there is no such extension.
[email protected]800f9872014-06-12 04:12:51104 const std::string& GetExtensionID() const;
[email protected]f55c90ee62014-04-12 00:50:03105
[email protected]2101c4c2014-08-22 00:16:16106 // Returns the RenderFrame associated with this context. Can return NULL if
107 // the context is in the process of being destroyed.
108 content::RenderFrame* GetRenderFrame() const;
109
[email protected]f55c90ee62014-04-12 00:50:03110 // Runs |function| with appropriate scopes. Doesn't catch exceptions, callers
111 // must do that if they want.
112 //
113 // USE THIS METHOD RATHER THAN v8::Function::Call WHEREVER POSSIBLE.
kalman70c00e242015-05-15 23:42:27114 v8::Local<v8::Value> CallFunction(const v8::Local<v8::Function>& function,
[email protected]f55c90ee62014-04-12 00:50:03115 int argc,
tfarinaf85316f2015-04-29 17:03:40116 v8::Local<v8::Value> argv[]) const;
kalman70c00e242015-05-15 23:42:27117 v8::Local<v8::Value> CallFunction(
118 const v8::Local<v8::Function>& function) const;
[email protected]f55c90ee62014-04-12 00:50:03119
tfarinaf85316f2015-04-29 17:03:40120 void DispatchEvent(const char* event_name, v8::Local<v8::Array> args) const;
[email protected]f55c90ee62014-04-12 00:50:03121
[email protected]f55c90ee62014-04-12 00:50:03122 // Returns the availability of the API |api_name|.
123 Feature::Availability GetAvailability(const std::string& api_name);
124
125 // Returns a string description of the type of context this is.
kalman8bcbc7592015-06-03 23:12:27126 std::string GetContextTypeDescription() const;
[email protected]f55c90ee62014-04-12 00:50:03127
mek7e1d7452014-09-08 23:55:57128 // Returns a string description of the effective type of context this is.
kalman8bcbc7592015-06-03 23:12:27129 std::string GetEffectiveContextTypeDescription() const;
mek7e1d7452014-09-08 23:55:57130
[email protected]f55c90ee62014-04-12 00:50:03131 v8::Isolate* isolate() const { return isolate_; }
132
133 // Get the URL of this context's web frame.
kalmanf91cb892015-04-15 19:20:48134 //
135 // TODO(kalman): Remove this and replace with a GetOrigin() call which reads
Dana Jansens71331252016-03-09 20:57:22136 // of WebDocument::getSecurityOrigin():
kalmanf91cb892015-04-15 19:20:48137 // - The URL can change (e.g. pushState) but the origin cannot. Luckily it
138 // appears as though callers don't make security decisions based on the
kalman04755302015-09-14 18:52:11139 // result of url() so it's not a problem... yet.
kalmanf91cb892015-04-15 19:20:48140 // - Origin is the correct check to be making.
141 // - It might let us remove the about:blank resolving?
kalman04755302015-09-14 18:52:11142 const GURL& url() const { return url_; }
143
144 // Sets the URL of this ScriptContext. Usually this will automatically be set
145 // on construction, unless this isn't constructed with enough information to
146 // determine the URL (e.g. frame was null).
147 // TODO(kalman): Make this a constructor parameter (as an origin).
148 void set_url(const GURL& url) { url_ = url; }
[email protected]f55c90ee62014-04-12 00:50:03149
150 // Returns whether the API |api| or any part of the API could be
151 // available in this context without taking into account the context's
152 // extension.
153 bool IsAnyFeatureAvailableToContext(const extensions::Feature& api);
154
155 // Utility to get the URL we will match against for a frame. If the frame has
156 // committed, this is the commited URL. Otherwise it is the provisional URL.
[email protected]c1abb3232014-07-30 18:28:39157 // The returned URL may be invalid.
[email protected]f55c90ee62014-04-12 00:50:03158 static GURL GetDataSourceURLForFrame(const blink::WebFrame* frame);
159
[email protected]ae26b282014-05-15 16:40:16160 // Returns the first non-about:-URL in the document hierarchy above and
161 // including |frame|. The document hierarchy is only traversed if
162 // |document_url| is an about:-URL and if |match_about_blank| is true.
163 static GURL GetEffectiveDocumentURL(const blink::WebFrame* frame,
164 const GURL& document_url,
165 bool match_about_blank);
166
[email protected]f55c90ee62014-04-12 00:50:03167 // RequestSender::Source implementation.
dcheng9168b2f2014-10-21 12:38:24168 ScriptContext* GetContext() override;
169 void OnResponseReceived(const std::string& name,
170 int request_id,
171 bool success,
172 const base::ListValue& response,
173 const std::string& error) override;
[email protected]f55c90ee62014-04-12 00:50:03174
rockote261b162014-12-12 01:59:47175 // Grants a set of content capabilities to this context.
kalman04755302015-09-14 18:52:11176 void set_content_capabilities(const APIPermissionSet& capabilities) {
177 content_capabilities_ = capabilities;
178 }
rockote261b162014-12-12 01:59:47179
180 // Indicates if this context has an effective API permission either by being
181 // a context for an extension which has that permission, or by being a web
182 // context which has been granted the corresponding capability by an
183 // extension.
184 bool HasAPIPermission(APIPermission::ID permission) const;
185
kalmanc81508d2015-04-23 17:14:02186 // Throws an Error in this context's JavaScript context, if this context does
187 // not have access to |name|. Returns true if this context has access (i.e.
188 // no exception thrown), false if it does not (i.e. an exception was thrown).
189 bool HasAccessOrThrowError(const std::string& name);
190
kalman8bcbc7592015-06-03 23:12:27191 // Returns a string representation of this ScriptContext, for debugging.
192 std::string GetDebugString() const;
193
dmazzonid6848287c2015-07-27 23:41:31194 // Gets the current stack trace as a multi-line string to be logged.
195 std::string GetStackTraceAsString() const;
196
annekao533482222015-08-21 23:23:53197 // Runs |code|, labelling the script that gets created as |name| (the name is
198 // used in the devtools and stack traces). |exception_handler| will be called
199 // re-entrantly if an exception is thrown during the script's execution.
200 v8::Local<v8::Value> RunScript(
201 v8::Local<v8::String> name,
202 v8::Local<v8::String> code,
203 const RunScriptExceptionHandler& exception_handler);
204
mlamouri60a2857d2015-04-14 15:22:36205 private:
206 class Runner;
207
kalmanb0c1c502015-04-15 00:25:06208 // Whether this context is valid.
209 bool is_valid_;
210
211 // The v8 context the bindings are accessible to.
212 v8::Global<v8::Context> v8_context_;
213
kalmanf91cb892015-04-15 19:20:48214 // The WebLocalFrame associated with this context. This can be NULL because
215 // this object can outlive is destroyed asynchronously.
216 blink::WebLocalFrame* web_frame_;
[email protected]f55c90ee62014-04-12 00:50:03217
218 // The extension associated with this context, or NULL if there is none. This
219 // might be a hosted app in the case that this context is hosting a web URL.
220 scoped_refptr<const Extension> extension_;
221
222 // The type of context.
223 Feature::Context context_type_;
224
mek7e1d7452014-09-08 23:55:57225 // The effective extension associated with this context, or NULL if there is
226 // none. This is different from the above extension if this context is in an
227 // about:blank iframe for example.
228 scoped_refptr<const Extension> effective_extension_;
229
230 // The type of context.
231 Feature::Context effective_context_type_;
232
[email protected]f55c90ee62014-04-12 00:50:03233 // Owns and structures the JS that is injected to set up extension bindings.
dchengf6f80662016-04-20 20:26:04234 std::unique_ptr<ModuleSystem> module_system_;
[email protected]f55c90ee62014-04-12 00:50:03235
236 // Contains safe copies of builtin objects like Function.prototype.
kalman33076cb2015-08-11 19:12:07237 SafeBuiltins safe_builtins_;
[email protected]f55c90ee62014-04-12 00:50:03238
rockote261b162014-12-12 01:59:47239 // The set of capabilities granted to this context by extensions.
240 APIPermissionSet content_capabilities_;
241
kalmanb0c1c502015-04-15 00:25:06242 // A list of base::Closure instances as an observer interface for
243 // invalidation.
244 std::vector<base::Closure> invalidate_observers_;
245
[email protected]f55c90ee62014-04-12 00:50:03246 v8::Isolate* isolate_;
247
Sadrul Habib Chowdhury0d7ef9f2014-12-03 20:07:30248 GURL url_;
249
dchengf6f80662016-04-20 20:26:04250 std::unique_ptr<Runner> runner_;
sammcde54a47e2015-01-13 23:16:34251
kalman04755302015-09-14 18:52:11252 base::ThreadChecker thread_checker_;
253
[email protected]f55c90ee62014-04-12 00:50:03254 DISALLOW_COPY_AND_ASSIGN(ScriptContext);
255};
256
257} // namespace extensions
258
259#endif // EXTENSIONS_RENDERER_SCRIPT_CONTEXT_H_