bye2018,hi2019

44次阅读

共计 4805 个字符,预计需要花费 13 分钟才能阅读完成。

辞旧迎新。
2018 的工作总结一直拖着拖到现在忍不下去了终于扣了半天扣出一个总结。
2018 年已经过去,回看,有努力,有成果,也有遗憾,有无奈。
由于不考虑 kpi,所以主要总结遗憾和无奈。
最大的遗憾
是立了一个为听障/视障人士开发更满足他们需求的功能交互的 flag,结果无疾而终。目前苹果手机做的相对比较好,但是价格较贵,听视障碍人士很多收入不高,android 手机价格相对便宜但是这方面做的不太好,第三方软件受限于权限问题,某些方面可能做不了系统厂家可以做的事。原因有很多成分,自己努力坚持不够吧。
最大的无奈是
在软件供应链上被巨头鄙视了。尽管做了很多努力,比如配套的生态,重点宣传等共赢措施。原因有很多成分,也许是自身体量的问题,巨头看不上,也许是沟通问题,没找对门路或者没能打动对方。
没有 bug 的一年,不是完整的一年,2018 年 bug 主要分布:

新需求产生的 bug 为 33%。
也就是自己作出来的问题占了 1 /3。可以理解。年度最作,录像防抖方案存在瑕疵,永远有 20 多帧视频 cache 在防抖模块里,只有在结束的时候才能 flush 出来,20 多帧视频在时间维度上差不多要 1 秒钟了,在结束之前音频相应的就多了 1 秒钟,而从录像的框架和编码的实现上都不会在兼顾这种奇葩情况上浪费时间,所以录像播放的最后 1 秒只有声音没有视频观看体验很不好。最终权衡再三妥协再三,最佳方案是,作了一个小模块 cache 音频 1 秒钟左右,结束的时候音频 cache 和视频 cache 默认被放弃,这样录出来的视频就非常同步了,虽然最后 800 毫秒左右会丢掉,这是综合最大效益的方案了,硬伤没办法。
传统框架上的问题为 27%。
不到三分之一,比如解码,播放,交互等等。
声音和音质的问题占了 15%。
包括测出来的和用户反馈的。视频图像质量的问题报告或反馈几乎没有 (彩条,绿屏,马赛克,不完整等属于视频图像解码显示问题不属于质量问题)。有 2 个原因,用户对视频图像质量的变化不敏感或者不挑剔,或者用户群还没有形成这样的意识环境,视频图片行业内容为王,有的看就行还要啥自行车,还有就是视频行业的内容巨头们也是很关注视频的质量的体验的,当然他们也关心带宽,所以他们提供了有前提条件的内容质量,但是也不尽然,最近在重温西游记前半部分,无论哪个档次画面都让我觉得还不如我小时候看的 crt 画面清楚。但是音质就不一样了,我们对声音更敏感和挑剔,一首 3 分钟的音乐,中间出现两次杂音或者卡顿之类的,就要骂娘了。可能还有部分原因是用户没有画质反馈入口,这个可以完善。
CTS/GTS/VTS 等问题占比 11%。
这是 google 为了保证 android 开放生态下系统服务一致性安全性等方面的强制措施。而且各种 TS 越来越多,收的越来越紧。好好搞,google 会考试的,考不过后果很严重的,上个月的搞完了吗,这个月还有,忙起来,省的你们闲得想自己搞个操作系统。
性能,功耗,稳定性占比 6%。
框架的性能,功耗在 cpu 一定的情况下 80% 是一定的,20% 可能存在优化空间。业务上的功耗性能问题会比框架要多得多。稳定性问题占了大部分,框架承上启下提供了一些服务,上层业务在框架上发展,框架的缺陷或底层缺陷导致的框架不可用或可用性变差,会表现在上层业务上,有些业务是系统业务会引发连串的系统问题导致系统不可用或可用性降低,用户体验变差,如果上层业务不受影响,谁管你框架的死活,当然这是不可能的,业务是鱼框架是水。
平台漏洞占比 5%。
单独拿出来是因为,这种坑太深太隐蔽,而且造成的后果比较严重。几家平台坑的各有特点,某家最坑,使用这个平台的客户较少,不过代码最干净,研发投入最大。这里要颁发两个年度最佳应用一个是海外的 sweetsanp,一个是酷狗音乐,它们暴露了两个很严重的平台漏洞。(1).sweetsnap 遇到的问题。是无法正常录像,框架层面也没有报告给 app,app 在这个过程中认为一切正常,调查发现 sweetsnap 在使用编码接口时,参数设置存在逻辑问题:它使用了 b frame,但是 b frame 个数为 0,而 p frame 的个数大于 0。首先,这样设置在编码原理上是有问题的,但是 mediacodec api 并没有显示的限制这种设置或者说明,那样的话增加了接口的复杂度,对开发者是不友好的,边界的检查放在了框架设置更底层的 hal 层,然后把结果逐层上报。这里平台上 v4l2 边界检查的逻辑出现了漏洞,放过了使用 b frame,但是 b frame 为 0,p frame 不为 0 的情况,没有正确上报问题,实际编码又没有成功。(2). 酷狗音乐遇到的问题。是功耗比正常数据大了 300 多 mA。看 systrace 统计,audiotrack 中的一个线程占有 cpu 时间异常,感觉在空跑。发现是 mMyCond.waitRelative(lock, paused_ns) 这个函数实效,进一步调查发现这个函数在应用处于 32bit 运行时失效,基本所有音视频第三方应用都是 32bit 运行时,都采用 audiotrack 输出声音,所有基本都有这个问题。用我们可以切换 32/64bit 运行时的 demo 发现,在 32bit 下也是这种失效情况,64bit 下函数有效,由于参数 paused_ns 数值比较大,加上 32bit/64bit 的差异,怀疑是溢出问题。最后发现 waitRelative 最终实现是 libc 的__pthread_cond_waittimeout 函数,超时参数在 32bit 下 CLOCK 设置为 REALTIME 时,会发生溢出,需要将 CLOCK 调整为 MONOTONIC。
开发者提出的问题占比在 3%。
但有一部分问题系统层面也不好处理或者没有义务处理需要开发者自己关注注意 api 的使用。一些 api 使用开发者很熟悉了比如 bitmap 用完要记得 recycle,culsor 要记得 close 之类的,网上类似的文章也一大堆,但是有些 api 或参数的使用注意事项几乎没有介绍。(1). 对于没有正确使用 api 的 android 设计了一些惩罚机制。应用开发者应该很清楚 exception 这个机制。在 android 除了 exception 机制之外其实还有其他提醒开发者的方式,比如 assert, abort 等,但是它们不像 exception 这么温柔了,直接用自杀的方式告诉你兄弟这样搞不对。比如 app 要录像,录屏的时候,分辨率宽高最好设置成 2 的倍数,也就是不要出现奇数,16 的倍数最好,方便底层编码工作,有些平台对不是 2 的倍数的情况,会直接在 native 层 abort 导致程序异常。而如果对多媒体视频不太了解的 java 工程师往往比较迷惑暂时找不到头绪。即使看到 native fatal backtrace。即使在 webrtc 这样非常流行的开源库里,在一个动态分辨率的调整的模块里也存在类似问题,它降低分辨率的算法是直接宽高各处以 2,这样降低分辨率的梯度不够平滑不说,如果分辨率处以 2 最后会变成奇数,造成兼容性问题。(2). 还有一种应用更过分,占着所有坑,别人来了没坑用。(2.1). 比如有些开发者,在自己的应用里,无限制的使用 mediaplayer 但短期内不释放,用了几个发现用不了。这是因为 mediaplayer 为开发者提供播放便利的同时,它也隐藏了很多细节比如解析解码等模块或资源的管理。一个 mediaplayer 对象的创建或使用就代表了一套解析解码等相关资源的分配,只有这个 mediaplayer 被释放了(不一定 java 对象被回收),这套资源才会回收释放,这也是 mediaplayer 提供 release 这个接口的设计初衷,让开发者尽早释放配套资源,可以在 java 对象被回收之前。如果这些配套资源都是软件的,在内存允许的情况下,理论上是不存在对象个数限制的,但是解码器有些是硬件的尤其常用的 h264,h265 等,硬件资源是有限制的,管理解码器的框架叫 omx,硬件解码器 omx 实例的个数是有限的。对于 h264 等格式 android 播放框架默认优先使用硬件解码,一个 mediaplayer 对象分配一个硬件解码器 omx 实例,但是有个数限制,超过个数分配不出来。而 android 框架上并没有硬件分配不出来转去分配软解码器的设计(如果这么做会产生另外一个困惑,开发者不知道你第 n 个解码器是软的还是硬的)。硬件解码器 omx 实例个数每个平台不一样最少的也有 2 个,最多的可能有 8 个,同时播放 2 个视频够了吧 (2 个 mediaplayer 对象),如果真有特殊需求,就不要用 mediaplayer 了,用 android 的 mediaextractor,mediacodec 去同时调用硬件和软件解码器,或者自己用 ffmpeg 实现解码播放。(2.2). 除了占着 mediaplayer 不放的,还有占着 audiotrack 不放的。而且是某些日活上亿超级应用,用户每天都会打开。有些定制系统为了用户体验追求快速启动,会把一些超级应用放进一个名单里,不会被真正杀死。audiotrack 也是有限的,最多 32 个,如果被超级应用全部吃掉,不释放或泄漏了,其他有音频输出需求的应用再也获取不到 audiotrack 实例,用户就听不到声音了,而且用户杀死也没用,因为它没被真正杀死。
my chaos monkey design
what is chaos monkey?
名字来源于 netflix 的一个开源项目 chaos monkey,该项目故意制造一些线上问题然后看整个系统包括软件,人员等的反应能力。逆向思维,值得学习。在这里是一套自动化测试体系,包含了对边界条件,性能,重点 api 等扫描的测试用例和自动化过程实现。是对 android 官方提供的资源的一个补充。
buster。
灵感也来源于 netflix 的 chaos monkey。在移动端实际工作中,经常会遇到一些逼近或突破软件系统极限的问题,对软件的边界设计是一个考验,也会暴露很多问题。这些问题,散落在各个模块的 bug 系统里,即使有关注也是各个模块人工跟踪可重复性差,并没有作为一类问题加以重视。buster 做的是,将这些问题作为一类问题,并且利用自动化的方式实现高可重复性,提高扫描或回归等测试效率。比如,一张巨大的图片,应用在前台解码时几乎会耗尽所有的内存,系统剩余可用内存会逼近 0。这个时候会发生一些不可以预期的严重问题,也许是前台应用会崩溃界面闪退,也许是其它模块内存得不到分配导致系统卡死等等。现实的场景有很多,比如微信朋友圈发图选图的时候打不开或闪退,文档或图库等闪退或导致系统卡死等等,这些地方都会去解码图片,如果解码列表里有一张巨大的图片就会发生这些问题。
chanpion。
关注框架重点 api 的性能,核心是它的 benchmarks,这些数据是通过对比不同平台,厂家,机型的出来的。属于同一代的平台会拿来进行比较,但是也要注意测试时,同一代的平台不同厂家产品,运行时的当前 cpu 频率,比如都是 660 的平台,同一测试场景结果差异比较大,要关注下当前 cpu 频率是否有差别,有些厂家会通过调频做一些加速。还有一个方法确定,就是把执行过程拆分成一个个原子步骤,每一步耗时,在总耗时少和总耗时多的产品上都统计出来,如果每一原子步骤耗时都没有异常大的说明你的这个过程问题不大,差异应该在不同产品 cpu 频率不同,反之如果在耗时多的产品上执行过程中某一原子步耗时过长,这里可能存在问题需要优化。
straight。
是 api 的 demo 实现,便于问题的验证和对比,也可以给开发者作为参考。主要是场景和 feature demo,更贴近于实际问题,是对 android api demo 的一个补充。比如,通过实现多路录音,来模拟录音的同时录像,voip 通话之类的场景。
展望 2019
less is more & slow down。一个词概括就是 focus,在有限资源的前提下,专注 1,2 件最有价值最有意义的事情。2019 我们还有机会吗,试过才知道。

正文完
 0