blob: 623465bfd58d9834973c9b29f45e7a08bfaa7963 [file] [log] [blame]
// 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 COMPONENTS_NO_STATE_PREFETCH_BROWSER_PRERENDER_LINK_MANAGER_H_
#define COMPONENTS_NO_STATE_PREFETCH_BROWSER_PRERENDER_LINK_MANAGER_H_
#include <stddef.h>
#include <stdint.h>
#include <list>
#include <memory>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/no_state_prefetch/browser/prerender_handle.h"
#include "third_party/blink/public/mojom/prerender/prerender.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
FORWARD_DECLARE_TEST(WebViewTest, NoPrerenderer);
namespace prerender {
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 KeyedService,
public PrerenderHandle::Observer {
public:
explicit PrerenderLinkManager(PrerenderManager* manager);
~PrerenderLinkManager() override;
// Called when a <link rel=prerender ...> element has been inserted into the
// document. Returns the prerender id that is used for canceling or abandoning
// prerendering. Returns base::nullopt if the prerender was not started.
virtual base::Optional<int> OnStartPrerender(
int launcher_render_process_id,
int launcher_render_view_id,
blink::mojom::PrerenderAttributesPtr attributes,
const url::Origin& initiator_origin);
// Called when a <link rel=prerender ...> element has been explicitly removed
// from a document.
virtual void OnCancelPrerender(int prerender_id);
// Called when 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.
virtual void OnAbandonPrerender(int prerender_id);
private:
friend class PrerenderBrowserTest;
friend class PrerenderTest;
// WebViewTest.NoPrerenderer needs to access the private IsEmpty() method.
FRIEND_TEST_ALL_PREFIXES(::WebViewTest, NoPrerenderer);
class PendingPrerenderManager;
// Used to store state about a requested prerender.
struct LinkPrerender {
LinkPrerender(int launcher_render_process_id,
int launcher_render_view_id,
blink::mojom::PrerenderAttributesPtr attributes,
const url::Origin& initiator_origin,
base::TimeTicks creation_time,
PrerenderContents* deferred_launcher);
~LinkPrerender();
LinkPrerender(const LinkPrerender& other) = delete;
LinkPrerender& operator=(const LinkPrerender& other) = delete;
// Parameters from PrerenderLinkManager::OnStartPrerender():
const int launcher_render_process_id;
const int launcher_render_view_id;
const GURL url;
const blink::mojom::PrerenderRelType rel_type;
const content::Referrer referrer;
const url::Origin initiator_origin;
const gfx::Size size;
// The time at which this Prerender was added to PrerenderLinkManager.
const base::TimeTicks creation_time;
// If non-null, this link prerender was launched by an unswapped prerender,
// |deferred_launcher|. When |deferred_launcher| is swapped in, the field is
// set to null.
const PrerenderContents* deferred_launcher;
// Initially null, |handle| is set once we start this prerender. It is owned
// by this struct, and must be deleted before destructing this struct.
std::unique_ptr<PrerenderHandle> handle;
// True if this prerender has been abandoned by its launcher.
bool has_been_abandoned;
// The unique ID of this prerender. Used for canceling or abandoning
// prerendering.
const int prerender_id;
};
bool IsEmpty() const;
bool PrerenderIsRunningForTesting(LinkPrerender* link_prerender) 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* FindByPrerenderHandle(PrerenderHandle* prerender_handle);
LinkPrerender* FindByPrerenderId(int prerender_id);
// Removes |prerender| from the the prerender link manager. Deletes the
// PrerenderHandle as needed.
void RemovePrerender(LinkPrerender* prerender);
// Cancels |prerender| and removes |prerender| from the prerender link
// manager.
void CancelPrerender(LinkPrerender* prerender);
// From KeyedService:
void Shutdown() override;
// From PrerenderHandle::Observer:
void OnPrerenderStop(PrerenderHandle* prerender_handle) override;
void OnPrerenderNetworkBytesChanged(
PrerenderHandle* prerender_handle) override;
bool has_shutdown_;
PrerenderManager* const 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. Using std::unique_ptr<> here as LinkPrerender is not copyable.
std::list<std::unique_ptr<LinkPrerender>> prerenders_;
DISALLOW_COPY_AND_ASSIGN(PrerenderLinkManager);
};
} // namespace prerender
#endif // COMPONENTS_NO_STATE_PREFETCH_BROWSER_PRERENDER_LINK_MANAGER_H_