管理Chromium源代码的利器——depot_tools

由于Chromium项目的代码量巨大,又依赖了很多第三方代码库,所以如何有效的管理这些代码是个难题。Chromium官方提供了一个depot_tools来管理Chromium源代码的工具,官方开发工作流也是基于depot_tools。最初接触depot_tools觉得它很难用,最近研究了depot_tools的代码,发现掌握了它能够让我们事半功倍。 配置depot_tools 因为我是在Windows上开发Chromium,所以只介绍Windows上配置depot_tools的流程。 根据https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up的介绍,从这里https://src.chromium.org/svn/trunk/tools/depot_tools.zip... Read More | Share it now!

获取代码运行所在模块的HMODULE/HINSTANCE的句柄值

最近看代码,遇到一个很有趣的问题:如何获取一个静态库代码链接进模块的句柄? 模块句柄值实际上是这个模块加载内存中的基地址。我们暂且放下这个问题,先看看动态库是如何获取句柄值的。 动态库获取句柄值 正常情况下一个动态库dll获取它的句柄,可以通过GetModuleHandle或者GetModuleHandleEx这个API来获取。 这个两个API都需要把dll模块名传进去才能获取句柄值。但是dll可能被人重命名,所以这个方法不一定百分百可靠。 另外一种办法是在DLLMain入口函数里保存hinstDLL值。但是不一定所有的Dll都有Dll,所以这个方法也是不一定百分百可靠。 还有种方法是调用VirtualQuery接口获取MEMORY_BASIC_INFORMATION值: MEMORY_BASIC_INFORMATION结构体里面的MEMORY_BASIC_INFORMATION.AllocationBase就是基地址,可以转换成模块的句柄。这个算是获取Dll句柄的终极办法了。但是这个办法毕竟有些hack,不到万不得已,就别用。 从http://www.codeguru.com/Cpp/W-P/dll/tips/article.php/c3635/... Read More | Share it now!

Chromium ICU库定制裁剪

ICU库是一个支持国际化,本地化的软件库。最近在研究ICU库,有点心得,总结一下。 ICU库功能介绍 支持最新的Unicode标准。 不同代码页的字符集转换。 本地化数据,如:数字、日期、货币等等。 语言相关的字符串处理,如:排序、搜索等等。 正则表达式支持。 语言转换。 阿拉伯语、希伯来语、印度语、泰语等文字排版。 文本分词。 编译步骤 Chromium项目中的ICU是经过Chromium开发人员精简过的,目前在Windows环境中无法成功编译。Chromium团队也是在Linux下编译,然后把文件Push到代码仓库中。 根据README.chromium文件中“Pre-built... Read More | Share it now!

windows环境下获取并编译v8引擎代码

这段时间在研究v8引擎,这个就是Chromium的Javascript的实现。接下来要写一系列的文章来总结学习过程。不过第一步是获取代码和配置编译环境。幸好v8获取代码和编译跟Chroumium很类似。 获取代码 假设你已经配置好gclient和网络能否访问google等网站了,获取代码就很简单了。在gclient的控制台窗口输入: 这个命令用来获取v8和它所依赖的第三方库代码。整个仓库大概有900多MB,你可以根据你的网速预估一下下载时间。相比Chromium仓库的体积来说,算是很幸运了。 然后运行获取最新代码: 运行命令同步所有代码,并生成编译工程: 如果需要获取所有分支,你在v8仓库的.git/config... Read More | Share it now!

Chromium进程模型

http://dev.chromium.org/developers/design-documents/process-models SiteInstance SiteInstance表示着一组之间有脚本联系的网页,从第一个网页开始,通过点击它页面上的超链接或者脚本代码打开的网页都属于同一个SiteInstance。比如用js... Read More | Share it now!

Chromium WebUI机制介绍

本文简要介绍一些Chromium WebUI的特点,然后分析其内部机制,最后介绍如何创建使用WebUI。 WebUI介绍 WebUI是通过本地的html网页来实现客户端的UI功能,把c++、html、css、js组织在一起,css,html做界面,js和c++做逻辑,灵活而又强大。chromium UI里面很多地方使用WebUI ,比如设置页面,flags开关页面,关于页面。我们在浏览器的地址栏中输入chrome://chrome-urls/,就可以看到更多的WebUI 链接页面。 Chromium之所以大量用到WebUI,我想有两个主要原因: WebUI界面看起来就像是新建了一个tab打开的一个网页,UI交互非常统一,也非常简洁 利用html构建UI,减少了开发跨平台UI的复杂性 WebUI机制分析 我们现在以chromium中一个简单而又典型WebUI页面chrome://version/为例子分析WebUI机制。 创建WebUI流程 在地址栏中输入chrome://version/与输入一个网址创建新标签页的基本流程是一致的。在地址栏中输入任何网址WebContentsImpl都会创建WebUIImpl 。如果在GetWebUIFactoryFunction中找到对应的chrome::kChromeUIVersionHost,就会创建对应的WebUIController——VersionUI,然后WebContentsImpl::CreateWebUI会判断WebUIController是否创建成功,如果创建失败则销毁WebUIImpl。 资源加载流程 WebUI的资源加载也是复用一般的网页网络请求机制,不同的是一般的http协议底层是用URLRequestHttpJob去做网络请求,而WebUI则是使用URLRequestChromeJob。 在地址栏输入一个WebUI网址chrome://version/,就会创建VersionUI对象,VersionUI会创建一个与当前host绑定的WebUIDataSource,并添加到URLDataManager中。当发起网络请求,URLDataSourceImpl根据host返回对应的资源,然后再当做response返回。 类图介绍 ChromeWebUIControllerFactory是创建WebUI对应的WebUIController。 VersionUI实现了WebUIController,会根据WebUI的网址创建一个WebUIDataSource。WebUIDataSource就可以添加WebUI所需要的前端资源文件。VersionUI同时也创建VersionHandler并添加到WebUI中。 VersionHandler继承自WebUIMessageHandler。通过WebUI的RegisterMessageCallback来注册回调,VersionHandler就可以处理来自前端的js的调用。 其实VersionHandler并非必须要创建,任何类都可以通过WebUI来注册js回调函数。WebUI类就是用来连接js与c++交互的纽带。 c++与js交互 c++调用js非常简单,直接通过WebUI的CallJavascriptFunction来执行js代码中的函数,比如: CallJavascriptFunction底层其实是调用的通用的RenderFrameHost接口的ExecuteJavaScript。 Js调用c++稍微复杂一点。 首先browser进程中通过WebUI的RegisterMessageCallback来向js暴露自己可被调用的接口,实现对应接口处理函数。之后js就可以通过chrome.send方法去调用c++中的接口。 在renderer进程里面WebUIExtension::Install通过v8创建一个chrome的js对象,并暴露出send,getVariableValue两个接口,注册接口的c++回调函数。js直接调用chrome.send,然后在renderer进程中对应的回调函数通过IPC把函数调用相关的信息发送到browser进程中的WebUIImpl中。 前端资源 WebUI的前端html网页元素扩展了三个属性:i18n-content、i18n-options、i18n-values。 i18n-content可以用来指定元素的文本内容。比如我们在c++中指定application_label的字符串内容为Google Chrome,html网页写成<td class=”label” i18n-content=”application_label”></td>,最终渲染出的html为<td class=”label” i18n-content=”application_label”>Google Chrome</td>。 i18n-options会生成一个<select>的<option>元素,具体用法搜索现有代码中的例子。 i18n-values会生成一个元素的属性和值的列表。比如<html id=”t” i18n-values=”dir:textdirection;lang:language”>。 扩展属性中的值是c++把数据生成strings.js,然后网页再从strings.js中加载。 创建WebUI chromium有篇文档介绍如何创建WebUI界面。但这个文档有些过时,有些地方已经改变了。我们通过创建一个计算两个整数和的WebUI例子来学习如何使用WebUI。 在这个例子中,我们打开chrome://calculator/页面,会有两个输入框让我们输入两个整数,点击等号按钮,前端获取到输入的两个整数,然后调用c++的cpp_add函数计算出和,然后c++再调用js里面的set_result方法设置结果到输入框。 添加前端资源 WebUI的前端资源文件一般放在src/chrome/browser/resources目录下面,我们在这个目录下新增一个如下内容的calculator.html文件: c++代码在创建WebUIDataSource中可以指定这个标示符对应的字符串值。 最终chromium会渲染出html网页,其中就会把IDS_CALCULATOR_TITLE字符串的值根据calculator_title放到title里面,最终网页渲染出如下效果: 还有点注意的是html中引用了很多框架的js文件,其中load_time_data.js要放在最前面,i18n_template2.js要放在body里面。 然后再添加一个如下内容的calculator.js文件: 然后在src/chrome/app/generated_resources.grd加入一些本地化的字符串资源: 然后把新增前端文件加入到grd文件中,根据之前文件的惯例,我们加入到src/chrome/browser/browser_resources.grd文件中: 增加c++处理逻辑 增加url 首先,我们定义WebUI的url,在src/chrome/common/url_constants.h中定义: 然后在src/chrome/common/url_constants.cc中定义: 然后创建我们的WebUIController,我们定义CalculatorUI: 增加WebUI c++实现 CalculatorUI的实现如下: CalculatorUI会调用CreateCalculatorUIDataSource创建WebUIDataSource: 创建WebUIDataSource要跟指定的WebUI的host绑定到一起。AddLocalizedString是添加一些本地话字符串,AddString是添加ascii字符串,SetJsonPath是设置生成数据的js文件名。AddResourcePath是添加其他js资源,SetDefaultResource是添加html资源。 CalculatorUI也会在构造函数里增加WebUIMessageHandler类CalculatorHandler,在这个类里面处理c++与js的交互: 然后把新增的c++代码文件加入到src/chrome/chrome_browser_ui.gypi中: 最终效果 最后我们打开chrome://calculator/,在第一第二个输入输入数字,然后点击等号按钮,就会在第三个输入框里得到前面输入的两个数字的和。 ... Read More | Share it now!