summaryrefslogtreecommitdiffstats
path: root/chrome/browser/blocked_popup_container.h
blob: 2d5ef6a0cc582de3219d4f91df48773fd1b4a5a1 (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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
// Copyright (c) 2009 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.

// Defines the public interface for the blocked popup notifications. This
// interface should only be used by TabContents. Users and subclasses of
// TabContents should use the appropriate methods on TabContents to access
// information about blocked popups.

// TODO(idanan): Rename class to BlockedContentContainer.

#ifndef CHROME_BROWSER_BLOCKED_POPUP_CONTAINER_H_
#define CHROME_BROWSER_BLOCKED_POPUP_CONTAINER_H_

#include <map>
#include <set>
#include <string>
#include <vector>

#include "app/gfx/native_widget_types.h"
#include "base/gfx/rect.h"
#include "base/string16.h"
#include "chrome/browser/tab_contents/constrained_window.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/common/notification_registrar.h"

class BlockedPopupContainer;
class PrefService;
class Profile;
class TabContents;

// Interface that the BlockedPopupContainer model/controller uses to
// communicate with its platform specific view.
class BlockedPopupContainerView {
 public:
  // Platform specific constructor used by BlockedPopupContainer to create a
  // view that is displayed to the user.
  static BlockedPopupContainerView* Create(BlockedPopupContainer* container);

  // Notification that the view should properly position itself in |view|.
  virtual void SetPosition() = 0;

  // Shows the blocked popup view / Animates the blocked popup view in.
  virtual void ShowView() = 0;

  // Sets the text in the blocked popup label.
  virtual void UpdateLabel() = 0;

  // Hides the blocked popup view / Animates the blocked popup view out.
  virtual void HideView() = 0;

  // Called by the BlockedPopupContainer that owns us. Destroys the view or
  // starts a delayed Task to destroy the View at some later time.
  virtual void Destroy() = 0;
};

// Takes ownership of TabContents that are unrequested popup windows and
// presents an interface to the user for launching them. (Or never showing them
// again). This class contains all the cross-platform bits that can be used in
// all ports.
//
// +- BlockedPopupContainer ---+         +- BlockedPopupContainerView -----+
// | All model logic           |    +--->| Abstract cross platform         |
// |                           |    |    | interface                       |
// |                           |    |    |                                 |
// | Owns a platform view_     +----+    |                                 |
// +---------------------------+         +---------------------------------+
//                                                  ^
//                                                  |
//                  +-------------------------------+-----------+
//                  |                                           |
//  +- BPCViewGtk -----------+     +- BPCViewWin ----------------------+
//  | Gtk UI                 |     | Views UI                          |
//  |                        |     |                                   |
//  +------------------------+     +-----------------------------------+
//
// Getting here will take multiple patches.
class BlockedPopupContainer : public TabContentsDelegate,
                              public NotificationObserver {
 public:
  // Creates a BlockedPopupContainer, anchoring the container to the lower
  // right corner.
  static BlockedPopupContainer* Create(TabContents* owner, Profile* profile);

  static void RegisterUserPrefs(PrefService* prefs);

  // Returns the profile associated with the Browser this container exists in.
  Profile* profile() const { return profile_; }

  // Sets this BlockedPopupContainer's view. BlockedPopupContainer now owns
  // |view| and is responsible for calling Destroy() on it.
  void set_view(BlockedPopupContainerView* view) { view_ = view; }

  // Adds a popup to this container. |bounds| are the window bounds requested by
  // the popup window.
  void AddTabContents(TabContents* tab_contents,
                      const gfx::Rect& bounds,
                      const std::string& host);

  // Shows the blocked popup at index |index|.
  void LaunchPopupAtIndex(size_t index);

  // Returns the number of blocked popups
  size_t GetBlockedPopupCount() const;

  // Adds a blocked notice if one is not already there for the same host.
  void AddBlockedNotice(const GURL& url, const string16& reason);

  // Returns the hostname and reason for notice |index|.
  void GetHostAndReasonForNotice(size_t index,
                                 std::string* host,
                                 string16* reason) const;

  // Returns the number of blocked notices, popups don't count.
  size_t GetBlockedNoticeCount() const;

  // Returns true if host |index| is whitelisted.
  // NOTE: Does not sanity-check; do not pass an invalid index!
  bool IsHostWhitelisted(size_t index) const;

  // If host |index| is currently whitelisted, un-whitelists it.  Otherwise,
  // whitelists it and opens all blocked popups from it.
  // NOTE: Does not sanity-check; do not pass an invalid index!
  void ToggleWhitelistingForHost(size_t index);

  // Deletes all popups and hides the interface parts.
  void CloseAll();

  // Sets this object up to delete itself.
  void Destroy();

  // Message called when a BlockedPopupContainer should move itself to the
  // bottom right corner of our parent view.
  void RepositionBlockedPopupContainer();

  // Returns the TabContents for the blocked popup |index|.
  TabContents* GetTabContentsAt(size_t index) const;

  // Returns the names of hosts showing popups.
  std::vector<std::string> GetHosts() const;

  // Returns the number of popup hosts.
  size_t GetPopupHostCount() const {
    return popup_hosts_.size();
  }

  // Deletes all local state.
  void ClearData();

  // Called to force this container to never show itself again.
  void set_dismissed() { has_been_dismissed_ = true; }

  // Overridden from TabContentsDelegate:

  // Forwards OpenURLFromTab to our |owner_|.
  virtual void OpenURLFromTab(TabContents* source,
                              const GURL& url, const GURL& referrer,
                              WindowOpenDisposition disposition,
                              PageTransition::Type transition);

  // Ignored; BlockedPopupContainer doesn't display a throbber.
  virtual void NavigationStateChanged(const TabContents* source,
                                      unsigned changed_flags) { }

  // Forwards AddNewContents to our |owner_|.
  virtual void AddNewContents(TabContents* source,
                              TabContents* new_contents,
                              WindowOpenDisposition disposition,
                              const gfx::Rect& initial_position,
                              bool user_gesture);

  // Ignore activation requests from the TabContents we're blocking.
  virtual void ActivateContents(TabContents* contents) { }

  // Ignored; BlockedPopupContainer doesn't display a throbber.
  virtual void LoadingStateChanged(TabContents* source) { }

  // Removes |source| from our internal list of blocked popups.
  virtual void CloseContents(TabContents* source);

  // Changes the opening rectangle associated with |source|.
  virtual void MoveContents(TabContents* source, const gfx::Rect& new_bounds);

  // Always returns true.
  virtual bool IsPopup(TabContents* source);

  // Returns our |owner_|.
  virtual TabContents* GetConstrainingContents(TabContents* source);

  // Ignored; BlockedPopupContainer doesn't display a toolbar.
  virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) { }

  // Ignored; BlockedPopupContainer doesn't display a bookmarking star.
  virtual void URLStarredChanged(TabContents* source, bool starred) { }

  // Ignored; BlockedPopupContainer doesn't display a URL bar.
  virtual void UpdateTargetURL(TabContents* source, const GURL& url) { }

  // A number larger than the internal popup count on the Renderer; meant for
  // preventing a compromised renderer from exhausting GDI memory by spawning
  // infinite windows.
  static const size_t kImpossibleNumberOfPopups;

 protected:
  struct BlockedPopup {
    BlockedPopup(TabContents* tab_contents,
                 const gfx::Rect& bounds,
                 const std::string& host)
        : tab_contents(tab_contents), bounds(bounds), host(host) {
    }

    TabContents* tab_contents;
    gfx::Rect bounds;
    std::string host;
  };
  typedef std::vector<BlockedPopup> BlockedPopups;

  // TabContents is the popup contents.  string is opener hostname.
  typedef std::map<TabContents*, std::string> UnblockedPopups;

  // string is hostname.  bool is whitelisted status.
  typedef std::map<std::string, bool> PopupHosts;

  struct BlockedNotice {
    BlockedNotice(const GURL& url, const string16& reason)
        : url_(url), reason_(reason) {}

    GURL url_;
    string16 reason_;
  };
  typedef std::vector<BlockedNotice> BlockedNotices;

  // Hosts with notifications showing.
  typedef std::set<std::string> NoticeHosts;

  // Creates a BlockedPopupContainer, anchoring the container to the lower
  // right corner using the given BlockedPopupContainerView. Use only for
  // testing.
  static BlockedPopupContainer* Create(TabContents* owner, Profile* profile,
                                       BlockedPopupContainerView* view);

  // Hides the UI portion of the container.
  void HideSelf();

  // Helper function to convert a host index (which the view uses) into an
  // iterator into |popup_hosts_|.  Returns popup_hosts_.end() if |index| is
  // invalid.
  PopupHosts::const_iterator ConvertHostIndexToIterator(size_t index) const;

  // Removes the popup at |i| from the blocked popup list.  If this popup's host
  // is not otherwised referenced on either popup list, removes the host from
  // the host list.  Updates the view's label to match the new state.
  void EraseDataForPopupAndUpdateUI(BlockedPopups::iterator i);

  // Same as above, but works on the unblocked popup list.
  void EraseDataForPopupAndUpdateUI(UnblockedPopups::iterator i);

 private:
  friend class BlockedPopupContainerImpl;
  friend class BlockedPopupContainerTest;
  friend class BlockedPopupContainerControllerTest;

  // string is hostname.
  typedef std::set<std::string> Whitelist;

  // Creates a container for a certain TabContents:
  BlockedPopupContainer(TabContents* owner, Profile* profile);

  // Either hides the view if there are no popups, or updates the label if
  // there are.
  void UpdateView();

  // Overridden from notificationObserver:
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details);

  // The TabContents that owns and constrains this BlockedPopupContainer.
  TabContents* owner_;

  // The PrefService we can query to find out what's on the whitelist.  If the
  // profile is off the record, this will be NULL.
  PrefService* prefs_;

  // Once the container is hidden, this is set to prevent it from reappearing.
  bool has_been_dismissed_;

  // Registrar to handle notifications we care about.
  NotificationRegistrar registrar_;

  // The whitelisted hosts, which we allow to open popups directly.
  Whitelist whitelist_;

  // Information about all blocked popups.
  BlockedPopups blocked_popups_;

  // Information about all unblocked popups.
  UnblockedPopups unblocked_popups_;

  // Information about all popup hosts.
  PopupHosts popup_hosts_;

  // Notices for all blocked resources.
  BlockedNotices blocked_notices_;

  // Hosts which had notifications shown.
  NoticeHosts notice_hosts_;

  // Our platform specific view.
  BlockedPopupContainerView* view_;

  // The profile for the browser associated with the container.
  Profile* profile_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(BlockedPopupContainer);
};

#endif  // CHROME_BROWSER_BLOCKED_POPUP_CONTAINER_H_