Home - zhonglong/TPV GitHub Wiki

2012

十一月初入职,工作是Android智能电视软件开发,参与的第一个机种是Philips 7730(Panasonic sld3,Android 4.0),负责的应用是手机遥控器服务端。客户端是基于开源的Anymote修改的,但是服务端不开源,传闻是公司的牛人(已离职)反编译Gooogle TV遥控器代码写出来的。到我入职的时候,接手的是接近完成的源代码,主要维护和增加电视控制接口,并陆续删除已弃用的代码,以免被这些无用的代码干扰。

此外,还参与SmartEPG(电子节目单)前期开发工作,这个应用是从网络(TV猫)下载电视节目单,并在手机上展示,最初的目标是融合到手机遥控器中,选择节目自动换台。由于TV猫对节目内容报价高达一年几十万,超出费用预算,导致此功能最终被砍掉。

2013

年后,由于人员变动,手头的工作增加浏览器和手势教学两个应用,都是维护前人的代码。浏览器是基于Android原生代码修改的,主要为各主流网站定期适配User-Agent以实现在电视上的最佳显示效果。手势教学用于引导用户通过手势控制电视,并根据用户操作进行反馈,主要是手势控制引擎接口不稳定,配合联调。

芯片厂商升级Android 4.2版本,开始了第二个机种Philips 8830(Panasonic sld3,Android 4.2),我负责将组内几个应用(除了前面提到的还有媒体中心和Launcher)的升级工作,面临的主要问题是多用户限制,作为系统应用需要用AsUser的接口去访问Activity,Service和Broadcast,并注意多用户下后台服务是否会冲突。此外就是外置存储区分用户,每个用户只能访问自己的私有空间,主要影响媒体中心这个应用。

多用户下一个新功能是结合面部识别引擎,为每个用户录入人脸,一旦摄像头识别到人脸则自动(或提示)切换用户。

第一个全新开发的应用是媒体扫描服务,用于替换Android原生的MediaScannerService,主要解决两个问题:一是媒体扫描过程中拔出USB设备,易出现MediaScannerService停止运行,导致media进程停止运行,解决办法是将媒体扫描服务指定到独立的进程中;二是原生的媒体扫描会解析很多数据,如果USB设备内媒体文件很多,会导致扫描耗时,而且扫描过程中系统非常卡,新的扫描服务大幅减少媒体文件属性,只根据界面需求做解析。

端午节前还为每年一度的董事会做demo,应智能家居的热点,结合Philips Hue和电视独有的流光溢彩(Ambilight)功能,设计的一个场景。在电视播放图片时,会提取当前图片的主色,设置给流光溢彩和Hue,最终环境光会呈现与图片相似的颜色。那个时候,Hue官网还未发布SDK,只能通过原始的HTTP RESTful API来控制Hue,以及使用UPnP协议来发现Hue Bridge设备。

由于公司有ODM业务,之前开发的应用也给其他品牌使用,如Haier和Panda,界面稍作修改,替换品牌LOGO就可以用于另一个项目。为了方便移植和开发调试,还将很多应用,如手机遥控器服务端,浏览器,输入法等改为Eclipse编译(引入frameworks.jar),而之前由于需要调用系统隐藏接口不得不在Android源码下编译。除此之外,为了平台兼容性,将部分接口改为反射的方式调用,尽可能用一套代码兼容更多平台和项目。

下半年最重要的是Philips 9340机种(MStar 818,Android 4.2),导入全新一代Ebony 2k14 UI,完全复制欧洲飞利浦风格。最初我负责的是手机遥控器服务端,浏览器和流声闹钟三个应用(手势教学因为手势控制太小众已放弃)。手机遥控器主要增加了Push URL和Take-away功能,支持大屏(电视)和小屏(手机)之间联动。浏览器改为基于Android 4.2原生代码修改界面,支持用按键控制屏幕鼠标操作。流声闹钟除了传统的闹钟功能,还结合流光溢彩的特性,闹钟响起时电视背面灯带会发光联动。

由于Ebony 2k14 UI整个开发过程时间短,工作量大,也被抽调给其他人打打杂。例如媒体中心的播放列表管理,设置中的网络设置等等,结识了更多同事,也有助于去了解不同领域的应用。网络设置算是这一年写的最失败的代码,那时候还停留在调用接口的理解,没有意识到网络状态本身是个庞大的状态机,有很多广播事件需要处理,导致测试过程中出现很多bug,其中网络连接方式(WiFi,WiFi-AP,WiFi-P2P)切换的流程近乎被重构。

2014

年后主要就是Ebony 2k14 UI一套应用的维护,期间由于某同事怀孕休假,手头又多了电视设置这个应用。为了满足每周一版的迭代,还时常帮忙解决其他应用的问题点,一直戏称至少一半应用都有我的提交记录。

当Ebony 2k14 UI软件质量稳定后,开始向各衍生机种移植,最痛苦的是那些低端机。出于硬件成本考虑,公司大量推出低端机,512M的内存对很多应用流畅运行都是挑战,那段时间学习了很多应用优化的知识。

除了单纯的电视销售,公司也陆续有跟内容绑定的需求。第一次尝试是跟青岛联通合作的案子,公司负责STB端,对接华为的OTT平台。除了一个完整的Wireshark抓包,几乎没有文档,前期折腾了很久。后来我加入,负责鉴权功能,有前一家公司处理运营商(中国移动手机视频)鉴权的经验,轻车熟路地完成。后来由于运营商换老板这种狗血的理由,这案子最终还是黄了。

Ebony 2k14 UI的电视,在大陆市场反响还不错,带动电视销量提升,于是公司开始规划更庞大的Tile 2k15 UI系列。这是一套全新设计的UI,规模比上一代至少大一倍,除了传统的电视功能,加入了大量个性化和社交应用。这套UI的设计时间非常长,经历多次评审会议,甚至推倒重来,目标和方向迟迟未定,恐怕也成为失败的原因之一,这是后话。

新的一代UI,我负责或参与的应用更多了,这时候也有了两个下属(虽然一个没多久就开始休产假),开始考虑设计和任务分工的事情,但是开发工作还是占大多数。我负责主要包括开机向导,电视设置,语音助手,SocialTV;另一位同事负责账户管理和网络设置。

开机向导总体架构比较简单,各界面独立适合并行开发。大部分都直接调用系统或芯片的设置接口。除了网络设置需要关注系统广播,有了上一代应用的开发经验,做得比较顺利。电视设置主要功能也是调用接口,但在界面上做了些封装,可以方便切换不同平台的接口,因为此时最终用哪家的芯片还没确定。

语音助手通过百度SDK完成语音识别(NLU),解析出用户意图后,跟电视的其他应用进行通信,获取相应数据再通过语音播报反馈给用户。这个应用的难点在于庞大的应用间通信,需要跟十几个应用打交道,例如天气,浏览器,搜索,电视,媒体中心等等。采用Bound Service和Messager减少对AIDL的依赖,适应接口的需求变化。

SocialTV是一个全局的服务,支持其他应用调用,将电视节目,媒体文件,截图等分享到QQ和微博等社交平台,主要涉及浮动窗口的管理,以及各社交平台SDK的接入。

这一代产品还用蓝牙遥控器替代传统的红外遥控器,于是涉及到蓝牙遥控器的配对,以及查找遥控器的功能,主要跟遥控器方案厂商的联调。新的遥控器还支持挥动遥控器手写数字换台,电视端采用GestureOverlayView和GestureLibrary实现,预训练手写模型后单个数字的准确率还是蛮高的,有些后来机器学习的雏形。

2015

由于上一年的Tile UI 2k15迟迟无法落地,虽然在MStar芯片上开发的,但实际量产芯片选型从高通,到MTK都无法确定,最终再回归MStar芯片时,功能砍了很多。以AOC PDL960机种(MStar918,Android 4.3)作为实际量产,功能也只保留开机导览,电视和网络设置,以及简化的语音助手(替换成Nuance方案只保留简单控制命令,不支持NLU)。

这一年Philips品牌也推出全新一代的Ebony 2k15 UI,导入Philips 6850机种(MStar918,Android 4.3),负责的应用只有一个:录影和提醒,依然涉及到诸多电视接口,例如频道,节目,录影。这个案子碰到了一个大坑是电视时间,由于电视会从信号源中更新系统时间,而码流仪和工厂信号时间上又有所不同,其中一个会在某个时间段内循环,导致预设的录影无法触发。系统端无法给出解决方案,只能在应用层同时采用多种计时方式来规避。

在两个机种接近尾声的时候,部门组织结构和业务开始大调整。我们整个开发组转做Philips品牌Android手机软件开发。

相较于电视软件的各种仓促,手机的软件明显更加谨慎,主要修改界面符合大陆使用习惯,并未对功能做太多增减。规格文档以Excel方式维护,每一条都附上开发人员的分析,确认技术方案。正式开发前也做过多次预研,从Android 4.4(Philips V387),到Android 5.0(Philips S616),最终到Android 6.0才定案。虽然由于MTK架构变化,例如Android L引入的MPlugin做了些无用功,但总的来说,到Android 6.0第一个正式版(称为Freely UI 1.0),软件已经比较稳定。

手机端我负责电话应用的客制化,电话应用由于其特殊性,与芯片强相关,只能在每一代芯片厂商提供的公版代码的基础上再做修改,对阅读代码和背后的领域知识都有较多要求。

整个电话开发过程中遇到的最大难题是三合一功能,即在界面中同时展示电话,联系人,短信三个列表,最终的方案是以电话为基础,将联系人和短信列表界面从原来的应用中抽出来,合并到电话应用,同时处理大量Plugin代码的冲突。MTK提出MPlugin架构本来是减少客制化的工作,但因为Plugin接口与模块强绑定,结果在三合一过程中反而增加更多的工作。

手机软件的开发,我带两个人负责联系人和短信,两个应届生。因此在原生代码结构方面需要给他们更多指导,帮忙解决一些难点问题。好在两个少年都比较勤奋,很快也能独当一面。

2016

上一年大体上完成Freely UI 1.0(Android M)的开发工作,年后经历几轮版本迭代陆续开始导入量产,最终定的是Philips S653(MT6755)和Philips X818(MT6755)。这两款手机一开始面向大陆市场,分别在天猫聚划算和京东首发,结果S653因为轻薄外观而减少电池容量导致续航不足;X818因为采用玻璃后壳导致良品率低,都没有在大陆市场取得成功。

于是X818开始面向海外市场,推出俄罗斯,东欧,越南,以及拉美等市场,后来的Philips手机也主要面向这些区域,大陆市场只有零星几款做尝试。

由于Freely UI 1.0界面上的特点不够鲜明,很快Freely UI 2.0(Android M)提上日程。这一代系统的蓝色调更明显以强调商务风,主要开发工作集中在调整界面。另一个改动是导入主题市场,可通过切换主题来替换界面的图标和颜色,这个功能做在framework层,通过Resources去载入主题包。

对电话来讲,Freely UI 2.0只增加通话录音管理,但界面变化较大,整体来说显得更方,用圆角矩形元素替换原生的椭圆(如Switch);以及大量渐变色和阴影的使用,对主题和样式修改较多。

这一年重点抓软件质量,引入Sonar代码静态检查,代码review会议,重大问题点lesson learn等多种方式,来帮助开发人员提升代码质量。

随着内部合并和新员工的招募,我的团队规模达到十人,除了电话/短信/联系人外,组内还负责Launcher,系统界面,开机向导,相机,音乐,天气等应用。总体采用一人一个引用的原则,按成员的资深程度和应用复杂度分配,减少内部相互推诿。由于工作量和工作成果比较同意评判,在管理上并不需要投入太多精力。

2017

Android 7.0芯片厂商提供公版代码后,例行的工作就是各应用的移植,由于没有增加新功能,此时版本定为Freely UI 2.5,仍在X588手机上开发,用于OTA升级。虽然功能不变,但Android 7.0 Dialer代码与前一代相比差异不小,大量support包的引入,定制过程中重写了不少代码。另一项修改是支持分屏功能,原先定制的界面在分屏模式下会显示异常,甚至导致应用崩溃。

在Freely UI 2.5上新的功能是简易模式的开发,主要是为了推出老人机,满足市场需求。简易模式的电话主要包含通话记录,拨号盘和来电语音播报,都是全新开发,只有通话界面必须做在默认电话应用(即Dialer)内。此时,Dialer本身的MVP设计模式也有所体现,同一个Presenter,只需要载入不同的View,就能切换标准模式和简易模式。从这个方面讲,修改代码的过程中,也是在学习Google原生优秀的编程方式。

Freely UI 2.5没有对应对应全新的机型,只能以OTA的方式导入X818和X588手机。同时由于X588手机在成本,性能和续航方面做了比较好的平衡,市场反馈还不错,因此推出了大陆销向,期间主要处理CTA认证反馈的问题点;同时也推出中国移动运营商定制机型,此后面向大陆市场的机型都由外包案占据。

在熟悉了Android 7.0代码后,很快开始了Freely UI 3.0的开发工作,以X828(MT6755S,Android 7.0)为主导机型。Freely UI 3.0主要对界面细节要求更严格,本身不再加入新功能。

因为电话应用对芯片依赖较大,在某款芯片源码上编译的APK无法直接用于其它芯片,限制了外包案的使用。于是出现了一个折中的方案,功能还是按照公版来,但是界面改为Freely UI风格,提出了电话换肤的需求。电话换肤在公版代码的基础上,修改界面主题和样式,并替换一些图标,然后将修改内容仿照MTK patch的方式提供给各家外包商。

产品部门为了凸显Philips手机的亮点,提出了SmartCover功能。这是一个皮套,正面有镂空的小窗口和实体按键,目标是在不打开皮套的情况下,将手机当功能机使用。这又是个庞大的功能,涉及到锁屏,电话,音乐,闹钟,录音机,相机等诸多应用。最终的技术方案是SmartCover应用负责界面和用户交互,以AIDL方式与各应用进行数据交互。皮套还有一个亮点是四周一圈是透明的,来电或播放音乐时,屏幕四周会有跑马灯效果透出来,灵感来源是电视的流光溢彩功能。SmartCover在公司内部反响不错,获取当年的创新奖。

由于最近两次Freely UI升级,除了细节优化并没有太多改善,于是一套全新的Freely UI 3.5提上日程,界面风格全新设计,追求扁平化,功能也有所删减,例如将短信移出三合一界面。Freely UI 3.5最初目标是X599手机(MT6750S,Android 8.0),因为样机时程较晚,还是先在X588上开发。

Android 8.0 Dialer源代码出现了颠覆性的变化,整个源码结构完全不同于以往任何版本,大量三方库和注解的引入,导致编译速度非常慢。再加上MTK修改了MPlugin架构,拆分Plugin,由一个应用对应一个Plugin改为一个功能点对应一个Plugin,而且有些功能直接集成在frameworks中,给移植过程带来很多额外的工作。从Android 4.4到8.0,这一次的定制难度是最大的。

2018

Android 8.0芯片厂商公版源代码一直无法稳定下来,新的一年产品方向不明确,整个开发节奏明显慢了下来。Freely UI 3.5的优先级一再降低,只能以设计出Android 8.0换肤方案的Freely UI 3.1先用于产品。一些进行中的机种也不断推迟甚至取消,整个手机业务严重萎缩。

很快就迎来新一轮组织结构调整,厦门的手机团队全部改为创新研发,从事人工智能和机器学习领域的研究,我的团队投入在视频监控,Amazon Alexa智能音箱和YOLO物体检测三个方向,其中我直接参与编码的是YOLO物体检测。

YOLO是一个快速的物体检测模型,采用Darknet开源框架,宣称的识别速度优于同类应用。我们的目标是将它用在手机上,接入摄像头实时检测物体。从Github下载的代码来看,检测一张图片的时间,高端机约2秒,低端机约4秒,显然第一步工作是优化检测速度。尝试了OpenCL,OpenMP,OpenBlas以及NNPACK等方案,最终将检测速度提升四倍,低端机也能够在1秒内完成检测,不过大量CPU运算会导致发热降频,只能短时间使用。

机器学习离不开模型训练,我们使用Pascal VOC,MS COCO以及ImageNet三个数据集来训练。模型训练计算量实在太大,哪怕是一台双路Xeon E5-2699也要花费一个月才能训练完一个简单的模型,而一块CUDA加速的GTX1060显卡可以将时间缩短都一天内。从这个角度讲,机器学习就是烧钱的。

当机器学习项目还在如火如荼的进行中,AOC Cloud CMS悄然展开,其背景是电视机消费市场低迷(哪怕今年有世界杯),而企业市场,如广告机需求量大。AOC品牌一直使用外包的CMS系统,为了削减成本,开发自有的CMS系统的工作就落到厦门,通过修改开源的方案以快速出产品。

Xibo是一个PHP后台的内容管理系统,前端用jQuery和Bootstrap,后端用Slim和TWIG,MVC模型。项目目标很明确,将Xibo功能,操作方式以及界面全部改成之前AOC外包商(CLEAR)的样子。这个案子还在进行中,以后再补充。