分享

转 游览Chrome源代码

 quasiceo 2013-01-29

转 游览Chrome源代码

source-code
目录
1. 1概述
2. 2解决方案文件快速介绍
3. 3顶级工程
4. 4目录“chrome/”下的快速考
5. 5常用操作的代码路径
1. 5.1应用程序启动
2. 5.2标签页的启动及初始导

3. 5.3从地址栏导航
4. 5.4导航和会话历史
概述
Chrome是分成三个主要部分(不包括其他类库):浏览器,渲染器,和Webkit。该浏览器是主要的进程,并代表所
有的用户界面和I / O渲染器是是由浏览器驱动(经常)每标签子进程,。它嵌入了WebKit的做布局和渲染。
您将要阅读,成为我们熟悉的多进程架构和Chrome如何显示网页 。
解决方案文件快速介绍
我们有两个解决方案文件, de>chrome.slnde>这是正常的版本,它使用的V8作为Javascript引擎的和
de>chrome_kjs.slnde>它使用WebKit的JavaScriptCore的(JSC)作为JavaScript引擎。您通常会希望使用V8引擎
的版本,我们保持JSC的版本,看看是否有的错误与V8引擎有关。
启动代码在de>App/chrome_dllde>和de>App/chromede>工程中。
普通共享库代码在de>Libraries/basede>工程。这些代码为所有项目共享,我们尽量保持它越小越好。
常见的浏览器特定的代码是在de>Browser/commonde>项目,这些代码与浏览器和渲染器共同使用。
WebKit的代码是在项目的de>Webkit(readonly)de> 。在此之上是谷歌的de>WebKit(ours)/portde>的
Windows介面,de>WebKit(ours)/gluede>这是我们的嵌入层。
Glue与de>Browser/rendererde>工程交流,它代表了运行每个标签的进程。
该de>Browser/browserde>的工程提供了用户界面,存储,网络要求等
顶级工程
当您用SVN签出Chromium,你会发现一个顶级目录的数量。 这些工程如下:
base :所有子工程共享的代码部分。这里面包含如字符串处理操作,一般工具等。在这里添加东西,只有当
它必须在一个以上的其他顶级工程共享。
gfx :共享图形类。这些构成了Chromium的图形用户界面的基础。有额外的图形类{在
0}chrome/common/gfx中,为所Chromium应用程序所特有。
breakpad:谷歌的开源崩溃报告的项目。这是直接从谷歌代码的Subversion存储库获得的。
build :与生成(build)相关的配置,为所有工程共同分享。
chrome :chrome的浏览器(见下文)。
data :为进行测试的一些数据文件。
gears:Gears 项目。
googleurl:谷歌的的URL解析和规范化的开源库。这是直接从谷歌代码的Subversion存储库中获取的。
net :为Chrome制作的网络库。这可独立与Chrome运行,当我们运行一些简单的test_shell为测试
de>webkitde>。同见de>chrome/common/netde> 。
sandbox :沙箱项目,阻止一客渲染修改系统。
skia:谷歌的Skia为Android开发的图形库开发库。这是从Android项目获得的副本。我们添加的的类在
base/gfx中的包装类
testing :包含谷歌的GTest开源代码,我们用它来进行单元测试。
third_party:一些外部库,如图像解码器和压缩类库。还有一些Chrome特定第三方库在
de>chrome/third_partyde> 目录中。
tools
v8 :V8Javascript引擎库。这是直接从谷歌代码的Subversion存储库获取的。
WebKit的 :所有Chromium的WebKit有关的东西:
build :项目文件和其他项目的配置文件。
data :大部分的目录包含对Porting层进行单元测试的数据。该layout_tests目录是WebKit的布局测试
套件,我们直接从Apple直接获取的。
glue :glue层是嵌入层。它可以转换之间加入WebCore类型和我们的应用程序的类型(主要是
STL),并提供更方便的方法,加入许多我们需要访问WebCore的对象。
tools
layout_tests:运行WebCore的布局测试的脚本。
merge :帮助合并WebKit的脚本。
npapi_layout_test_plugin:在我们的测试所使用的一些插件层的一些特殊的插件。
test_shell:一个很简单的独立浏览器。这使我们的测试glue和port代码,而不必编译和运行非
常大的Chrome应用程序。
目录“chrome/”下的快速考
app :在“app”目录中的是该程序的最基层。它在启动时运行,无论是派遣到浏览器或渲染代码,这取决于当
前进程的能力。它的项目包含de>chrome.exede>和de>chrome.dllde> 项目。你不需要改变这些东西,除了
一般需要像图片和字符串资源等。
locales :生成本地化的DLL所需要的。
resources :图标和鼠标指针。
theme :窗口主题所用到的图片。
browser :在前端运行的,包括主窗口,用户界面,以及与后端的负责处理所有I / O和存储的应用程序。它
告诉de>渲染器de>处理网页。
common :渲染器和浏览器之间共享文件,以及其他随机项目。这代码为Chromium特有的(而不是被用
于base ),但是这是由chrome/browser 与chrome/renderer所共用的目录
gfx :特定于Chrome图形与渲染相关的辅助代码。某些图形模块的东西,必须分享在外部顶层的
de>base/gfxde> 。
net :在最顶层模块基础上的特定于Chromium的网络模块。这样的应该合并在 browser/net目录下。
installer :制作安装程序(MSI包)所需要的源文件和工程。
plugin :在其他进程中运行的浏览器插件。
renderer :每个标签页渲染器代码。这嵌入WebKit并与de>browserde>交互进行I/O。
test:
automation :为驱动用户界面的测试程序,例如,在test/ui,test/startup等。这些操作通过
browser/automation 与浏览器交流。
page_cycler:运行page cycler的测试代码(供性能测试用)。参见de>tools/perf/dashboardde> 。
reliability :可靠性试验测试, 分布式测试页面加载、可靠性度量以及崩溃的检测。
selenium :运行Selenium测试的代码,这是一套为测试Ajax和JavaScript第三方测试工具。见
de>test/third_party/selenium_corede> 。
startup :测试启动性能代码。查看de>tools/perf/dashboardde>和de>tools/test/reference_buildde>

ui :用户界面测试,打开浏览器的用户界面,打开标签,等。它使用de>test/automationde>做大多数
操作。
unit :单元测试的基础代码。个人测试的测试代码通常是这样的一个测试de>*_unittest.ccde>文件。
third_party:Chrome所特有的第三方库。其他一些第三方库是在顶层de>third_partyde>库。
tools
build :和生成有关的一些随机的的工具。
buildbot:Buildbot配置。Buildbot管理我们的自动生成系统。见de>third_pary/buildbotde> 。
windows :Windows下的生成东西,包括一些de>.vspropsde>文件用于项目属性和脚本。
memory :内存工具。目前包括de>gflagsde>设置页堆选项
perf/dashboard :把性能日志转换成数据和图表的工具(例如de>test/startup_testde> )
profiles :随机历史数据生成器。用来测试Profiles。
views :一个简单的UI开发框架,提供渲染,布局和事件处理。大部分浏览器的用户界面,是在这一部分实
现的。这个目录包含基本对象。一些更多的浏览器特定的对象是在browser/views 。
共同操作的代码路径
还有更多的信息和更多的例子在Chrome如何显示网页 。
应用程序启动
1. 我们的de>WinMainde>函数是在de>chrome/app/main.ccde>中 ,在de>chromede>项目中被链接。
2. de>WinMainde>加载谷歌更新客户端,它在installer/autoupdater。它会找到最新版本的子目录,从那里加载
de>chrome.dllde>。
3. 它在新加载的库中调用de>ChromeMainde>,它在de>chr0ome_dllde>项目中的de>chrome_main.ccde>中声

4. de>ChromeMainde>对常见的组件进行初始化,然后进行有两种选择。如果命令行的标志为是一个子进程,
将会跳转到在chrome/renderer/renderer_main.cc。如果不加载一个新的副本实例的话,它将会跳转到
chrome/browser/browser_main.cc中的Browser_Main函数。当这个启动完成时时,我们会加载浏览器。
5. de>BrowserMainde>会进行常规的初始化。它为不同的模式运行安装的webapps,当浏览器测试时候会连接
到自动化系统等
6. 它调用在de>browser_init.ccde>中de>LaunchWithProfilede>,由它创建了一个新的de>Browserde>对象(声
明在de>chrome/browser/browser.ccde>中)。该对象封装在应用程序一顶层窗口。第一个标签是在这个时候
加载的。
标签启动及初始导航
1. de>Browser::AppendTabde>在de>chrome/browser/browser.ccde>被调用来增加一个新的标签。
2. 这将创建一个新的de>TabContentsde>对象(声明在de>browser/tab_contents/tab_contents.ccde>)
3. de>TabContentsde>创建一个de>RenderViewHostde> (
chrome/browser/renderer_host/render_view_host.cc))通过RenderViewMostManager初始化函
数(chrome/browser/tab_contents/render_view_host_manager.cc)。根据不同
的SiteInstance,RenderViewHost要么产生一个新的渲染进程,或重新使用现有de>RenderProcessde> 。
de>RenderProcessde>在浏览器中的子对象是,它表示一个单一的渲染子进程。
4. NavigationController (声明在chrome/browser/tab_contents/ navigation_controller.cc)归标签的内容所有,被
指示导航到URL中的新标签de>NavigationController::LoadURLde> 。 “”5.3 从地址栏导航“描述了由这一点发
生的一切。
从地址栏导航
1. 当用户在地址栏目中键入一个酒吧或接受输入的网址,自动完成编辑框确定最终目标URL并传递到
de>AutocompleteEdit::OpenURLde> 。 (这可能不是用户键入的网址 - 例如,有的网址是在一个搜索查询的
情况下产生的。)
2. 该导航控制器指示导航到的URL de>NavigationController::LoadURLde> 。
3. 该de>NavigationControllerde>用de>NavigationEntryde>调用de>TabContents::Navigatede>,并用他们创建
的代表这个特定网页的过渡。如果有必要的话,它将创建一个新的de>RenderViewHostde>,这将导致在在渲
染进程中建立一个新的de>RenderViewHostde>。如果这是第一次浏览网页,或者渲染器已经崩溃,
de>RenderViewde>不会存在,因此,这也将恢复崩溃。
4. de>Navigatede>转发到de>RenderViewHost::NavigateToEntryde> 。该de>NavigationControllerde>存储该
导航项目,但它被标记为“等待”,因为它不知道是否会采取过渡(也许主机地址不能得到解析)。
5. de>RenderViewHost::NavigateToEntryde>发送de>ViewMsg_Navigatede>到新的渲染进程中的新的
de>RenderViewde>
6. 当被告知浏览时候, de>RenderViewde>可以浏览,可能会失败,也可能导航到其他地方(例如,如果用户
点击一个链接)。de>RenderViewHostde>等待一个从de>RenderViewde>发出的
de>ViewHostMsg_FrameNavigatede> 消息。
7. 当加载被WebKit接受时(服务器响应,并传送给我们的数据), de>RenderViewde>发送此消息,这个消息
在de>RenderViewHost::OnMsgNavigatede> 被处理。
8. 当点击链接时,并且浏览器以前没有访问到这个链接时候,该de>NavigationEntryde>与加载的页面更新,如
果导航是由浏览器初始化的,因为在启动的情况下,有可能已被重定向,改变了网址。
9. 该de>NavigationControllerde>更新其导航列表处理这一新的信息。
导航和会话历史
每个de>NavigationEntryde>存储一个页ID和一个历史状态数据块。该页ID用于唯一标识一个加载的页面,所以我们
知道哪些是de>NavigationEntryde>相对应的。当页被提交时候,页ID会被赋值,所以待处理的de>NavigationEntry
de>的ID会被赋为-1。历史状态数据仅仅是de>WebCore::HistoryItemde>序列化后的一个字符串。关于这个项目包括
像网页的网址,子窗体的网址,和表单数据。
1. 当浏览器发起的请求(在地址栏输入,或者点击后退/前进/刷新按钮时候)
1. 一个de>WebRequestde>是由代表导航以及一些额外信息,如页ID来记录访问历史。新的导航的ID为-
1。当访问旧的页面时,页面的ID是这个页面第一次访问时候的ID。这一额外的信息将被查询后,当加
载时提交。
2. 主de>WebFramede>被告知要加载新的请求。
2. 当渲染器启动请求(用户点击一个链接,JavaScript的改变位置,等等):
1. de>WebCore::FrameLoaderde>被告知,根据不同的的请求,调用不同的加载函数。
3. 在这两种情况下,当第一个从服务器发出的数据包被接收,加载被提交(不再“等待”或“临时”)。
4. 如果这是一个新的导航, de>WebCorede>将创建一个新的de>HistoryItemde>并添加到de>BackForwardList
de> ,一个de>WebCorede>类。这样,我们可以区分哪些是新的导航,哪些是历史会话导航。
5. de>RenderView::DidCommitLoadForFramede>处理提交的加载。在这里,前一页的状态存储在会话历史,

通过发送de>ViewHostMsg_UpdateStatede>消息。这将告诉浏览器来更新相应的de>NavigationEntryde>
(由de>RenderView'sde>当前de>page IDde>)与新的历史状态。
6. de>RenderView'sde>当前de>page IDde>被更新,以影响提交的页面。对于一个新的导航,新的唯一

de>page IDde>会被生成。对于会议的历史导航,这将是它第一次访问时候的最初分配的de>page IDde>,我
们在启动导航时候存储在de>WebRequestde>中。
7. 一个de>ViewHostMsg_FrameNavigatede>消息发送到浏览器,更新了相应的de>NavigationEntryde> (由
de>RenderView'sde>新更新的de>page IDde>标识 )与新的URL和其他信息。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多