WPA分析卡顿

这周一个同事电脑上出现了程序卡顿的情况,我去他电脑上看了一下现场。启动后做拖动窗口等操作,有一定概率发生卡顿。过一会又恢复正常。然后通过WPR工具抓到的性能监控数据文件,用WPA分析了一下。分析出当时系统确实很繁忙,CPU有几段时间几乎100%跑满了。因此我认为这不是死锁导致的卡顿,是CPU占用高导致的。如下图所示: 然而另外一个同事他得出了不同的结论,他认为程序卡顿直接原因并不是由于系统CPU... Read More | Share it now!

Chromium将拒绝第三方软件注入

Windows上有好几种代码注入的方式,一个软件被其他软件注入是比较常见的事情,比如输入法、杀毒软件。往往这些注入的模块导致了软件的不稳定性。Chrome统计大概有15%的的崩溃是由于第三方模式的注入导致的。中国环境更加恶劣,各种软件更加流氓,它们肆无忌惮的注入到你的程序中,甚至破坏你程序的功能。 Chrome... Read More | Share it now!

使用Tabhelper解耦WebContents

WebContents是Chromium里面非常核心的一个对象,它本身代表着一个tab页面。通过WebContents我们几乎可以涉及到所有重要的浏览器对象概念。WebContents如此重要,我们做Chromium开发的时候势必会跟它有很多交互。但是我们又不能对WebContents代码的本身做太多的修改。因为随着业务的发展,会导致WebContents的逻辑越来越多,最后代码膨胀,难以维护。所以需要设计一套机制来对WebContents的逻辑进行解耦。 实际上Chromium已经设计好了一套很好的Tabhelper机制来解耦WebContents。我们可以做到完全不用改的WebContents代码而扩展WebContents的逻辑。介绍Tabhelper机制之前我先介绍一下SupportsUserData机制,下面是简化的代码例子: SupportsUserData机制就是不通过增加类的成员变量,把一种类型的实例绑定到另一个类的实例上。以上例子是我们把NameData、AgeData这种类型的实例动态的绑定到Host类的实例上。这样做的好处一是我们不用修改Host类的代码可以动态扩展Host类的功能,具有扩展性,二是相比类变量会绑定到类的所有实例上,而SupportsUserData机制可以让我们有选择的绑到到类的某些实例上,更具有伸缩性。 Tabhelper就是基于SupportsUserData实现的。因为WebContents继承自base::SupportsUserData,所以它支持别的类的实例动态的绑定到一个WebContents实例上。通常一个Tabhelper继承自WebContentsObserver和WebContentsUserData,而WebContentsUserData继承自base::SupportsUserData::Data。通过继承自WebContentsObserver,它可以获得WebContents各种状态和事件。 当一个WebContents在CreateTargetContents里面被创建的时候,会在TabHelpers::AttachTabHelpers里面绑定上很多功能的TabHelpers。我们以页面上的查找框功能FindTabHelper为例子,FindTabHelper就是在这个时候被绑定到一个WebContents上面,并且TabHelper的生命周期归对应的WebContents管理。 除了这种在WebContents创建的时候就绑定上TabHelper,其实可以在WebContents的生命周期内通过CreateForWebContents随时绑定上一个TabHelper。只要有WebContents对象,我们随时可以通过FromWebContents获取到对应的TabHelper。 参考: https://chromium.googlesource.com/chromium/src/+/lkcr/docs/tab_helpers.md   ... Read More | Share it now!

HTML5支持更多音视频格式

HTML5引进了新的的<audio>和<video>标签,可以直接播放音频和视频。但是不同浏览器对音频视频的支持格式有所不同。比如Chromium浏览器不支持MP3、MP4格式,而Chrome却支持。根本原因是浏览器内核所依赖的FFmpeg编译开关不一样导致的的。 在Chromium代码工程的生成gn工程的时候加上以上两个值: 就可以让Chromium编译出来的浏览器像Chrome一样支持MP3、MP4格式格式了。 proprietary_codecs的作用是开启代码中的USE_PROPRIETARY_CODECS宏,使Chromium的代码支持更多的音视频解码格式。ffmpeg_branding则是作用于Chromium所依赖的第三方ffmpeg工程的代码,使之编译相关的支持代码。 Chromium的音视频解码是调用的第三方库ffmpeg。ffmpeg几乎支持所有的音视频格式,那么Chromium理论上也是可以支持所有的音视频格式的能力。实际上由于ffmpeg这个库很大,为了优化浏览器的体积,Chromium只编译链接了它所需要支持格式的相关代码,只占整个ffmpeg很小的一部分。 我以3GP格式为例,介绍如何让Chromium内核的video标签支持更多视频格式。 我们先编写一个测试3gp格式视频的html文件: 然后在MimeUtil::AddSupportedMediaFormats里面添加如下2行: 这是让浏览器能够识别Video标签中的video/3gpp。 3gp只是视频的容器格式,实际上的音频和视频的编解码器是有多种可能的。通过工具查看这个test.3gp的音频格式,如下: 这个的视频格式是mpeg4,是Chromium内核默认所不支持的。而音频格式是aac,Chromium内核默认支持。所以为了支持这个浏览器播放这个3gp文件,只需要添加mepg4的解码器相关的代码即可。所以我们修改一下Chromium代码编译ffmpeg的开关。 因为之前我们已经把ffmpeg_branding设置成”Chrome”,因此我们的的配置文件是third_party\ffmpeg\chromium\config\Chrome\win\ia32\config.h。 在这个config.h里面搜索关键词MPEG4,找到了#define... Read More | Share it now!

精简Chromium代码仓库进行维护与升级

Chromium的代码仓库很大,我最近更新了一下,现在git仓库里面pack文件已经有8.8GB了。然而网络又不稳定,要完整获取如此大的代码还是比较困难。 我最推荐的方式是用阿里云香港或者新加坡的服务器搭建VPN,连接VPN来获取代码。阿里云香港或者新加坡的的VPN速度很快很稳定,我自己这边下载代码的速度有2MB/s,非常快。 其次是搭建Chromium代码仓库的mirror。这种方法对服务器的配置要求很高,4GB的内存只能支持不超过2个人同时获取代码。维护也比较麻烦,要成功编译Chromium,除了Chromium仓库,还有各种第三方仓库还有其他文件都需要做mirror。 如果不是很需要Chromium代码的历史提交记录,我们可以从Chromium代码的一个tag里面拉出代码,再提交到我们的自己的git仓库里面。这样的git仓库有700MB左右大小,只有Chromium的十分之一。 比如我们从Chromium的60.0.3112.113... Read More | Share it now!