Chrome文档精读
TODO
study the usage of base::Thread
Thread pool: Sequence or Virtual thread Task runner
Multi-process Architecture
Managing renderer processes
Each renderer process has a global RenderProcess
object that manages communication with the parent browser process and maintains global state. The browser maintains a corresponding RenderProcessHost
for each renderer process, which manages browser state and communication for the renderer. The browser and the renderers communicate using Mojo or Chromium’s legacy IPC system.
In the renderer process:
- The
RenderProcess
handles Mojo setup and legacy IPC with the correspondingRenderProcessHost
in the browser. There is exactly oneRenderProcess
object per renderer process. - The
RenderFrame
object communicates with its correspondingRenderFrameHost
in the browser process (via Mojo), and the Blink layer. This object represents the contents of one web document in a tab or subframe.
In the browser process:
- The
Browser
object represents a top-level browser window. - The
RenderProcessHost
object represents the browser side of a single browser ↔ renderer IPC connection. There is oneRenderProcessHost
in the browser process for each renderer process. - The
RenderFrameHost
object encapsulates communication with theRenderFrame
, andRenderWidgetHost
handles the input and painting forRenderWidget
in the browser.
Chromium has split out a number of other components into separate processes as well, sometimes in platform-specific ways. For example, it now has a separate GPU process, network service, and storage service. Sandboxed utility processes can also be used for small or risky tasks, as one way to satisfy the Rule of Two for security.
Process 进程
简单来说,出于安全、稳定和隔离性的考虑,每个网站(而不是每个标签页)都会起一个独立的进程。具体可以看Chrome更多工具里的任务管理器。每个进程的崩溃不会影响整个浏览器。
For stability, putting web site instances in separate processes limits the impact of a renderer process crash or hang, allowing other content to continue working. For performance, this allows different web site instances to run in parallel with better responsiveness, at the cost of some memory overhead for each process.
For security, strictly using separate processes for different web sites allows significantly stronger defenses against malicious web sites. In addition to running web content within a low-privilege sandbox that limits an attacker‘s access to the user’s machine, Chromium’s multi-process architecture can support Site Isolation, where each renderer process is only allowed to access data from a single site. Site Isolation involves:
- Locked Renderer Processes: A renderer process can be limited to documents and workers from a single web site or origin, even if such documents are in iframes.
- Browser-Enforced Restrictions: The privileged browser process can monitor IPC messages from locked processes to limit their actions or access to site data (e.g., using ChildProcessSecurityPolicy::CanAccessDataForOrigin). This prevents compromised renderer processes from asking for cross-site data, using permissions granted to other sites, etc.
- Network Response Limitations: Chromium can ensure that locked renderer processes are only allowed to receive sensitive data (e.g., HTML, XML, JSON) from their designated site or origin, while still allowing cross-origin subresource requests (e.g., images, media) as needed for compatibility. This is achieved using Cross-Origin Read Blocking (CORB) or Opaque Response Blocking (ORB).
Principal Instance (implemented by SiteInstance): A principal instance is the core unit of Chromium‘s process model. Any two documents with the same principal in the same browsing context group (see below) must live in the same process, because they have synchronous access to each other’s content
Threads 线程
Chrome has a multi-process architecture and each process is heavily multi-threaded. The main goal is to keep the main thread (a.k.a. “UI” thread in the browser process) and IO thread (each process‘s thread for receiving IPC) responsive. This means offloading any blocking I/O or other expensive operations to other threads. Our approach is to use message passing as the way of communicating between threads. We discourage locking and thread-safe objects. Instead, objects live on only one (often virtual — we’ll get to that later!) thread and we pass messages between those threads for communication.
Task : a function pointer with optionally associated state
Cancelling a Task: Using base::WeakPtr
can be used to ensure that any callback bound to an object is canceled when that object is destroyed.
In Chrome this is base::OnceCallback
and base::RepeatingCallback
created via base::BindOnce
A task is a base::OnceClosure
added to a queue for asynchronous execution.
Task runner: An interface through which tasks can be posted. In Chrome this is base::TaskRunner
.
其他概念
学习webcontents.h
The content/
layer of Chromium has a class called WebContents
, which is one of the most basic building blocks of all of Chromium. This document describes how WebContents
es are used to build tabs in browser windows.
WebContents is the core class in content/. A WebContents renders web content (usually HTML) in a rectangular area.
Instantiating one is simple:
// std::unique_ptr<content::WebContents> web_contents(
// content::WebContents::Create(
// content::WebContents::CreateParams(browser_context)));
// gfx::NativeView view = web_contents->GetNativeView();
// Each WebContents has exactly one NavigationController; each NavigationController belongs to one WebContents. The NavigationController canbe obtained from GetController(), and is used to load URLs into the WebContents, navigate it backwards/forwards, etc. See navigation_controller.h
Blink
Blink is a rendering engine of the web platform. Roughly speaking, Blink implements everything that renders content inside a browser tab:
Blink is embedded by many customers such as Chromium, Android WebView and Opera via content public APIs.
From the code base perspective, “Blink” normally means //third_party/blink/. From the project perspective, “Blink” normally means projects that implement web platform features. Code that implements web platform features span //third_party/blink/, //content/renderer/, //content/browser/ and other places.
Page, Frame, Document, ExecutionContext and DOMWindow
A Page corresponds to a concept of a tab (if OOPIF explained below is not enabled). Each renderer process may contain multiple tabs.
A Frame corresponds to a concept of a frame (the main frame or an iframe). Each Page may contain one or more Frames that are arranged in a tree hierarchy.
A DOMWindow corresponds to a window object in JavaScript. Each Frame has one DOMWindow.
A Document corresponds to a window.document object in JavaScript. Each Frame has one Document.
An ExecutionContext is a concept that abstracts a Document (for the main thread) and a WorkerGlobalScope (for a worker thread).
Renderer process : Page = 1 : N.
Page : Frame = 1 : M.
Frame : DOMWindow : Document (or ExecutionContext) = 1 : 1 : 1 at any point in time, but the mapping may change over time. For example, consider the following code:
iframe.contentWindow.location.href = “https://example.com”;
In this case, a new DOMWindow and a new Document are created for https://example.com. However, the Frame may be reused.
Isolate, Context, World
Isolate corresponds to a physical thread. Isolate : physical thread in Blink = 1 : 1. The main thread has its own Isolate. A worker thread has its own Isolate.
Context corresponds to a global object (In case of a Frame, it’s a window object of the Frame). Since each frame has its own window object, there are multiple Contexts in a renderer process. When you call V8 APIs, you have to make sure that you’re in the correct context.
To realize the isolation, the main thread creates one main world for the web page and one isolated world for each content script. The main world and the isolated worlds can access the same C++ DOM objects but their JavaScript objects are isolated. This isolation is realized by creating multiple V8 wrappers for one C++ DOM object; i.e., one V8 wrapper per world.
blink::WebLocalFrame* web_frame = render_frame_->GetWebFrame();
v8::Local<v8::Context> context = web_frame->MainWorldScriptContext();
V8 API
V8 uses handles to point to V8 objects. The most common handle is v8::Local<>, which is used to point to V8 objects from a machine stack. v8::Local<> must be used after allocating v8::HandleScope on the machine stack. v8::Local<> should not be used outside the machine stack:
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
v8::Local<v8::Context> context = web_frame->MainWorldScriptContext();
v8::Context::Scope context_scope(context);
Introduction
What is a “tab helper”? It is a WebContentsObserver
owned by the WebContents
itself. Let’s break that down.
WebContentsObserver
WebContentsObserver
is a simple interface that allows an object to observe events in the life of a WebContents
. 观察者模式,观察webcontent
最后更新于 2025年1月6日 by qlili