在中国使用chromium镜像

在中国,由于伟大的GFW的存在,使得我们开发人员备受折磨。如果仅仅是使用google搜索,使用普通的梯子,差不多可以应付。但是对于Android和chromium开发人员而言,动辄几十G的代码,没有一个很稳定的梯子实在不行。现代的SCM系统通常采用git,好处不必说了,但有一个重大的问题,不支持断点续传。也就是说,如果有10几个G的源码,下载到90%,突然断了,就前功尽弃了。偏偏GFW又格外努力,好好的梯子,说不定哪天就突然被封,通常越是出名,封锁的越厉害。

因为这几年一直在做浏览器开发相关的工作,对此有深刻体会。我们在公司内部为chromium的git库做了镜像,开发人员可以减少一些痛苦。然而chromium更新的相当频繁,我们做镜像也跟得相当痛苦。

不过现在好了,CodeAurora下的Chromium browser for snapdragon也做了chromium的镜像,而且非常贴心的在中国部署了镜像服务器。这个项目由高通资助,致力于浏览器在高通snapdragon芯片上的优化。如果你是在开发ARM上的浏览器产品,非常具有借鉴意义。

下面说明一下如何通过CodeAurora的镜像服务器下载chromium源码。在此需要说明的是,通过镜像服务器,下载源码是不需要翻墙的,但是在后面,有一些工具链什么的,还是需要从google的服务器上下载,仍然需要翻墙。不过此时的下载量较小,普通的VPN,比如GreenVPN可以应付的过来。

因为chromium browser for snapdragon项目fork自chromium,所以下载、build、安装等方法,和chromium项目基本相同,在此不多说,如果需要,请访问相关文档:

Environment Setup

Android Build Instructions

配置CAF镜像

1
2
3
git config --global url.https://source.codeaurora.org.insteadOf git://codeaurora.org
git config --global url.https://beijing.source.codeaurora.org.insteadOf git://codeaurora.org
git config --global url.https://beijing.source.codeaurora.org.insteadOf https://source.codeaurora.org

注:还有几个可选镜像,可根据实际情况选择上海或香港的镜像服务器,将上面的beijing替换为shanghai或hongkong即可。

选择活动的分支

截止写这篇文章为止,有三个主要的分支:

  • m52 beta分支
  • m46 正式分支
  • m42 维护分支,不建议在新项目中采用

考虑到chromium v52已经出来一段时间,趋于稳定,而且经过一段beta期后,很快就会成为正式版本,所以推荐使用m52分支。

m52下载与编译指南

  • 编辑.gclient文件,内容如下:
1
2
3
4
5
6
7
8
9
solutions = [
  { "name"        : "src",
    "url"         : "git://codeaurora.org/quic/chrome4sdp/chromium/src.git@refs/remotes/origin/m52",
    "deps_file"   : "DEPS",
    "managed"     : False,
    "safesync_url": "",
  },
]
target_os = ["android"]
  • 同步代码
1
2
3
4
5
6
export GYP_CHROMIUM_NO_ACTION=1 # don't process gyp
gclient sync
cd src
./build/install-build-deps-android.sh
. ./build/android/envsetup.sh
gn gen out/Default --args='target_os="android" is_debug=false'
  • 生成SWE浏览器
1
ninja -C out/Default swe_browser_apk

Android源码阅读与理解(二):Android系统Build流程详解

个人认为,成为一个靠谱的Android系统工程师,必须具备以下技能:

  • 翻墙
  • 会使用Linux系统
  • 阅读英文资料

翻墙技能就不用说了,因为不翻墙,Android源码难以获取,更不用谈体验墙外精彩的世界了。关于第二点,最好的Android系统开发环境就是Linux(推荐ubuntu),如果能够熟练使用Linux系统可以节省不少折腾环境的时间。最后英文阅读能力也很关键,因为碰到问题Google, StackOverflow非常有用,上面的回答有不少是用英文写的。

在这里略过下载Android源码,最好的方法是参考官方文档。简单说一下我的环境:

  • Ubuntu 14.04 LTS 64位
  • Android 5.1.1源码
  • Sublime Text 2
  • Intel® Core™ i7-2630QM CPU @ 2.00GHz, 8G RAM, 1TB hd

配备一台Nexus 4/5也是极好的,这个上淘宝,几百元就能搞定,可以省下不少时间(用模拟器也可以,但是比较慢,对主机要求也比较高)。Nexus系列作为google的亲儿子,通常都会得到最新的更新,最适合折腾系统了。

源码下载后,执行如下命令即可编译Android系统(后面的文章将使用$ANDROID_SRC指代Android源码所在目录,如非特别指明,假设命令行在Android源码目录下执行):

  1. source build/envsetup.sh
  2. lunch
  3. make -j4

下面就解析以上三个步骤分别做了什么事情。

设置环境变量

打开$ANDROID_SRC/build/envsetup.sh文件,我们可以看到文件中定义了一些shell函数,其作用是初始化编译环境,并引入一些辅助的Shell函数,这其中就包括第二步使用lunch函数。这些shell函数可以看做shell命令,方便我们进行一些build任务,比如常用的mm。下面就列出一些常用的函数:

表 1. build/envsetup.sh 中定义的常用函数


名称 说明
lunch 选择产品,格式为lunch BUILDID-BUILDTYPE,如果不指定,会弹出一个列表选择
tapas build未打包到image的app,命令行后可以跟一个或者多个app的名称。用法为: tapas [ …] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
croot 切换到源码树的根目录
m 在源码树的根目录执行 make
mm Build 当前目录下的模块
mmm Build 指定目录下的模块
mma Build 当前目录下的模块及所有依赖的模块
mmma Build 指定目录下的模块及所有依赖的模块
cgrep 在所有 C/C++ 文件上执行 grep
ggrep 在所有 Gradle 文件上执行 grep
jgrep 在所有 Java 文件上执行 grep
resgrep 在所有 res/*.xml 文件上执行 grep
sgrep 在所有源码上执行grep
godir 转到包含某个文件的目录路径
printconfig 显示当前 Build 的配置信息
add_lunch_combo 在 lunch 函数的菜单中添加一个条目

除了定义辅助Shell函数,在脚本的结尾处,还会遍历device和vendor目录下的vendorsetup.sh文件,vendorsetup.sh文件定义与设备相关的环境变量,比如/device/lge/hammerhead/vendorsetup.sh就定义了如下:

add_lunch_combo aosp_hammerhead-userdebug

这会在lunch菜单中增加一个选项:aosp_hammerhead-userdebug

lunch函数详解

Android支持不同的硬件,比如不同的CPU架构(ARM、MIPS,X86),不同厂商的外设(如蓝牙、wifi、基带等),另外可能还需要分Debug版本和Release版本,这都是在lunch中进行选择的。lunch命令的格式为lunch BUILDID-BUILDTYPE,其中BUILDTYPE取值如下:

表 2. BUILDTYPE说明


BUILDTYPE 说明
user 相当于Release版本,无root权限,不打包调试工具,适合最后的产品发布
userdebug 和user类似,但多了root权限,可以调试,适合于产品调试
eng 开发阶段的配置,另外还打包了许多调试工具,适合于产品初期阶段

BUILDID则是一组特性集合的代码,这个通常与具体的平台相关。除了Android源码预置的选项外,还可以通过add_lunch_combo命令添加自定义的组合。当我们要开发一款新的Android产品时,首先就需要在Build系统中添加对于该产品的定义。

产品定义文件通常位于device目录下,vendor目录已经不建议使用(nexus系列的产品定义就是放在vendor目录)。device目录下通常根据公司名及产品名分为二级目录,比如lge的目录结构如下:

1
2
3
4
5
6
 device
   |-- lge
         |-- hammerhead
         |-- hammerhead-kernel
         |-- mako
         |-- mako-kernel

其中mako和hammerhead分别为nexus4和nexus5的产品代号。通常一个产品定义至少包含4个文件:AndroidProducts.mk, BoardConfig.mk, vendorsetup.sh及版本定义文件(文件名不固定)。关于如何添加产品定义,请参考<<理解 Android Build 系统>>一文的添加新的产品一节。

build Android系统

最后一步执行make -j4才开始真正的进行编译操作,j后面的数字代表同时编译的job数,这个数字可根据CPU核心线程数而定,通常可指定为CPU核心线程的1~2倍,数字越大,代表同时进行编译的任务越多,整个编译过程也会越快,但需要注意过犹不及。如果不指定目标,默认就会使用“droid”目标,build出完整的Android系统镜像。

Android build系统使用了GNU make,这点很让人意外,因为GNU Makefile实在太难编写了,也不易阅读。不过Google的天才工程师进行了模块化、写了很多实用函数,修改/添加起来还算容易。

Build输出目录结构

所有的编译产物都将位于 out 目录下,该目录下主要有以下几个子目录:

  • out/host/:该目录下包含了host端的工具和库,例如:emulator,adb,aapt等。
  • out/target/common/:该目录下包含了针对设备的共用的编译产物,主要是 Java 应用代码和 Java 库。
  • out/target/product/product_name/:包含了针对特定设备的编译结果以及平台相关的 C/C++ 库和二进制文件。其中,product_name是具体目标设备的名称。

Build生成的镜像文件

Build 的产物中最重要的是三个镜像文件,它们都位于 out/target/product/product_name/ 目录下。这三个文件是:

  • system.img:包含了 Android OS 的系统文件,库,可执行文件以及预置的应用程序,将被挂载为根分区。
  • ramdisk.img:在启动时将被 Linux 内核挂载为只读分区,它包含了 /init 文件和一些配置文件。它用来挂载其他系统镜像并启动 init 进程。
  • userdata.img:将被挂载为 /data,包含了应用程序相关的数据以及和用户相关的数据。

另外还有cache.img,启动模拟器时可使用-cache参数来挂载该文件,指定/cache内容。一般来说我们不直接使用userdata.img,而是使用userdata_qemu.data,用来存放用户数据,可读写,android启动后mount到 /data。只有使用-wipe-data参数启动模拟器是时候才会用到userdata.img,它会使用userdata.img的内容覆盖userdata-qemu.img。

参考文档

  1. Android官方文档
  2. 理解 Android Build 系统
  3. Android编译系统详解(一)——build/envsetup.sh
  4. Android模拟器镜像文件介绍

Android源码阅读与理解(一):开篇

作为一个自认为苦逼的程序员,有一阵子曾考虑逃离程序世界,做一个文艺青年。你看,出去旅旅游、读读书、摄个影,没事发个呆,生活该是多么的惬意。反观程序员,每天对着冰冷的机器,有事无事还要加个班。正如一个段子所写:

你苦战通宵游戏时,布里斯班的灯鱼已划过珊瑚丛;

你赶场招聘会时,蒙巴萨的小蟹刚溜出渔夫的掌心;

你写程序代码时,布拉格的电车正摇着铃晃过金色夕阳;

你挤进汹涌的食堂时,哥本哈根的街头画家完成了第99幅立体画。

有一些穿高跟鞋走不到的路,有一些喷着香水闻不到的空气,有一些在楼宇里永远碰遇不到的人。

但是,看村上春书的《当我谈跑步时我谈些什么》如同嚼蜡,看侯孝贤、王家卫的电影直睡觉之后,我发现其实身上缺少文艺细胞,无事发呆更是让我难受。其实仔细想想,写代码时虽然苦逼,但是当纠出一个苦苦追寻了半个月的bug的时刻,内心还是感觉很爽的。不读村上春树,读读东野圭吾也挺开心的。每天充实的感觉比无所事事更舒服。所以,我还是需要做回自己,做自己喜欢、自己擅长的事情。读到池建强的《是旅行还是长跑》中这样一段话:

只要你没有一个强悍的爹,就要先忘掉那些小鱼小蟹,还有珊瑚丛,那些暂时还不属于你,踏踏实实地练习和提升才是王道,为自己规划一个十年的长跑,可以时不时停下来休息一下,低下头汗水就落入尘埃,抬起头就看看夕阳西下,你抹去疲惫,然后继续前行。十年看似很长,但实在很短,十年以后你回头看看,你究竟是成了人中龙凤,还是小鱼小虾,是你认知了世界,还是世界抛弃了你。

瞬间引起了共鸣。

闲话扯远了,作为一个国产OS的从业者,一直都从Android系统吸(chao)收(xi)营(yuan)养(ma)。其实我们更想借鉴ios系统,可惜人家不开源,光看表面是做不了神似的。在开发的过程中,也碰到不少问题,零零碎碎读过一些Android的源码,但基本上都是现学现用,缺乏整体的理解。既然做不了文艺青年,那我就来挑战一下Android系统源码吧。当然现在Android源码分析的书和文章也比较多,比如我手头就有邓凡平的《深入理解Android》、杨云君的《Android的设计与实现》和罗升阳的《Android系统源代码情景分析》,网上的文章更是不计其数。但别人分析了也是别人的,买了他们的书,但买不到他们的知识。还是需要亲自深入代码分析,知识才能变成我的。

在后续的学习中,我将结合自身的工作,分析我所感兴趣的部分。Android系统是一个相当庞大的系统,想要深入掌握每个细节,那是一个不可能完成的任务。所以我会略去驱动、linux内核、media等部分,初步计划阅读的部分如下:

  1. Android build系统
  2. Android系统启动
  3. Binder原理与实现
  4. Surface系统
  5. Dalvik虚拟机
  6. chromium Webview

为了让自己能坚持下去,要求在阅读过程中记笔记,每周至少写一篇博客,梳理一下阅读心得。希望我能够坚持下去并有所得,加油!

[注] 本文引用的文字出自池建强《MacTalk人生元编程》P.194。

基于chromium for android开发Android浏览器

在上一篇文章<< Chromium for Android开源了 >>中谈到了Google已经完全开源了Chromium for Android,这样我们就完全可以开发与Chrome for Android媲美的Android浏览器了。通常浏览器的一些新特性和新功能会先出现在Chromium for Android上,稳定后才会出现在Chrome for Android上,如果我们基于Chromium for Android开发浏览器产品,在新特性和新功能方面不会落后于Chrome浏览器.

Chromium开源项目的代码及其庞大,也相当的复杂。对于Android开发人员,特别是UI开发人员来说,没有一个合适的IDE环境,会是一个非常痛苦的事情。我们通常是这样开发的,在sublime text中阅读、修改代码,使用chromium的构建系统build出apk,安装到手机,进行调试。对于native代码来说,这样的开发方式也不会有太多麻烦,因为native部分的代码通常修改很少。但如果主要进行UI的定制,这种开发方式就非常痛苦了。

为了应对这个问题,考虑如下方案:

  1. 采用Android Studio作为开发环境,从Chromium for Android抽取chrome模块的源码,加入Android project。
  2. native代码在chromium环境中build,作为so加入Android project
  3. 基础模块(base, content, net等)在chromium环境build为jar包,加入Android project
  4. content, chrome, ui等模块的资源文件加入Android library project

资源文件为什么不能直接都添加到Android project呢?因为命名空间的原因,比如content模块的资源的命名空间为org.chromium.content, chrome模块的资源的命名空间为org.chromium.chrome,所以需要建立不同的Android library project, 指定不同的包名。最后整个项目的结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
browser
  |_ app
  |    |_ libs
  |    |_ src
  |         |_ main
  |              |_ aidl
  |              |_ assets
  |              |_ java
  |              |_ jniLibs
  |              |_ res
  |_ libraries
       |_ androidmedia_res
       |_ chrome_res
       |_ content_res
       |_ datausagechart_res
       |_ ui_res

注意事项:

  1. chromium项目的源码和资源有些是自动生成的,需要到out目录下去复制
  2. pak和dat等文件需要加入到assets目录,而且不能压缩
  3. aidl文件加入到main/aidl下,android studio会自动处理

实践证明,这种方案是行之有效的,请参考github上的项目: 365browser。在script目录下有从chromium项目同步代码和资源的脚本。

Chromium for Android开源了

最近一段时间都在忙其它的事情,没有关注chromium的最新进展。这几天浏览 http://www.chromium.org 上的文档,发现android build目标增加了一个:chrome_public_apk。编译方法:

Build the full browser

~/chromium/src$ ninja -C out/Release chrome_public_apk

~/chromium/src$ build/android/adb_install_apk.py out/Release/apks/ChromePublic.apk

搜索了一下相关新闻,大约在2015年5月份开始,chromium中开始加入了chrome for android的源码。从2012年开始,chromium中开始出现Android的移植代码,但只有Content API和ContentShell,离一个完备的浏览器还有一定的距离。当然,基于Content API开发浏览器也是可行的,当年就是这么干的。Chromium for Android和Chrome for Android并非完全一样,就如同桌面版Chromium浏览器和Chrome浏览器之间的区别。

下面放上一些Chromium for Android浏览器的截图,慢慢品味吧:

welcome

欢迎界面

account

帐号同步界面

main

浏览器主界面

menu

浏览器菜单

settings

浏览器设置

tabs

浏览器标签页

打造自己的chrome for Android

[注] 这是两年前写的一篇旧文,现翻出来,根据现在的实际变化作了修订。

chromium移植已经接近尾声,正在冲刺beta版本。不过越往后面,越是一些难啃的骨头。虽然背靠chromium这座大山,但是网页的复杂性超乎想象。更郁闷的是,有些BUG在chrome for android上没有,但在我们的浏览器上存在。因此经常会有这样的质疑:人家的chrome浏览器好好的,你做的浏览器为什么会有这样的问题。面对这样的质疑,真是有苦说不出。在有些人看来,别人都把源代码开放出来了,超过他们是理所当然的。没有办法,碰到难啃的骨头只能迎难而上了。好在chrome for android(V25之后的版本)开始支持自行定制了,虽然没法调试全部的代码,但是部分代码还是可以调试的。这样在分析我们和chrome浏览器在代码执行路径上的差异,也许能够提供一种思路。下面就谈谈如何构建自己的chrome for android。

  1. 使用您的android设备下载chrome for android,如果能够翻墙的话就在Google Play下载,国内的应用商店也一般有,这里就不详细说了。

  2. 打开您的android设备上的chrome for android,地址栏中输入chrome://version

  3. 记下Build ID(版本号ID)后的那一长串数字。

  4. 在PC机上访问 http://storage.googleapis.com/chrome-browser-components/<BUILD_ID>/index.html。其中<BUILD_ID>为步骤3中的ID。下载该页面所列的文件。以下将以$CHROME_PREBUILT指代所存放的目录。

  5. 下载与chrome for android版本对应的chromium源码,请参考[http://dev.chromium.org/developers/how-tos/get-the-code#TOC-Check-out-the-source-for-a-branch-or-specific-release]上的指导将代码切换到正确的release分支。下面就以$CHROMIUM_SRC指代chromium源码的src目录

  6. build出自己的libchromeview.so库

    • cd $CHROMIUM_SRC
    • mkdir chrome-android-prebuilts
    • cp $CHROME_PREBUILT/chromeview_target.gyp chrome-android-prebuilts/libchrome.gyp
    • mkdir -p out/Release
    • cp $CHROME_PREBUILT/libchrome_android_prebuilt.a out/Release
    • CHROMIUM_GYP_FILE=“chrome-android-prebuilts/libchrome.gyp” build/gyp_chromium
    • ninja -C out/Release libchrome_prebuilt
  7. 解包官方chrome的apk

    • 使用USB连接设备
    • cd $CHROME_SRC
    • mkdir out/apk
    • cd out/apk
    • adb pull $(adb shell pm path $CHROME_PACKAGE | sed ‘s/package:([^\r ]+).*$/\1/g’)
    • 将pull出的apk重命名为Chrome.apk
    • apktool d Chrome.apk

    注1:您也可以从网上下载Chrome for android,但要确保下载正确的版本

    注2:apktool 可以从http://code.google.com/p/android-apktool/ 下载

  8. 更新应用程序包

    • cp $CHROME_PREBUILT/change_chromium_package.py .
    • chmod a+x change_chromium_package.py
    • ./change_chromium_package.py -u Chrome -p desired_package_name -a desired_app_name
    • cp $CHROMIUM_SRC/out/Release/lib.target/libchromeview_prebuilt.so libchromeview.so
    • arm-linux-androideabi-strip libchromeview.so
    • cp libchromeview.so $CHROMIUM_SRC/out/apk/Chrome/lib/armeabi-v7a
  9. 重新打包和安装apk

    • apktool b Chrome Chromium_unaligned.apk
    • 签名apk,为了简便起见,可以使用debug key:

    jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore PATH_TO_ANDROID_SDK/.android/debug.keystore -storepass android Chromium_unaligned.apk androiddebugkey

    • zipalign -f -v 4 Chromium_unaligned.apk Chromium.apk
    • adb install -r Chromium.apk

到此,自有品牌的chrome浏览器就此诞生,您可以更换logo,修复chromium的bug等等。

如何打印gyp构建系统中的变量值

chromium项目使用了gyp构建系统,gyp的全称是”Generate Your Projects”。gyp构建系统使用的并不广泛,目前已知的只有chromium开源项目采用了这一构建系统。官方虽然也有一些文档,但都是一些比较基础的指南,总体来说缺少详细的文档来指导开发人员在项目中使用。 因为研究chromium的缘故,所以对gyp构建系统也有一些了解,在使用中也碰到一些问题,本文所要探讨的是如何输出gyp的变量值。这个问题的场景是这样的:在gyp中定义了变量,但是经过多重gypi包含,在别的gyp文件中可能对变量值进行了赋值。处于调试目的,我们希望输出gyp变量的值。

方法看起来很简单,但也摸索了很久。方法如下,在gyp中合适的位置加入如下代码:

'variables': {
  'mytest': '<!(echo <(variable) 1>&2)',
}

其中’mytest’是我随便定义的一个变量值,variable是希望打印的gyp变量。比如以下语句:

'variables': {
  'mytest': '<!(echo <(OS) 1>&2)',
}

输出如下结果:

Updating projects from gyp files...
android
gyp: Call to 'echo android 1>&2' returned exit status 0.

从上面的输出可以看出,OS的变量值为android。

在Chromium for Android中能否用TextureView替代SurfaceView

在开发Browser 2.0时,碰到一个非常头疼的问题,往布局上添加SurfaceView时,会引起黑屏闪一下。为了解决这个问题,我们不得不在初始化阶段就把SurfaceView添加好,之后也不能调整大小、移动位置。当时就考虑是不是能够用TextureView替代SurfaceView,不过由于计划上的调整,没有做进一步的尝试。今天在网上看到这篇文章,正好解答了我的疑问,在此把文章翻译过来,供参考。

Android SurfaceView和textureView

本文将简要介绍SurfaceView和TextureView的不同之处

SurfaceView和TextureView

SurfaceView和TextureView都继承自android.view.View类,他们都可以在另一个独立线程中绘制和渲染,这是和其它View的最大不同。Crosswalk采用这一分离绘制特性,独立的GPU线程显著提高了渲染效率。

SurfaceView提供一个嵌入在视图层次上的专用绘制表面,您可以控制该表面(Surface)的格式和尺寸。SurfaceView负责将表面放置在屏幕上正确的位置。它的行为多少有些类似于传统桌面系统上的onscreen窗口,比如,X11系统中的XWindow可以是无边框的,嵌入在另一个XWindow中。

SurfaceView存在如下两个缺点:

  • 不能应用动画、变换和缩放
  • 不能叠加(Overlay)两个SurfaceView

TextureView看似更像一个通用的View,可以应用动画、变换和缩放,就如同TextView。TextureView只能用在硬件加速的窗口。但是,TextureView比SurfaceView更耗内存,而且可能会有1~3帧的延迟,请参考讨论3

使用可以动画的XWalkView

Crosswalk Embedding API for Android很好的支持了SurfaceView和TextureView。XWalkView缺省使用SurfaceView,也允许您在以下情况下使用TextureView:

  • 您想让XWalkView支持动画和变换
  • 您想叠加两个XWalkView

设置布尔标识ANIMATIBLE_XWALK_VIEW为true即可启用TextureView。

  1. http://developer.android.com/reference/android/view/SurfaceView.html
  2. http://developer.android.com/reference/android/view/TextureView.html
  3. https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/Z0yE-PWQXc4

文中提到的讨论起源是在google groups中有人提出如下问题:

在当前ContentViewRenderView实现中,使用SurfaceView作为合成表面(compositing surface),如我们所知,SurfaceView是一个特别的视图,无法进行动画或者变换。

TextureView可以做SufaceView同样的事情,比如,您可以在另一个独立线程中渲染,也可以从底下的SurfaceTexture创建一个egl表面(eglSurface)。更主要的是,TextureView可以进行动画和变换。

我很好奇为什么不使用TextureView作为合成表面,是否TextureView在使用上有一些特别的考虑,比如性能问题?欢迎任何讨论。

Google groups有人做如下回复:

事实上chrome过去使用TextureView作为合成表面,但我们出于几个原因切换到SurfaceView:

  • 由于失效(invalidation)和缓冲的特性,TextureView增加了额外1~3帧的延迟显示画面更新
  • TextureView总是使用GL合成,而SurfaceTexture可以使用硬件overlay后端,可以占用更少的内存带宽,消耗更少的能量
  • TextureView的内部缓冲队列导致比SurfaceView使用更多的内存
  • TextureView的动画和变换能力我们用不上

所以结论是Chromium for Android中可以使用TextureView替代SurfaceView作为合成表面,但带来的后果是占用更多的内存,性能下降。

关于Ubuntu菜单项中的%U参数

今天在研究chromium deb打包的时候,发现Google Chrome deb包中的/usr/share/applications/google-chrome.desktop文件定义入口为:

1
Exec=/usr/bin/google-chrome-stable %U

这个%U参数是做什么用的呢?查找了一下资料,有如下描述:

1
2
3
%u A single URL. Local files may either be passed as file: URLs or as file path.

%U A list of URLs. Each URL is passed as a separate argument to the executable program. Local files may either be passed as file: URLs or as file path.

也就是说,加入了%U参数,可以传递多个URL给Chrome浏览器,浏览器会依次打开各URL。比如您在文件管理器中选择了多个html文件,然后在鼠标右键菜单中点击”Open with Google Chrome”,Chrome浏览器就会依次打开所选的网页。

以下是Exec支持的参数说明,来自http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Code Description
%f    A single file name, even if multiple files are selected. The system reading the desktop entry should recognize that the program in question cannot handle multiple file arguments, and it should should probably spawn and execute multiple copies of a program for each selected file if the program is not able to handle additional file arguments. If files are not on the local file system (i.e. are on HTTP or FTP locations), the files will be copied to the local file system and %f will be expanded to point at the temporary file. Used for programs that do not understand the URL syntax.
%F    A list of files. Use for apps that can open several local files at once. Each file is passed as a separate argument to the executable program.
%u    A single URL. Local files may either be passed as file: URLs or as file path.
%U    A list of URLs. Each URL is passed as a separate argument to the executable program. Local files may either be passed as file: URLs or as file path.
%d    Deprecated.
%D    Deprecated.
%n    Deprecated.
%N    Deprecated.
%i    The Icon key of the desktop entry expanded as two arguments, first --icon and then the value of the Icon key. Should not expand to any arguments if the Icon key is empty or missing.
%c    The translated name of the application as listed in the appropriate Name key in the desktop entry.
%k    The location of the desktop file as either a URI (if for example gotten from the vfolder system) or a local filename or empty if no location is known.
%v    Deprecated.
%m    Deprecated.

Ubuntu 14.04 VirtualBox启动问题之解决

开发机上的Ubuntu从12.10升级到14.04后,发现VirtualBox无法启动,有如下提示

1
2
3
4
5
6
Setting up virtualbox (4.3.10-dfsg-1ubuntu3) ...
 * Stopping VirtualBox kernel modules                   [ OK ] 
 * Starting VirtualBox kernel modules
     * No suitable module for running kernel found
                                                        [fail]
invoke-rc.d: initscript virtualbox, action "restart" failed.

解决方法如下:

1
2
3
sudo apt-get purge virtualbox
sudo apt-get install linux-generic linux-image-generic linux-headers-generic linux-signed-generic
sudo apt-get install virtualbox

安装irtualbox的信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  virtualbox-dkms virtualbox-qt
Suggested packages:
  virtualbox-guest-additions-iso vde2
The following NEW packages will be installed:
  virtualbox virtualbox-dkms virtualbox-qt
0 upgraded, 3 newly installed, 0 to remove and 29 not upgraded.
Need to get 0 B/20.5 MB of archives.
After this operation, 84.1 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
WARNING: The following packages cannot be authenticated!
  virtualbox virtualbox-dkms virtualbox-qt
Install these packages without verification? [y/N] y
Selecting previously unselected package virtualbox.
(Reading database ... 276049 files and directories currently installed.)
Preparing to unpack .../virtualbox_4.3.10-dfsg-1ubuntu3_amd64.deb ...
Unpacking virtualbox (4.3.10-dfsg-1ubuntu3) ...
Selecting previously unselected package virtualbox-dkms.
Preparing to unpack .../virtualbox-dkms_4.3.10-dfsg-1ubuntu3_all.deb ...
Unpacking virtualbox-dkms (4.3.10-dfsg-1ubuntu3) ...
Selecting previously unselected package virtualbox-qt.
Preparing to unpack .../virtualbox-qt_4.3.10-dfsg-1ubuntu3_amd64.deb ...
Unpacking virtualbox-qt (4.3.10-dfsg-1ubuntu3) ...
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
Processing triggers for ureadahead (0.100.0-16) ...
Processing triggers for hicolor-icon-theme (0.13-1) ...
Processing triggers for shared-mime-info (1.2-0ubuntu3) ...
Processing triggers for bamfdaemon (0.5.1+14.04.20140409-0ubuntu1) ...
Rebuilding /usr/share/applications/bamf-2.index...
Processing triggers for desktop-file-utils (0.22-1ubuntu1) ...
Processing triggers for mime-support (3.54ubuntu1.1) ...
Processing triggers for gnome-menus (3.10.1-0ubuntu2) ...
Setting up virtualbox (4.3.10-dfsg-1ubuntu3) ...
 * Stopping VirtualBox kernel modules                                                                                                                                                                 [ OK ] 
 * Starting VirtualBox kernel modules                                                                                                                                                                         * No suitable module for running kernel found
                                                                                                                                                                                                      [fail]
invoke-rc.d: initscript virtualbox, action "restart" failed.
Processing triggers for ureadahead (0.100.0-16) ...
Setting up virtualbox-dkms (4.3.10-dfsg-1ubuntu3) ...
Loading new virtualbox-4.3.10 DKMS files...
First Installation: checking all kernels...
Building only for 3.13.0-46-generic
Building initial module for 3.13.0-46-generic
Done.

vboxdrv:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.13.0-46-generic/updates/dkms/

vboxnetadp.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.13.0-46-generic/updates/dkms/

vboxnetflt.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.13.0-46-generic/updates/dkms/

vboxpci.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.13.0-46-generic/updates/dkms/

depmod....

DKMS: install completed.
 * Stopping VirtualBox kernel modules         [ OK ]
 * Starting VirtualBox kernel modules         [ OK ]
Setting up virtualbox-qt (4.3.10-dfsg-1ubuntu3) ...

这个时候virtualbox可以启动了。但是建立了虚拟机后,启动虚拟系统时提示:

1
VT-x is disabled in the BIOS 

解决方法:

1
2
3
4
5
6
7
8
重启系统
长按 DEL 进入 BIOS
方向键切到 BIOS Features
选中如下选项
Intel Virtualization Technology

选择 Enable
按下 F10 保存并重启

因为各个机器的bios设置并不相同,请根据自己电脑的设置查找“Intel Virtualization Technology”, 大部分电脑默认是Disable的。