summaryrefslogtreecommitdiffstats
path: root/chrome/browser/prerender/prerender_link_manager.h
blob: 9511fb9818cc0b98464620dc0bcf61ddd99a1fce (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
// Copyright (c) 2012 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 CHROME_BROWSER_PRERENDER_PRERENDER_LINK_MANAGER_H_
#define CHROME_BROWSER_PRERENDER_PRERENDER_LINK_MANAGER_H_

#include <list>

#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/time.h"
#include "chrome/browser/prerender/prerender_handle.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "googleurl/src/gurl.h"

class Profile;

namespace content {
struct Referrer;
}

namespace gfx {
class Size;
}

FORWARD_DECLARE_TEST(WebViewTest, NoPrerenderer);

namespace prerender {

class PrerenderHandle;
class PrerenderManager;

// PrerenderLinkManager implements the API on Link elements for all documents
// being rendered in this chrome instance.  It receives messages from the
// renderer indicating addition, cancelation and abandonment of link elements,
// and controls the PrerenderManager accordingly.
class PrerenderLinkManager : public ProfileKeyedService,
                             public PrerenderHandle::Observer {
 public:
  explicit PrerenderLinkManager(PrerenderManager* manager);
  virtual ~PrerenderLinkManager();

  // A <link rel=prerender ...> element has been inserted into the document.
  // The |prerender_id| must be unique per |child_id|, and is assigned by the
  // WebPrerendererClient.
  void OnAddPrerender(int child_id,
                      int prerender_id,
                      const GURL& url,
                      const content::Referrer& referrer,
                      const gfx::Size& size,
                      int render_view_route_id);

  // A <link rel=prerender ...> element has been explicitly removed from a
  // document.
  void OnCancelPrerender(int child_id, int prerender_id);

  // A renderer launching <link rel=prerender ...> has navigated away from the
  // launching page, the launching renderer process has crashed, or perhaps the
  // renderer process was fast-closed when the last render view in it was
  // closed.
  void OnAbandonPrerender(int child_id, int prerender_id);

  // If a renderer channel closes (crash, fast exit, etc...), that's effectively
  // an abandon of any prerenders launched by that child.
  void OnChannelClosing(int child_id);

 private:
  friend class PrerenderBrowserTest;
  friend class PrerenderTest;
  // WebViewTest.NoPrerenderer needs to access the private IsEmpty() method.
  FRIEND_TEST_ALL_PREFIXES(::WebViewTest, NoPrerenderer);

  struct LinkPrerender {
    LinkPrerender(int launcher_child_id,
                  int prerender_id,
                  const GURL& url,
                  const content::Referrer& referrer,
                  const gfx::Size& size,
                  int render_view_route_id,
                  base::TimeTicks creation_time);
    ~LinkPrerender();

    // Parameters from PrerenderLinkManager::OnAddPrerender():
    int launcher_child_id;
    int prerender_id;
    GURL url;
    content::Referrer referrer;
    gfx::Size size;
    int render_view_route_id;

    // The time at which this Prerender was added to PrerenderLinkManager.
    base::TimeTicks creation_time;

    // Initially NULL, |handle| is set once we start this prerender. It is owned
    // by this struct, and must be deleted before destructing this struct.
    PrerenderHandle* handle;
  };

  bool IsEmpty() const;

  // Returns a count of currently running prerenders.
  size_t CountRunningPrerenders() const;

  // Start any prerenders that can be started, respecting concurrency limits for
  // the system and per launcher.
  void StartPrerenders();

  LinkPrerender* FindByLauncherChildIdAndPrerenderId(int child_id,
                                                     int prerender_id);

  LinkPrerender* FindByPrerenderHandle(PrerenderHandle* prerender_handle);

  void RemovePrerender(LinkPrerender* prerender);

  // From ProfileKeyedService:
  virtual void Shutdown() OVERRIDE;

  // From PrerenderHandle::Observer:
  virtual void OnPrerenderStart(PrerenderHandle* prerender_handle) OVERRIDE;
  virtual void OnPrerenderStopLoading(PrerenderHandle* prerender_handle)
      OVERRIDE;
  virtual void OnPrerenderStop(PrerenderHandle* prerender_handle) OVERRIDE;

  bool has_shutdown_;

  PrerenderManager* manager_;

  // All prerenders known to this PrerenderLinkManager. Insertions are always
  // made at the back, so the oldest prerender is at the front, and the youngest
  // at the back.
  std::list<LinkPrerender> prerenders_;

  DISALLOW_COPY_AND_ASSIGN(PrerenderLinkManager);
};

}  // namespace prerender

#endif  // CHROME_BROWSER_PRERENDER_PRERENDER_LINK_MANAGER_H_