Xoom更新4.1.1

之前听说Android 4.1.1在Xoom上公开测试了,昨儿听说已经OTA了,于是去系统设置里检查更新,没有…… 去网上看,说可以清除Google Service Framework的数据再试。试了一次,果然刷出来一个更新,4.1.1的。Google这是故意的么…… 下完之后,更新,刚过百分之十几,就成了个倒了的Android的样子,上面还有个红色三角。 根据经验,反正是升级败了。重启,去/cache,发现recovery目录里有last_log。看最后说啥验证失败。 E: failed to verify whole-file signature E: signature verification failed Installation aborted 我一开始以为是更新包验证败了,但是弄到电脑上,能正常解开……(更新包就在/cache里,一个zip) 那估计和上次一样,因为这是个补丁包,所以要先验证源文件正确,才能打补丁,而某些文件可能被改过了,在Root或者别的时候。 这时候我想起来,上次见到过一个叫OTA RootKeeper的东西,可以在更新后保留Root,就去装了一个,打开之后,选保留Root以及暂时unroot。 然后重启到EOS Recovery,尝试装那个zip,果然有apply_patch_check失败的,首先是/system/bin/gzip。进去一看,貌似被改成了到busybox的链接…… 大约是哪个busybox安装器干的好事。从网上下了一个4.0.4的完整镜像,从里面扒出gzip换掉系统里那个符号链接,再试,这次换成了ip。重复操作,搞定了ping和toolbox之后,这次是boot分区校验和挂了…… 重启到fastboot,刷那个4.0.4镜像里的,再更新,还是不行…… 想想大概是4.0.4那个镜像的boot改过了,去下载的地方,发现是root过的镜像…… 搜了一圈,就是找不到没root过的4.0.4 boot分区。 网上的恢复办法都是刷回3.x然后一路更新上来,好像很麻烦…… 我想,可以弄来3.x的boot.img和之后所有的补丁,一路打上来,弄到一个4.0.4的boot.img,再刷进去…… 在xda的http://forum.xda-developers.com/showthread.php?t=1597609这个帖子里有个网站,里面有3.0.1的原始镜像和所有升级包。把镜像里的boot.img和升级包里的所有boot.img.p扒出来,然后就是咋打补丁的问题了。 我记得android里有applypatch,于是去android source里面找,果然有这个东西。尝试编译一份主机可用的,居然成功了,命令如下: 在applypatch目录里 gcc utils.c imgpatch.c bspatch.c freecache.c bsdiff.c main.c applypatch.c -o applypatch -I../../../system/core/include/ -I../ ../minelf/Retouch.c -lbz2 -lz ../../bootloader/legacy/libc/sha.c ../mtdutils/mtdutils.c 然后跑,发现命令格式挺简单,就是 applypatch …

Continue reading ‘Xoom更新4.1.1’ »

在FreeBSD上装linux skype 4

折腾了一个晚上好歹是搞出来了…… 起因是把linux_base更新到了linux_base-c6,也就是CentOS 6。这是个相当新的版本,各种rpm找起来也比较容易。 但是问题是,ports里其他linux包基本都是老的,要么是fc4的,要么是f10的…… 反正用不了。于是统统删掉。但是这样linux程序基本就跑不了,缺很多包…… 于是就自己搞rpm来装。但是rpm这回又不好使,试了ports里rpm3/4/5貌似都不行。 怀疑是因为rpm调了cpio,而FreeBSD 8-STABLE里的cpio貌似还不支持xz? 因为CentOS那些新包是xz压缩的,于是就解不了。 后来干脆不管rpm了,搞个脚本: if [ ! -f $1 ]; then wget http://mirror.yandex.ru/centos/6.2/os/i386/Packages/$1 fi rpm2cpio $1 | unxz > ~/tmp cd /compat/linux sudo cpio -idv < ~/tmpif [ ! -f $1 ]; then wget http://mirror.yandex.ru/centos/6.2/os/i386/Packages/$1 fi rpm2cpio $1 | unxz > ~/tmp cd /compat/linux sudo cpio -idv < ~/tmp …

Continue reading ‘在FreeBSD上装linux skype 4’ »

APK相关工具

昨天搞的时候很混乱,今天整理了一下,搞了个图: 具体可以参见wiki: APK (de)compile 大致上有很多办法可以改一个apk,总的来说有两个办法,一个是搞成 Dalvik VM 的汇编,然后改。一个是先从 Dalvik VM 的字节码搞成 JVM 的字节码,然后搞成 JVM 的汇编,甚至搞成 Java source code,然后改。改完了再倒回去,重新签名就是新apk了…… 另,Dia 真好用……

自己动手,丰衣足食

最近虾米Android用得不甚顺畅。主要问题是,拿着虾米Android听电台,听着听着,自动就关了…… 一般都是在启动别的程序的时候挂掉。各种程序都可能引发,用内存多的概率更大。有时候没动手机也会自己挂掉。 之前就怀疑是Android低内存自动杀进程功能干的。近日研究了一下: 首先,用ps | grep xiami列xiami进程。每次挂掉之后,列进程可以发现com.xiami那个进程不见了。过一会儿,这进程又会被重新启动起来。但是音乐播放不会自动恢复。 看系统信息里面,虾米总共开了俩服务,一个是push message receiver,对应ps里面那个com.xiami:push。另一个就是music play service,对应那个被干掉的com.xiami。 我印象里,Android里面开了服务,就不应该会被干掉,至少会比那些后台程序更晚被干掉。利用adb shell dumpsys meminfo,可以发现后台还有好多进程啊…… 仔细看一眼dumpsys meminfo的输出,可以发现当从xiami切到别的程序之后,xiami被列在了Background分类里,而其他的还有A Services和B Services。xiami占的内存也不少,系统想杀进程的时候,挑大的杀,于是就杀了虾米…… 于是首先是这么个问题:既然xiami开了服务,为啥会被扔到Background里去?继续观察,可以发现xiami被杀并重启之后,居然跑到了A Services分类里…… 这样就不会被杀了,问题是音乐也停了…… 为了研究到底杀了重启是啥样的过程,我去网上找了个ServiceDemo。实验后发现,对于一个普通程序,就算开了服务,切到后台也是Background。等到内存不够,系统会先杀了你,之后再启动一个进程来仅仅跑服务。这样或许Activity那边的内存就能释放了?一般杀之前不调onDestroy(),杀完重启的时候调onCreate()和onStart()。所以要适应这种情况,可以在onStart()里处理被杀了重启的情况,并且继续之前的工作。 但是我觉得其他音乐播放器不是这样啊…… 于是随便找了个音乐播放器,开了之后切到别的程序,再看meminfo。这样可以注意到,那个程序并没有被扔到Background里,而是在Perceptible里面…… 于是去网上看啥样的程序会变成Perceptible。虽然找到了ActivityManager里面IMPORTANCE_PERCEPTIBLE这个常数定义,但是没有哪儿告诉我咋样可以变成Perceptible。 既然这样…… 只能看代码了。正好机子上有之前下下来的Android 4.0代码,在里面找PERCEPTIBLE,于是在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java里面找着了。 貌似成为PERCEPTIBLE的条件是,某调整值>=PERCEPTIBLE_APP_ADJ。但是继续看代码,发现这个调整值会因为各种理由而决定…… 通过继续研究dumpsys,发现还可以dump别的,例如dumpsys activity就可以dump出activitymanager这边的信息。在这个信息中,就包括了调整值设置的原因。观察那个靠谱的音乐播放器,发现他Perceptible的理由是foreground-service。 其实如果熟悉Android Service的话,或许已经知道这是啥了。但是我不太熟嘛…… 继续看ActivityManagerService,发现这个原因的触发条件是有foregroundServices,而这个值唯一会变成true的地方只有updateServiceForegroundLocked(true)。而这个东西会在setServiceForeground()里被调用。这个东西貌似只有外部引用。到这里我终于跑到网上去搜foreground service…… 发现Service类有个startForeground()方法,那基本上就是这个了…… 根据Android的描述,普通Service还是会被干掉的,只是日后由内存了可能会重开你。但是Foreground Service是这种只要你一干掉用户立马会有反应的,所以会尽可能不去干他。 我在ServiceDemo里加了startForeground()调用,果然他也成了Perceptible,咋样都没被干掉…… 那,虾米是不是没有调用这个startForeground()呢?我跑去搞了个最近看见的Android反编译器,ded,是PSU的人做的…… 反编译出来,貌似的确没有startForeground()。但是有一个对setForeground()的调用,可惜是false。另外,在新版Android里,setForeground()已经没用了…… 这样就知道是虾米写得烂了,我试了几个音乐播放器,都会变成foreground service…… 不过倒是有个也败了的,那就是豆瓣…… 既然如此嘛,要不改虾米,要不改系统。我尝试修改了/proc//oom_adj,但是貌似系统不care这个。我尝试修改了/sys/modules/lowmemorykiller/parameters/minfree,改小了点,希望系统不要没事情杀进程。但是问题依旧,而且chrome启动还更卡了…… 那只好改虾米。那个ded貌似反编译有些问题,编译回去也不太行。上网上找找apk反编译,找到了apktool。 这个东西能够把apk完整的反编译成dalvik VM的汇编码,还能编译回去,真是不错…… 于是反编译出来,找合适的地方加。因为startForeground()还需要提供一个Notification,而虾米本身就会显示Notification,我希望最好还是用虾米原来的。 找了一下,发现虾米的Notification都是NotificationsUtil管的。里面有个notifyOnGoing(),貌似就是显示平时歌曲信息那个Notification的。于是我篡改了NotificationsUtil.notifyOnGoing()里面显示Notification那句。startForeground()是Service类的函数,需要Service对象,正好MusicPlayService被传了进来,于是我直接把 invoke-virtual {v2, p3, …

Continue reading ‘自己动手,丰衣足食’ »