1// 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_BROWSER_GUEST_VIEW_GUEST_VIEW_MANAGER_H_
6#define EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_MANAGER_H_
7
8#include <map>
9
10#include "base/gtest_prod_util.h"
11#include "base/lazy_instance.h"
12#include "base/macros.h"
13#include "content/public/browser/browser_plugin_guest_manager.h"
14#include "content/public/browser/site_instance.h"
15#include "content/public/browser/web_contents.h"
16
17class GURL;
18
19namespace content {
20class BrowserContext;
21class WebContents;
22}  // namespace content
23
24namespace extensions{
25class GuestViewBase;
26class GuestViewManagerFactory;
27
28class GuestViewManager : public content::BrowserPluginGuestManager,
29                         public base::SupportsUserData::Data {
30 public:
31  explicit GuestViewManager(content::BrowserContext* context);
32  virtual ~GuestViewManager();
33
34  static GuestViewManager* FromBrowserContext(content::BrowserContext* context);
35
36  // Overrides factory for testing. Default (NULL) value indicates regular
37  // (non-test) environment.
38  static void set_factory_for_testing(GuestViewManagerFactory* factory) {
39    GuestViewManager::factory_ = factory;
40  }
41  // Returns the guest WebContents associated with the given |guest_instance_id|
42  // if the provided |embedder_render_process_id| is allowed to access it.
43  // If the embedder is not allowed access, the embedder will be killed, and
44  // this method will return NULL. If no WebContents exists with the given
45  // instance ID, then NULL will also be returned.
46  content::WebContents* GetGuestByInstanceIDSafely(
47      int guest_instance_id,
48      int embedder_render_process_id);
49
50  // Associates the Browser Plugin with |element_instance_id| to a
51  // guest that has ID of |guest_instance_id| and sets initialization
52  // parameters, |params| for it.
53  void AttachGuest(int embedder_render_process_id,
54                   int embedder_routing_id,
55                   int element_instance_id,
56                   int guest_instance_id,
57                   const base::DictionaryValue& attach_params);
58
59  int GetNextInstanceID();
60  int GetGuestInstanceIDForElementID(
61      content::WebContents* embedder_web_contents,
62      int element_instance_id);
63
64  typedef base::Callback<void(content::WebContents*)>
65      WebContentsCreatedCallback;
66  void CreateGuest(const std::string& view_type,
67                   const std::string& embedder_extension_id,
68                   content::WebContents* embedder_web_contents,
69                   const base::DictionaryValue& create_params,
70                   const WebContentsCreatedCallback& callback);
71
72  content::WebContents* CreateGuestWithWebContentsParams(
73      const std::string& view_type,
74      const std::string& embedder_extension_id,
75      int embedder_render_process_id,
76      const content::WebContents::CreateParams& create_params);
77
78  content::SiteInstance* GetGuestSiteInstance(
79      const GURL& guest_site);
80
81  // BrowserPluginGuestManager implementation.
82  virtual content::WebContents* GetGuestByInstanceID(
83      content::WebContents* embedder_web_contents,
84      int element_instance_id) OVERRIDE;
85  virtual bool ForEachGuest(content::WebContents* embedder_web_contents,
86                            const GuestCallback& callback) OVERRIDE;
87 protected:
88  friend class GuestViewBase;
89  FRIEND_TEST_ALL_PREFIXES(GuestViewManagerTest, AddRemove);
90
91  // Can be overriden in tests.
92  virtual void AddGuest(int guest_instance_id,
93                        content::WebContents* guest_web_contents);
94
95  // Can be overriden in tests.
96  virtual void RemoveGuest(int guest_instance_id);
97
98  content::WebContents* GetGuestByInstanceID(int guest_instance_id);
99
100  bool CanEmbedderAccessInstanceIDMaybeKill(
101      int embedder_render_process_id,
102      int guest_instance_id);
103
104  bool CanEmbedderAccessInstanceID(int embedder_render_process_id,
105                                   int guest_instance_id);
106
107  // Returns true if |guest_instance_id| can be used to add a new guest to this
108  // manager.
109  // We disallow adding new guest with instance IDs that were previously removed
110  // from this manager using RemoveGuest.
111  bool CanUseGuestInstanceID(int guest_instance_id);
112
113  // Static factory instance (always NULL for non-test).
114  static GuestViewManagerFactory* factory_;
115
116  // Contains guests' WebContents, mapping from their instance ids.
117  typedef std::map<int, content::WebContents*> GuestInstanceMap;
118  GuestInstanceMap guest_web_contents_by_instance_id_;
119
120  struct ElementInstanceKey {
121    content::WebContents* embedder_web_contents;
122    int element_instance_id;
123    ElementInstanceKey(content::WebContents* embedder_web_contents,
124                       int element_instance_id)
125        : embedder_web_contents(embedder_web_contents),
126          element_instance_id(element_instance_id) {}
127    bool operator<(const ElementInstanceKey& other) const {
128      if (embedder_web_contents != other.embedder_web_contents)
129        return embedder_web_contents < other.embedder_web_contents;
130      return element_instance_id < other.element_instance_id;
131    }
132  };
133
134  typedef std::map<ElementInstanceKey, int> GuestInstanceIDMap;
135  GuestInstanceIDMap instance_id_map_;
136  // The reverse map of GuestInstanceIDMap.
137  typedef std::map<int, ElementInstanceKey> GuestInstanceIDReverseMap;
138  GuestInstanceIDReverseMap reverse_instance_id_map_;
139
140  int current_instance_id_;
141
142  // Any instance ID whose number not greater than this was removed via
143  // RemoveGuest.
144  // This is used so that we don't have store all removed instance IDs in
145  // |removed_instance_ids_|.
146  int last_instance_id_removed_;
147  // The remaining instance IDs that are greater than
148  // |last_instance_id_removed_| are kept here.
149  std::set<int> removed_instance_ids_;
150
151  content::BrowserContext* context_;
152
153  DISALLOW_COPY_AND_ASSIGN(GuestViewManager);
154};
155
156}  // namespace extensions
157
158#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_MANAGER_H_
159