chromium/content/public/browser/document_service.h

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_PUBLIC_BROWSER_DOCUMENT_SERVICE_H_
#define CONTENT_PUBLIC_BROWSER_DOCUMENT_SERVICE_H_

#include <cstdint>
#include <string_view>
#include <utility>

#include "base/check.h"
#include "base/compiler_specific.h"
#include "base/functional/bind.h"
#include "base/threading/thread_checker.h"
#include "content/public/browser/document_service_internal.h"
#include "content/public/browser/render_frame_host.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "url/origin.h"

namespace content {

enum class DocumentServiceDestructionReason : int {};

// Provides a safe alternative to mojo::MakeSelfOwnedReceiver<T>(...) for
// document-scoped Mojo interface implementations. Use of this helper prevents
// logic bugs when Mojo IPCs for `Interface` race against Mojo IPCs for
// navigation. One example of a past bug caused by this IPC race is
// https://crbug.com/769189, where an interface implementation performed a
// permission check using the wrong origin.
//
// Like C++ implementations owned by mojo::MakeSelfOwnedReceiver<T>(...), a
// subclass of DocumentService<Interface> will delete itself when the
// corresponding message pipe is disconnected by setting a disconnect handler on
// the mojo::Receiver<T>.
//
// In addition, a subclass of DocumentService<Interface> will also track
// the lifetime of the current document of the supplied RenderFrameHost and
// delete itself:
//
// - if the RenderFrameHost is deleted (for example, the <iframe> element the
//   RenderFrameHost represents is removed from the DOM) or
// - if the RenderFrameHost commits a cross-document navigation. Specifically,
//   DocumentService instances (and DocumentUserData instances)
//   are deleted with the same timing, before the last committed origin and
//   URL have been updated.
//
// When to use:
// Any Mojo interface implementation that references a RenderFrameHost, whether
// directly via a RenderFrameHost pointer, or indirectly, via the
// RenderFrameHost routing ID, should strongly consider:
//
// - `DocumentService` when there may be multiple instances per
//   RenderFrameHost.
// - `DocumentUserData` when there should only be a single instance
//   per RenderFrameHost.
//
// There are very few circumstances where a Mojo interface needs to be reused
// after a cross-document navigation.
template <typename Interface>
class DocumentService : public Interface, public internal::DocumentServiceBase {};

}  // namespace content

#endif  // CONTENT_PUBLIC_BROWSER_DOCUMENT_SERVICE_H_