summaryrefslogtreecommitdiffstats
path: root/extensions/renderer/script_context_set.h
blob: ac3cb17840934007023ec4dc66017e54a5e73033 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_RENDERER_SCRIPT_CONTEXT_SET_H_
#define EXTENSIONS_RENDERER_SCRIPT_CONTEXT_SET_H_

#include <set>
#include <string>

#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/features/feature.h"
#include "url/gurl.h"
#include "v8/include/v8.h"

class GURL;

namespace base {
class ListValue;
}

namespace blink {
class WebLocalFrame;
class WebSecurityOrigin;
}

namespace content {
class RenderView;
}

namespace extensions {
class ScriptContext;

// A container of ScriptContexts, responsible for both creating and managing
// them.
//
// Since calling JavaScript within a context can cause any number of contexts
// to be created or destroyed, this has additional smarts to help with the set
// changing underneath callers.
class ScriptContextSet {
 public:
  ScriptContextSet(
      ExtensionSet* extensions,
      // Set of the IDs of extensions that are active in this process.
      // Must outlive this. TODO(kalman): Combine this and |extensions|.
      ExtensionIdSet* active_extension_ids);

  ~ScriptContextSet();

  // Returns the number of contexts being tracked by this set.
  // This may also include invalid contexts. TODO(kalman): Useful?
  size_t size() const { return contexts_.size(); }

  // Creates and starts managing a new ScriptContext. Ownership is held.
  // Returns a weak reference to the new ScriptContext.
  ScriptContext* Register(blink::WebLocalFrame* frame,
                          const v8::Handle<v8::Context>& v8_context,
                          int extension_group,
                          int world_id);

  // If the specified context is contained in this set, remove it, then delete
  // it asynchronously. After this call returns the context object will still
  // be valid, but its frame() pointer will be cleared.
  void Remove(ScriptContext* context);

  // Gets the ScriptContext corresponding to v8::Context::GetCurrent(), or
  // NULL if no such context exists.
  ScriptContext* GetCurrent() const;

  // Gets the ScriptContext corresponding to v8::Context::GetCalling(), or
  // NULL if no such context exists.
  ScriptContext* GetCalling() const;

  // Gets the ScriptContext corresponding to the specified
  // v8::Context or NULL if no such context exists.
  ScriptContext* GetByV8Context(const v8::Handle<v8::Context>& context) const;

  // Synchronously runs |callback| with each ScriptContext that belongs to
  // |extension_id| in |render_view|.
  //
  // An empty |extension_id| will match all extensions, and a NULL |render_view|
  // will match all render views, but try to use the inline variants of these
  // methods instead.
  void ForEach(const std::string& extension_id,
               content::RenderView* render_view,
               const base::Callback<void(ScriptContext*)>& callback) const;
  // ForEach which matches all extensions.
  void ForEach(content::RenderView* render_view,
               const base::Callback<void(ScriptContext*)>& callback) const {
    ForEach("", render_view, callback);
  }
  // ForEach which matches all render views.
  void ForEach(const std::string& extension_id,
               const base::Callback<void(ScriptContext*)>& callback) const {
    ForEach(extension_id, NULL, callback);
  }

  // Cleans up contexts belonging to an unloaded extension.
  //
  // Returns the set of ScriptContexts that were removed as a result. These
  // are safe to interact with until the end of the current event loop, since
  // they're deleted asynchronously.
  std::set<ScriptContext*> OnExtensionUnloaded(const std::string& extension_id);

 private:
  // Finds the extension for the JavaScript context associated with the
  // specified |frame| and isolated world. If |world_id| is zero, finds the
  // extension ID associated with the main world's JavaScript context. If the
  // JavaScript context isn't from an extension, returns empty string.
  const Extension* GetExtensionFromFrameAndWorld(
      const blink::WebLocalFrame* frame,
      int world_id,
      bool use_effective_url);

  // Returns the Feature::Context type of context for a JavaScript context.
  Feature::Context ClassifyJavaScriptContext(
      const Extension* extension,
      int extension_group,
      const GURL& url,
      const blink::WebSecurityOrigin& origin);

  // Calls Remove on |context| then appends |context| to |out|.
  // This is a helper designed to be used by OnExtensionUnloaded with ForEach.
  void DispatchOnUnloadEventAndRemove(std::set<ScriptContext*>* out,
                                      ScriptContext* context);

  // Weak reference to all installed Extensions.
  ExtensionSet* extensions_;

  // Weak reference to all installed Extensions that are also active in this
  // process.
  ExtensionIdSet* active_extension_ids_;

  // The set of all ScriptContexts we own.
  std::set<ScriptContext*> contexts_;

  DISALLOW_COPY_AND_ASSIGN(ScriptContextSet);
};

}  // namespace extensions

#endif  // EXTENSIONS_RENDERER_SCRIPT_CONTEXT_SET_H_