
2019 年 10 月,00 后田某因非法获取计算机信息系统数据罪判处有期徒刑三年,并处罚金人民币一万元。当事人田某只有初中文化,但却拥有极强的计算机天赋,在 2019 年 1 月 5 日到 1 月 15 日期间,通过软件抓包、PS 身份证、重放攻击等手段,在某银行手机银行 App 内使用虚假身份信息注册银行Ⅱ、Ⅲ类账户非法销售获利。 案例分析 很多人会好奇银行 App 是如何被一步步通过抓包、入侵、重放攻击,从而让黑客有利可图。让我们具体分析下作案过程: 首先,田某通过本人身份证信息,在注册账号正常流程中,通过「软件抓包」技术将银行系统下发的人脸识别身份认证数据包进行拦截并保存。 其次,在输入开卡密码环节,田某将 App 返回到第一步(上传个人身份证照片),并输入伪造的身份证信息,并在此进入人脸识别身份认证环节。 最后,田某使用先前拦截的身份认证数据包(含本人信息)进行上传验证,使得银行系统误以为此环节需比对本人身份信息,遂而成功验证本人人脸,使得其能够成功利用虚假身份证信息注册到银行账户。 客户端 App 数据安全刻不容缓 在以上案例中,涉及到银行开户系统遭受重放攻击的事件正好映证了移动端针对数据传输的加密验签的重要性。我们应当如何重新审视客户端的数据安全问题?通过解析支付宝目前在“端上安全”的设计机制,也许能够带给我们一些新的启发。 首先,我们以移动网关能力举例,试着重新梳理在重放攻击的层层环节中如何保障数据传输及存储的安全性。 客户端 App 数据安全传输、安全存储 针对客户端的数据传输与验签,要做到精细化的安全一直是老大难的挑战。借助“安全黑匣子”,目前支付宝已实现针对应用级别数据如 AppSecret 采用加密存储,通过数据加签接口实现各类上层业务的封装。 借助安全黑匣子,客户端通过应用公钥和秘钥加密针对生成的数据进行离散存储,保证加密秘钥的安全性。而安全黑匣子本身的代码混淆、多重反调试机制,使其安全性能极大提升保障。 除此之外,安全黑匣子基于反调试技术使得常见的调试工具如 GDB、IDA Pro 的动态调试分析技术失效,基于导出表混淆、垃圾指令等手段充分提升攻击者静态分析应用的难度。如此动静结合,客户端数据传输及存储安全能够充分保障。 当用户提交个人信息至客户端 App 时,MGS 移动网关能够通过 API 接口进行数据加密,使得下发的身份认证数据包无法被篡改; 即使用户尝试使用伪造的身份信息针对数据包进行解密篡改,MGS 移动网关同样具备验签机制,使得数据包无法被解密成功。 除却借助移动网关能力多方面的验签加密能力提升 App 被重放攻击的门槛之外,在业务服务器的设计中,仍然需要增加对用户及业务数据的多重验证,从而彻底保障端上数据的安全防护。 当然,App 数据安全不止于传输与存储。如何提前在开发期做风险预估及安全机制设计,针对用户端实现信息多重验证,以及构建围绕 App 全生命周期的防护措施,从而能够真正实现覆盖“App 开发、上线到使用”全链路的安全规范: App 开发期的安全机制设计 支付宝通过打造多层次的端上安全机制从而防止 App 被黑客或木马攻击,具体主要分为“本地域”、“线上运行”以及“App 端”三个层面。在本地域方面,通过代码混淆、加密等手段实现二进制防护;线上运行时,通过“安全黑匣子”打造的数据安全环境以及加密等手段实现数据防泄露;在 App 端,借助数据安全存储、安全签名等手段充分确保业务功能的稳定运行。 用户信息验证 随着终端设备算力的持续增强,目前移动端设备借助强大的 CPU 和 GPU 完全可以进行非常复杂的运算。而由此催生出的一系列移动端 AI 引擎,如支付宝的 xNN,帮助我们能够进一步加强用户信息验证的智能化。 结合端上金融业务属性,如银行卡及身份证 OCR 识别、人脸识别、活体检测等智能服务,已经过近 2 亿用户验证,具备识别准确率高、速度快、模块丰富等特点,同时在支付宝小程序中也已开放。 App 全生命周期防护 关于客户端 App 安全,实际上是一套从 App 开发、上线及使用的一站式解决方案。在 App 开发阶段,提供代码混淆、数据加密、数据库加密等安全开发以及数据安全能力;在上线阶段,提供 App 加固的能力,通过 DEX 加壳、SO 加壳、防反编译、防重打包等能力,提升 App 的整体安全水位;在使用阶段,通过 API 签名、API 数据加密等手段来保障数据的完整性及安全性,同时借助安全加密键盘从而保护用户输入的信息安全性。 mPaaS 客户端 App 安全能力 作为源自支付宝的移动开发平台,mPaaS 目前已完成支付宝金融级的端上安全能力沉淀,不仅能够提升 App 应对高峰带宽下的服务质量挑战,同时在弱网情况下的可用性、针对网络请求的危险识别能力均属于行业前列。目前,借助 mPaaS 客户端的加固技术与黑匣子,能够保障移动端的代码安全和网络层的数据安全,提供加签、加密等方式,同时网关能够识别出客户端环境,并有能力针对可疑请求做拦截。 结合中国人民银行于 2019 年 9 月出台的《移动金融客户端应用软件安全管理规范》,针对客户端应用在数据安全、身份认证安全、功能安全设计、密码秘钥管理、数据安全、安全输入、抗攻击能力等方面均提出明确要求,全面覆盖客户端应用在设计、开发、发布及运维的全生命周期。 mPaaS 产品目前已通过中国金融认证中心的安全测评,并服务银行、证券、政务、交通等众多行业超过 2000 家客户。同时,针对客户端安全方面 mPaaS 提供全方位安全防护方案,真正帮助企业打造安全稳定的移动应用,更好地做到技术驱动业务创新、为业务带来美好体验。
为提高业务研发的开发效率,解决业务基础工具技术痛点,让研发主要精力回归业务核心问题解决上,我们在不同的维度做了大量体系化的技术构建,为不同的自动化场景提供稳定、易用的自动化底盘。 本文主要分享 Totoro 框架在移动端截图及图像处理及在全链路体系上的技术方案和业务支持能力。 基础截图技术方案 一台手机上获取屏幕截图简单,但是想要兼容集群环境云真机平台上的大量移动设备,突破系统各种安全限制、安全页面(密码、转账等页面)反截图安全限制、及 ROM 差异性等不同维度的兼容性问题,且是非侵入方式,则会有一点技术小挑战。 这里从基础截图方案和突破系统限制达到截图能力全场景覆盖两方面分享 Totoro 的一些实践。 1. 一般常见截图方案选型及改造 在移动端自动化(测试)场景, 最长见的截图方法就是使用adb shell screencap或uiautomator截图接口。然而 adb shell screencap 方式使用很不方便,需要将截图先保存到手机磁盘上,然后再pull到 PC 设备上。Totoro 框架中采用了一次性的获取方式如下: adb -s sn exec-out screencap -p > name 但是即使采用adb exec-out方式也存在图片无法压缩导致的截图耗时较长的问题,并且 Java 项目中每次都要 Process 创建进程,遇到频繁截图情况,耗费系统资源,影响稳定性。所以在 Totoro 框架中提供的 SDK 默认 API 底层采用的的是 Uiautomator 提供的接口方法。 UI Automator 测试框架提供了一组 API,用于构建在用户应用和系统应用上执行交互的界面测试。通过 UI Automator API,您可以执行在测试设备中打开“设置”菜单或应用启动器等操作。 同样发现,UIAutomator 提供默认截图方法 生成图片文件也是非常大,压缩算法并没生效。导致截图链路上整体耗时会造成每次截图在平均 2-5s 左右,影响到了自动化整体时间。 考虑到单独引进一套压缩算法较重,且可能后续无资源维护,所以决定研究安卓源码,试图从根本解决压缩无效的问题。 /** * Write a compressed version of the bitmap to the specified outputstream. * If this returns true, the bitmap can be reconstructed by passing a * corresponding inputstream to BitmapFactory.decodeStream(). Note: not * all Formats support all bitmap configs directly, so it is possible that * the returned bitmap from BitmapFactory could be in a different bitdepth, * and/or may have lost per-pixel alpha (e.g. JPEG only supports opaque * pixels). * * @param format The format of the compressed image * @param quality Hint to the compressor, 0-100. 0 meaning compress for * small size, 100 meaning compress for max quality. Some * formats, like PNG which is lossless, will ignore the * quality setting * @param stream The outputstream to write the compressed data. * @return true if successfully compressed to the specified stream. */ public boolean compress(CompressFormat format, int quality, OutputStream stream) { ... } public boolean takeScreenshot(File storePath, int quality) { Bitmap screenshot = mUiAutomation.takeScreenshot(); ... BufferedOutputStream bos = null; try { bos = new BufferedOutputStream(new FileOutputStream(storePath)); screenshot.compress(Bitmap.CompressFormat.PNG, quality, bos); } ... return true; } 根据以上安卓源码,跟踪到系统压缩方法。看注释,似乎发现了问题所在,看 takeScreenshot 方法, 调用了 Bitmap 的 Compress 压缩方法,传的参数写死了 Bitmap.CompressFormat.PNG,格式,根据注释说明,Compress 方法又对 png 格式图片的压缩忽略的,所以导致获取到的图片都很大。马上重写系统方法,直接调用压缩方法,传入 JPEG 去验证可行性,马上得出了解决方案。 找到问题所在,解决方案也就出来了,主要改造逻辑可以通过三个核心步骤完成: 自行获取 Bitmap 文件。 调用 Bitmap 压缩方法,指定 jpeg 格式,并传入自定义压缩值。 获取压缩流数据,直接 Base64 编码传递给 SDK 层。 通过以上优化,减少了两次文件读写,并且有效压缩了图片大小,整体一次截图时间控制在了 200-800ms,对比原来速度最少提升 2-3 倍以上。 2.突破系统安全限制做到截图全覆盖 Totoro 的最大业务需求 来自 钱包系 相关 App 的自动化业务,而支付宝属于安全隐私要求较高 App,各个 ROM 针对钱包或者钱包自身都会做大量安全保护,例如在密码输入页面或转账页面,会导致截图获取失败,并且我们发现有些限制级别较高页面,连系统自身的截图功能也无法使用。 但是在测试场景下,数据及安全级别是可控的,多个业务线强烈提出 能否通过技术手段 获取到这些被限制的页面截图,来满足业务验证逻辑的正确性,去除人工页面截图审核死角,来进一步提高研发效能质量。 由于 Totoro 框架是对 App 是非侵入式的,也给我们的技术实现添加来不小挑战。但是,本着业务价值首位考虑,为了保障开发者使用效率,我们开始调研安卓各种截图方案,跟踪安卓截图源码,试图采用Hook方式绕过安全校验机制。 针对安卓平台各种全局截图方法的深入研究,最后发现,各种入口类的系统接口调用到底层都会调用SurfaceControl类或对应的 c 层代码, SurfaceControl 类成了关键研究对象。然而,从 Java 层的 SurfaceControl 类中各种 Hook 接口调用尝试发现,只要被安全页面限制,该方案下的截图方案就会失败或截到一张黑屏。这意味着系统针对截图的安全限制可以覆盖到目前我们了解到的任何场景,让我们的解决方案一时陷入困境,失去了思路方向。 然而在做 SLM 云测平台设备远程租用过程中,发现录屏功能在这些截图限制页面依然是可以正常使用,这说明系统或安全限制只是针对截图相关 API,这给我们的截图提供了新的思路,通过录屏来获取屏幕截屏。所以开始研究系统的录屏功能,能否在录屏过程中拉一帧的画面,作为截图新的实现方式。 A.自研技术方案 实现原理很简单,通过直接解码 Surface 获取屏幕视频流,然后从视频中获取一张可用帧,转换为 JPEG 格式,最后回传给 PC 上的接口。该方案从 Java 层实现,兼容性强,成本底,下面是关键代码逻辑: MediaCodec mcodec = MediaCodec.createEncoderByType("video/avc");//创建解码器 Surface surface = codec.createInputSurface();//构造目标Surface SurfaceControl.setDisplaySurface(display, surface);//通过反射SurfaceControl,将构造的Surface设置到系统 int outputBufferId = codec.dequeueOutputBuffer(bufferInfo, -1);//开始解码 //判断有效帧 ... Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(index);//获取屏幕bitmap值 bitmap.compress(Bitmap.CompressFormat.JPEG, quailty, fos);//保存截图 ... //截图回传到PC接口层 然后就是打包程序,利用系统 app_process 服务,可以避开各种权限弹窗问题,直接运行程序,即可获取到屏幕截图。目前该方式已全面应用到 Totoro 底层截图方案,可以兼容安卓 5.0-10 版本,但是仍然有改进地方,后续还可从以下几点进一步优化: 视频流有效帧判断逻辑优化,减少截图时间。 目前仍然需要一次手机端的文件保持读写逻辑,后续可考虑读流方式,直接获取图片 Base64 值。 可执行文件参数标准化,可满足多场景技术输出。 B.备用兜底方案 以上 A 方法主要针对 5.0+ 的安卓设备,且针对个别 OPPO、VIVO 设备开启了系统恶意录屏功能,就会造成录屏功能限制,引起截图失败。针对这部分的设备,我们设想 Android 能否像 Linux 系统一样,绕过 Java 层权限限制,直接从C层读取操作系统 framebuffer(Linux 设备/dev/graphics/fb0),来获取屏幕图像。 期间调研了开源的 minicap 录屏方案,发现 Surface 方案在个别设备不能兼容情况下, minicap 依然可以使用,其底层原理就是采用 NDK 开发的工具,直接读取操作系统 framebuffer,为了不重复造轮子,决定把 minicap 工具中的手机端的服务单独剥离出来集成到 Totoro,作为备用兜底方法提供截图能力。 String cmd = String.format("adb -s %s shell LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P %sx%s@%sx%s/0 -Q 90 -s -t > %s", deviceId, w, h, w, h, localPathFile); 按照上面命令单独调用 minicap 工具截图,并从流中解析到图片保持到制定目录,经大量测试,该命令并不一定稳定,有时会报格式错误,有时会报流处理错误,所以我们添加了降级方案,如以下命令。 String cmd = String.format("adb -s %s shell \"LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P %sx%s@%sx%s/0 -Q 90 -s -t > /sdcard/.totoro/%s\"", deviceId, w, h, w, h, name); //然后将图片Pull到PC上制定目录 两种技术方案相互降级搭配使用,这样正好弥补了 Java 层 Surface 方案的一些可能失败场景,作为兜底方法集成到了 Totoro 框架中,目前为止暂未发现两种方法都失败场景,保障了截图能力的底盘稳定性。 业务多场景支持 1.基础截图场景 通过以上相关多层技术方案兼容,Totoro 目前可以提供稳定的基础截图能力,业务层无需关注底层的具体技术实现方案或兜底方案,只需要调用一个 Totoro 实验 SDK 暴露的 API 即可。 String path = BizUtils.saveScreen(name); 2.长截屏技术方案 长截图能力一直是业务方提出的痛点需求,一直到 19 年末我们才抽出时间弥补了 Totoro 这块能力缺失。起先,先调研了行业内其他实现方案,基本思路都是滑动截图,然后合并多张截图,最后生成长截图。然而,难点在多张截图的完美合并,针对移动端的页面截图,存在页头、页尾、小 banner 更新、小红点等多重影响,给长截图的实现增加了不少难度。 可行方案分析: 直接利用第三方拼接工具。需要添加额外依赖,其在移动端个别极限场景拼接存在问题,维护成本高。 利用算法部门资源,特征值直接匹配。需要添加算法库,且要推动算法部门不断迭代更新,后续更新可能不及时。 自己实现一套,难度大,初期成本高。需要兼容移动端页面各种情况,但是后续维护成本低,升级方便且及时。 权衡利弊后,最终我们采用了方案 3,决定自己实现了一套针对移动端截图特征的拼接能力,采用了自研像素行灰度值末尾优先对比技术方案,核心逻辑思路是默认向上滑动生成的图片组,两两从底部优先开始对比行像素的灰度值,找到拼接点和裁剪点。为了减少噪点及个别红点、红线、小 banner、及底部导航栏影响,在不同的对比点及区域添加了对应的参数。其核心代码思路如下: public static File mergeImg(File imgA, File imgB, String mergedImgPathName) { int[][] listA = getPX(imgA);//获取像素数组 int samePartEnd = 0, sameBottom = srcALen;//定义查找目标位置 int samePart = mergeLen >> 2;//定义相似颗粒 for (int al = Math.max(0, listA.length - mergeLen + (samePart >> 1)), l = listA.length - 1; l >= al; l--) { for (int x = mergeLen - (listA.length - l), y = Math.max(0, (samePart >> 1)); x >= y; x--) { if (compareRowPx(listA[l], listB[x])) {// 对比行灰度相似度 //找到基础对比点 for (int i = 0, partLen = (l == listA.length - 1) ? samePart : samePart >> 1; i < partLen; i++) { //寻找拼接点 if (compareRowPx(listA[curA], listB[curB])) { if (i == partLen - 1) { //相同区域达到阀值,找到拼接点 samePartEnd = x; sameBottom = l - 1; break; } else { //寻找底部相同区域,如底部导航Tab栏 break; } } if (matchedBottom || samePartEnd > 0) { //拼接参数找到,提取结束循环 break; } } } } String fileSuffixA = getFileRealExt(imgA);//读取二进制流,获取原始图文件真实后缀 String fileSuffixB = getFileRealExt(imgB); String fileSuffixC = mergedImgPathName.substring(1 + mergedImgPathName.lastIndexOf(".")); if (samePartEnd == mergeLen - 1) { //图片相同,直接返回第一张图片 imgA.renameTo(file); return file; } //开始合并逻辑 int newY = srcALen - (srcALen - sameBottom) + (mergeLen - samePartEnd); ...//读取原始图片值 if (sameBottom > 0) { // 去除底部导航tab栏 } else { //没有底部操作tab栏 newA = reader.read(0); } ...//重新拼接图片 imgNew.setRGB(0, newA.getHeight(), width, newB.getHeight(), imgArrayB, 0, width); ImageIO.write(imgNew, fileSuffixC, file); ..//其他资源回收 return file; } 效果图如下: 该方案目前已全量上线,并且满足了目前业务方需求,在遇到长截图拼接有重叠或缺少问题时,也可以通过调节对比参数,快速优化合并逻辑代码,达到了既定研发目标。 3.局部控件截图 在自动化过程中,有些业务需要获取某个控件的截图, iOS 端可以通过 WDA 相关接口实现,但是安卓端是没有现成方案的。因此,Totoro 采用了按照坐标截图切割方式,结合控件坐标信息,可以在 PC 端实现一套局部控件获取方法。该 API 可以同时适用到 iOS 和安卓双平台,局部控件截图核心实现思路: src = BizUtils.saveScreen(name); WebElement element = driver.findElement(By); ...//根据element获取到element的坐标信息 ImageCheckUtils.imageCut( src, dest, x, y, width, height);//根据坐标信息切图,获取到控件截图dest文件 4.多屏幕截屏 目前 Totoro 中只集成了 adb 原生方式,用来为一些支付 IoT 设备,提供多屏幕截图能力。 #附屏幕截屏 adb shell screencap -d /dev/graphics/fb1 fb1.png #主屏幕截屏 adb shell screencap -d /dev/graphics/fb0 fb0.png 后续根据需求反馈,会调研采用 UIAutomater 或 Surface 方式实现。 图像智能算法分析 Totoro 借助兄弟团队(工程数据技术组)的算法能力,针对截图实现了页面智能分析、检测等能力,完成了图片相关技术体系小闭环。智能算法能力集成可以归类为以下三种。 1.控件分析 如上截图所示,可以通过以下 API 获取页面控件信息,可识别控件类型如 button、image、label、progress、switch、more、editView、popUp、checkBox、return、close 等。 2.页面异常检测 异常检测能力可抽象分为通用异常和业务异常,具体说明如下: 通用异常分析,如:黑白屏、加载失败、图片或文字截断,控件排列重叠等常见页面 UI 问题; 业务异常分析,如:业务弹窗、授权弹窗阻断等,且更加不同的业务异常场景需求,可定制化服务。 Totoro 中可通过一个接口获取页面异常信息,业务中通过自动化的检测,完成了之前很多无法实现的自动化场景。 3.业务场景识别 为实现更加智能的页面分析,为后续自动化测试场景中自遍历或自填充提供基础能力支撑,依赖算法能力可以智能分析当前页面场景,例如可以通过算法相关接口来自动判断当前页面属于哪个业务流程,比如登录流程场景、输入场景等。 目前内部只开放了登录场景的识别,已上线并应用到小程序自动化注入及巡检场景,可以代替小程序登录繁杂脚本工作量,大大减少用例脚本维护成本。 4.图片相似度分析 如上两张截图,由于存在大面积 Banner 变化和背景渐变颜色差异,如果单纯通过像素对比,很难分析出是一个页面上的截图,这里主要借助算法能力,通过提取页面特征值、图像指纹、颜色通道等多维度来精确计算出两个截图的相似度。 如以上截图所示,可以通过 Totoro 封装的 API 得出两张图相似度为 54,业务层代码可通过相似度应用到自己的实际业务场景。(只要相似度 >=50 则可认为两个截图是一个相似业务场景) 后续计划 针对很小的一个图片业务能力,都需要投入量巨大的努力 来保障 Totoro 的自动化底盘易用性和稳定性,业务不断扩张过程中,图片相关能力体系还是有多个细节仍需要不断调优,其中明确需要投入研究和后期开发计划有以下几点: 截图技术方法模块化抽离,进一步优化调用链路,加快整体截图获取速度。 长截图技术方案优化,泛化拼接方向,组件化包装,可单独灵活对外输出技术能力。 多屏截图场景优化,调研更加便捷稳定的多屏截图方案,满足越来越多的 IoT 场景。 进一步推动算法能力深化,通过埋点上报,加大算法数据闭环支持。
mPaaS 目前针对疫情防控类 App 已全面开放,免费接入。欢迎了解:https://www.aliyun.com/product/mpaas 如何解决百万级代码的快速构建?如何让上百位开发者针对同一个 App 实现高效研发协同?如何保障代码频繁变更下的交付质量? 传统的研发模式已无法适应企业在数字化转型过程中快速迭代、研发协同的要求,建设符合业务场景特性、有效支撑高并发、持续迭代继承需求的研发效能实践已迫在眉睫。 一、研发协同面临的挑战 疫情期间,为了保证服务的延续性以及更好地触达消费者,线下业务要能够快速地实现线上化,移动 App 无疑是业务线上化的最佳手段之一。短期内快速开发一个移动 App 或者将部分线下业务线上移动化,使用传统的开发模式,很难在短期内实现。 很多企业、公司的开发人员都在家办公,协同开发效率会受到很大影响,在业务需要快速迭代时,开发响应效率是能否保证业务连续性的关键。 传统的瀑布流研发模式以及长周期的迭代周期(几个月以上),需要迅速转化为 DevOps 开发模式以及具备快速响应业务需求的能力。 二、mPaaS 移动研发协同方案 方案:精准提升移动端 App 性能以及协同开发、测试效率 mPaaS 移动开发平台提供了 40+ 的移动端组件,可以快速接入。 客户端架构: 模块化的开发模式mPaaS 客户端组件支持 OSGI 模式的模块化开发方式,不同的技术同学开发不同的模块,开发者像搭建积木一样开发 App,模块可插拔、相互解耦并且支持独立发布。 一站式的移动测试解决方案(目前仅面向私有化部署方式开放)涵盖测试用例编写,本地用例录制,云平台执行真机测试,测试报告查看一站式的测试流程。 一站式移动端 DevOps 解决方案(目前仅面向私有化部署方式开放)提供从“项目->需求->开发->测试->集成->发布”全流程的协同服务支撑,提升研发协同效率。 三、方案价值: 统一的 App 开发标准 借助统一的客户端框架和开发标准,满足大团队协同开发需求,降低系统之间的耦合性。开发框架采用模块化的架构思路,具备高度可扩展性。IDE 插件提供工程化能力,可以快速上手,提高开发效率 所有组件都经历了支付宝 App 亿级用户的验证,开箱即用,极大的缩短开发周期 H5、小程序开发模式和能力支持,一套代码 Android、iOS 两端复用,缩短开发周期,快速响应业务需求 节约开发测试成本 提供移动端的产品研发管理服务,适合多人协作的场景,覆盖从产品需求准备、研发、构建、验证、集成等项目阶段,节约管理成本,提升研发效率 通过真机模拟真实用户操作,提供自动化测试方案,覆盖 App 开发期的各个阶段,上线前充分测试,发现 bug, 减少线上问题,提高整体用户体验。全自动化测试同时可以有效较少整体测试成本,缩短测试时间,加快上线速度 增强构建,流程任务驱动 按照开发过程中的核心流程驱动整个研发流程,在流程的不同阶段用任务驱动进程,确保项目稳步、快速进行 标准化、流程化的打包构建,支持 Android、iOS 三、典型案例 花生地铁、笑联科技等生活服务类的应用,通过提供优质的跨平台体验,确保应用稳定性及流畅度,更可通过小程序构建自有的业务场景生态,覆盖校园服务、办公 OA等领域。 在金融业务的移动化背景下,金融行业业务重心转向消费客户,业务由线下转向线上,移动App成为金融机构面向消费用户的最重要线上窗口和渠道。移动开发平台应能满足移动互联环境下的应用快速迭代需求,并能够承载互联网金融市场的高并发、大流量负载环境,由此要求移动开发平台必须具备敏捷的开发能力和稳定的平台性能。 四、如何咨询和开通 立即免费开通:https://www.aliyun.com/product/mpaas 同时欢迎大家使用钉钉搜索群号“23124039”加入 mPaaS 技术交流群,期待与你交流。
mPaaS 目前针对疫情防控类 App 已全面开放,免费接入。欢迎了解:https://www.aliyun.com/product/mpaas 都说年关难过,2020 年春节这关特别难。线下门店、营业厅、大型商超等以往人流密集的地方一下子冷清下来,对餐饮、超市、电信、银行、房地产等重线下渠道的行业带来严重冲击。以银行理财业务为例,以往理财经理需要在柜台为客户当面咨询和签约,这种面对面商务模式受疫情影响无法进行,导致网点理财业务收入的大幅下降。除了店铺租金、人员薪资等固定成本,餐饮、实体零售等行业额外还要承担无法及时清理库存带来的风险。能撑多久是悬在每个企业主头上的一个大问号。 与此同时,我们也看到电商、在线教育、在线问诊等“互联网+”经济的逆市繁荣。可以毫不夸张的说,在这场疫情之下,传统经济能否将线下业务转移到线上来,转移多少业务到线上来,成为企业生死攸关的大事。 如今,APP 已经成为最重要的线上渠道,而很多企业的 APP 还停留在移动版门户网站阶段,线上业务功能屈指可数,无法沉淀移动用户数据,线上营销活动也难以起到理想的拉新、促活和留存效果。 作为一款源于支付宝智能科技的 APP 运营平台,mPaaS 已经积累了银行、政务、交通、零售等众多行业的成功客户案例,累计服务超过 1 亿终端用户。针对线上业务运营和移动营销,mPaaS 提供了以下解决方案。 如何线上获取客户? 线上获客关键在于有效的营销活动。mPaaS 具备一站式营销活动投放能力,智能投放 CDP 组件通过App内的个性化广告投放,支持针对定向人群进行个性化广告投放,帮助 App 运营人员精准、及时触达用户,实现留存、促活、增长业务的目的。 智能投放 CDP 可以应用于以下几个典型场景中: 产品推广某银行对注册地为某区域的用户投放广告:在当地某商场购物用该银行卡支付,即可参与抽奖。广告内容在 App 首页顶部展示。 业务提醒某银行对最近一年在信用卡账单日即完成还款的用户发出一个信用卡额度提升 10% 的公告,公告内容在 App 首页顶部展示。 节日关怀对 App 用户推出端午节限时优惠活动对活动期间新注册的用户投放广告:某理财产品端午节期间购买,年化利率提升 y%。在 App 启动开屏页展示广告内容。 除了具备完善的投放前、中、后全链路营销活动管理能力以外,智能投放 CDP 还有强大的人工智能加持,支持一次广告投放搭配多套投放素材,可加载 AI 自动分流能力,系统根据广告投放效果进行自动调优,让广告投放的流量效果最佳,无需人工干预,降低运营成本,有效提升运营效果。 此外,AB 实验组件可以跟与智能投放 CDP 搭配使用,一次针对不同用户组投放不同形式和内容,通过用户实际作出的选择来智能调整投放内容和形式,达到提升转化率的目的。保证您的每一个营销方案都是科学决策。 如何唤回沉默用户? 如今用户手机普遍安装 15 个以上 APP,每天能打开一次的APP屈指可数。对于不活跃的 APP 用户,适当推送消息提醒显得尤为重要。mPaaS 推送服务帮助您快速、高效、有效触达用户。与其他推送产品相比,mPaaS 推送服务优势在于: 快速稳定:消息下发速度快,保证稳定到达。 接入简单:降低接入成本,更高效。 精准个性化推送: 可以向单个用户、自定义用户分组等各种维度精准推送个性化信息。 提供控制台推送页面推送,满足简单的推送需求。同时,也提供服务端接入方案,满足更为复杂的需求。 提供消息回执,供您追踪消息下发结果,有效提升用户留存率跟活跃度。 建立设备标识与 App 用户体系的对应关系,可把 App 用户名作为消息接收者直接发送消息,无论用户在哪台设备登录信息都能准确送达。 APP 流量不够,如何引流? mPaaS 提供阿里巴巴亿万级日活场景小程序投放服务,把自带流量的场景化产品投放到您的app端内,带来流量的同时也增加了 APP 用户活跃度和粘性。结合营销活动的投放推广和营销权益的定向发放,实现了权益发放和消耗在 APP 内整体闭环,有效提升 APP 用户留存和业务增长。 最佳实践 某银行 APP 通过 mPaaS 小程序投放服务引入了 1688 好享拼的团购场景,热门商品以图片形式在 APP 首页呈现。用户点击购买后,一键授权支付宝即可打开好享拼小程序选购商品,在小程序内下单后,支付宝可以绑定该银行的借记卡或信用卡作为单支付通道,独享优惠带动,从而带动银行卡支付活跃度。 详情咨询 • 访问移动营销套件专题页,查看更多内容。• 登陆阿里云官网 mPaaS 产品详情页,点击“立即开通”按钮,即可快速试用。
背景 再过不久又是农历新年,近几年在新年期间除了春晚之外,还有一个新的全民活动,那便是支付宝 AR 扫福。支付宝从 2017 年新春开始,五福的玩法变得有趣起来,陆续推出 AR 实景红包:通过将红包藏在特定场景中,打开 AR 相机进行寻找,这种新颖的基于 LBS 的红包方式引起一股热潮。 在 2018 年春节,支付宝将科技元素升级,推出了全民 AR 扫任意福的活动,通过扫福来集福,不管你是商店买的福,还是手写福,支付宝都可以将它们认出来。随了扫福以外,支付宝中还有大量的此类需求,如银行卡识别、身份证识别等,xMedia 多媒体端智能应用框架便由此衍生出来。 「端智能」 AR 扫福即使在网络状况并不好的情况下,识别速度都非常快,而且和一般的上传图片进行识别的流程不同,并不需要用户选择图片并上传的操作。为什么?除了算法与模型优化之外,还有一个很重要的原因就是识别引擎运行在端上,这也是最近端上AI越来越火爆的一个原因,我们称之为“端智能”。为什么要将引擎运行在端上?和一般运行在云端的智能化有什么区别?引擎之所以运行在端上而不是云端,主要有两大原因:一是由于端上涌现出大量的需求云端无法满足,在很多场景下端上的优势明显;二是由于端自身条件成熟。 端上识别引擎的优势: 优势点 具体信息 成本 AI 不是一个成本很低的计算,对于扫福这类大型的活动,如果所有计算都部署在云端,那服务器的流量、计算及存储成本将是不可想象的。但移动端本身就包含这些资源,有海量的本地边缘计算能力。 体验 现在的扫福平均时间是数百毫秒,如果走云端的方式,图片数据在网络传输方面的耗时将极大影响体验,遇到网络不好的情况时更是糟糕。很多人都有过新年抢火车票的经验,在同一时间大量的流量涌入时,等待用户的是无尽的转圈与重试。端上既不存在大数据的网络传输,也不存在大量的并发访问,因此这种场景的体验会好很多。 隐私 大数据时代人们对个人隐私的意识越来越强,云端可能面临着敏感数据上传的风险,比如前段时间火爆的换脸应用ZAO,它需要上传一张人脸的照片,就是这点让很多人放弃了使用。而如果是纯端上的运算,所有的数据都保存在用户的手机上,并不会像云端一样存在敏感数据上传的风险。 端上条件成熟: 除了端云对比的优势以外,另外一个更重要的原因是端上条件成熟,足以很好的支撑智能化的计算。主要有下面几个方面的原因: 一是终端设备算力的增强,强大的 CPU 和 GPU 可以进行非常复杂的运算,还有很多专门的 AI 芯片集成在手机中,算力进一步加强。 第二点是移动端 AI 引擎的发展,如支付宝的 xNN,Google 的 TensorFlow Lite 等,让 AI 运行在移动端成为了可能。同时模型压缩技术的发展也让过去云端动辄数百兆的模型可以被压缩到几兆以内,让模型存储于手机端成为了可能。 最后端上有很多类似于五福的实时类应用场景兴起,比如支付宝的 AR 识花/识车等,都是针对视频流进行识别。 AI 为业务带来了非常多的创新,而业务的蓬勃发展也驱动了AI技术的迅速发展,如何让这些场景迅速在移动端落地便成为极其重要的事情,xMedia 端智能应用框架便是为解决这个问题而产生。 端智能应用框架 xMedia 「端智能流程」 既然 AI 运行在端上,那么以扫福为例,整体的开发流程是什么样?来看下面这张流程图: 主要分成两部分,首先是针对扫福场景的模型如何产生。这点和云端的模型制作区别不大,一般由算法工程师负责,包含数据采集、算法设计、模型训练、模型压缩、模型部署等步骤。 待模型完成之后,接下来就到了端上的工作,它由移动端开发工程师负责。首先是数据的采集,如扫福需要打开相机,有些场景还需要其它传感器的数据用于静止判断等。采集到数据之后,不能直接将图像给到引擎,为什么?因为原始的图像分辨率很高,可能是 1080P,引擎不可能直接对这样的图像进行处理,需要先对图像进行裁剪缩放等操作。另外还有检测区域的处理,只有位于屏幕中心位置的区域才会被传递到算法,这是为了优化性能。在运行过程中,也不能够将所有采集的数据直接传递到后面进行处理,需要一定的调度策略,比如如何控制算法处理的帧率等。接下来才到 AI 引擎,引擎计算出来结果之后,也不能够直接返回给业务,而是需要一些处理才能展示出来,比如扫福中的 AR 动画。 整个交互过程看似简单,但其中涉及到非常多的细节。比如:下一帧过来时,上一帧还没有处理完怎么办?系统发热严重怎么办?覆盖率太低怎么办?等等。由此可见,移动端多媒体AI应用能否成功,除了需要一个好的模型,还依赖于资源的调度、数据的同步、部署模型的快捷程度及如何触达到更多的用户,这需要算法工程师与移动开发工程师共同的努力。 除了 AR 扫福为外,支付宝中还有很多其它类似的智能化需求,xMedia 框架便是为了解决各种场景都存在的这些共性问题。 「挑战」 从前面扫福的流程中来看,端上的AI应用场景面临着一些挑战,主要包含以下四个方面:**• 工程效率与门槛• 终端软硬件多样性• 终端资源与算法• 端智能的局限性** 对于工程效率与门槛,互联网时代最重要的成功条件之一,天下武功,唯快不破,这类挑战是如何以弹性灵活的方式完成各种各样的业务需求,如何在不发版本的情况下部署及升级模型,技术资源较少的垂直场景业务如何快速接入?解决思路主要有两种,一种是能力原子化,可以让业务快速方便的通过某种方式来组合业务。第二种思路是垂直场景的封装,将 OCR 银行卡/身份证等场景封装成可以直接使用的组件,降低这类场景的使用门槛。 面临的第二个挑战是终端软硬件多样性,Android 开发同学深有体会,数以千计的机型,GPU 型号 50+,兼容性与覆盖率问题简单是开发者的恶梦。这类挑战主要表现为如何能够让业务触达到更用的用户,让低端机也能够获得较好的体验。对于这点主要是通过不同维度的配置策略来解决多样性问题,针对各种 GPU 特性的兼容处理。 第三个挑战是终端资源与算法,所面临的问题是如何能够做到效果与电量之间的平衡,比如支付宝 AR 扫福,如果扫福一分钟耗电 30%,那么支付宝将面临着用户无尽的口水。解决这个问题除了算法本身的极致优化以外,还有一些自适应的调度策略,接下来会有详细的描述。 虽说端上智能在很多场景下有非常多的优点,但相对云端仍然存在一定的局限性,识别率与处理能力上无法达到云端的效果,端上面临这点可以通过端云结合的思路来处理。 如前面所说,支付宝中越来越多其它的智能化业务也同样面临着这些问题,如何解决这些共性的问题便成了 xMedia框架所面临的最重要的任务,这些挑战的解决方案也构成了该框架的主要特性。 「xMedia 技术大图」 为了解决前面提到的各种挑战,xMedia 框架逐渐演变成下面的架构,最重要的部分位于框架层与能力层。 先来看看能力层,前面提到,框架的思路是将处理能力原子化,并快速方便的将这些能力组合起来描述整个业务场景。它有些类似于AI引擎中的各种算子,不同的是AI引擎中的算子粒度非常细,而这里算子更加抽象,比如检测/分类算法、OCR 通用算法、图像识别能力等,它面向的是业务的开发者,而不是算法工程师。同时还有一个不同点,这里的算子不仅仅是算法的封装,它还包含渲染能力及数据源的采集能力等,所以为了加以区分,我们称这些原子化的能力为 functor。业务将这些原子化的 functor 组装起来完成需求,如何组装便是框架层的工作。 框架层类似于AI中的模型,在AI中,模型是将各种各样算子组合成一张有向无环图,用于描述算法的整体处理流程。在xMedia中,我们将前面能力层的各种 functor 通过协议组装成图,来描述整体业务的处理流程。因为这些 functor 不仅包含了算法,还包含渲染,采集等,所以可以构成完整的处理流程。除了将这些表达业务的图构建起来以外,框架层还需要负责算法的调度控制、数据同步、参数动态配置等事情。概括来说,能力层负责functor,框架层负责将functor 以最高效的方式运行起来。 在接口层,xMedia 提供了多种 API,包含端上的 Android/iOS 平台,为了便于前端使用,H5 与支付宝小程序的 API 也有提供。对于外部用户来说,xMedia 也通过 mPaaS 独立输出(mPaaS 是蚂蚁金服提供的完整 APP 解决方案,在大量的银行及保险公司 APP 中使用)。 因为特性较多,篇幅有限,接下来我们选择其中三个方面来介绍,这三个方面粗略的涉及到业务开发的完整流程: 如何灵活应对需求 如何让算法更好的运行 如何提升覆盖率 1. 如何灵活应对需求 前一节提过,为了应对复杂的业务需求,主要思路为两点: 将能力原子化成functor,可灵活扩展; 通过协议将业务流程用上面的functor构建成有向无环图。 以下图的处理流程为例: 图中分为上下两个部分,上面部分运行在客户端,有多个业务入口。业务将流程描述的协议传入框架,框架将该协议解析成由functor组装。针对不同的业务,该协议可以从云端进行配置。 图一般由三部分组成,输入、中间处理和输出。输入可以是麦克风、相机、传感器等数据,这些数据被采集之后输入到后面的处理functor中,因为这些输入源都是抽象出来的算子,也即functor,它们可以非常方便的进行扩展,当有其它类型的输入数据时,都可以将扩展后的functor加入图中。中间部分一般是算法类的functor,如推理、OCR、图像识别等,它们是输入数据的消费者,每个functor处理完这帧的数据之后会传到图的下一个节点。最后一部分负责将输出结果展示给用户,比如将手势或者姿态的关键点叠加到相机帧上,或者 AR 场景中 3D 模型合成至相机帧中。 由于functor可以自由扩展并组装到图中,这便为业务带来了灵活性,与各种深度学习的框架思路一致,通过扩展算子来增加框架的能力,通过模型文件将算子组合来完成不同的算法功能。 手势检测 接下来我们以一个线上例子来说明如何应用。 以蚂蚁庄园运动会的小鸡操为例(可以通过支付宝-蚂蚁庄园-运动会-手保健操体验),这是一个手势识别的场景,通过 AI 引擎检测用户相机中采集到的手势,当用户的手势与 UI 上提示的手势一致时即判定成功。那么,除了手势识别的模型之外,该场景如何用前面所说的思路? 下图是该业务的一个协议描述文件示意图,它描述了整个业务的流程,比如每个步骤具体由哪个functor来执行,它的参数是什么,functor输出的数据流向哪个functor等: xMedia 框架根据描述文件,运行时生成如下所示的流程图,该图从数据源开始生成数据,并将数据传输至每个functor处理,最后通过预览的functor渲染至屏幕上。 通过这种方式,可以非常好的解决业务的灵活性问题。我们要做的就是不断的扩展原子化能力及扩展框架层的控制能力。而业务方除了提供模型以外,用协议就可以较快的将需求描述清楚,动态更新也变会非常方便。 在这个示例中,协议描述了整体业务的流程,但除去业务流程以外,还有一些非常重要的因素决定业务的最终体验,如:数据的同步、运行调度、覆盖率如何提升等,接下来我们来看其中一个非常重要的部分——算法的调度。 2. 自适应调度 注意看前面的小鸡操示例,它将采集到的相机帧传递给算法,可是由于相机帧率一般为 30fps,如果将每一帧都交给算法去处理,由于连续帧之间相差不大,造成算法处理的结果存在大量重复,算法按照 30fps 来处理时大部分的数据无效。同时高帧率会造成非常高的 CPU,导致发热严重,电量以肉眼可见的速度向下掉。 如果帧率不够,又会导致算法不能及时的检测出结果,从而影响用户体验,所以选择一个合适的帧率非常重要。但由于机型的多样性,不同机器对不同的算法处理能力不同,因此不能够为所有的机器选择相同的帧率,那该怎么办? 最直接的办法是针对高中低端机,针对不同算法分别配置一个事先验证好的帧率,这个方法简单粗暴。但这个粗暴的办法会面临新的问题: 如果此时手机本身其它业务占用了较高的 CPU,与测试时环境不同怎么办? Android 成千上万的机器如何配置,即使降低维度,也是非常繁重的体力活。 对于新出来的机器如何配置? 为了解决这些问题,看似需要一种可以动态根据当前机器进行设置帧率的方法。有一种思路是直接根据 CPU、内存等硬件参数来将机器划分成不同级别,为不同级别的机器配置不同的帧率,这样看似可以节省大量的手工配置工作。但另外一个问题,手机后台任务不同,有时后台任务很轻,有时任务很重,甚至会出现 CPU 降频等可能,仅根据机器的配置来进行帧率的控制并不能达到最好的效果,需要一种更加“动态”的方式来选择帧率。 在这里,为了控制能耗,在不影响用户体验的情况下,我们通过始终将 CPU 控制到某个较低的水平来完成帧率的选择,从而达到自适应的算法调度的目的。这个思路很像空调的温度调节,可以将室内控制在一个固定的温度,这在工业控制中很常见,所以通过算法将 CPU 控制在一个固定值来达到自动控制帧率的目的。主要包含下面三个方面: 首先引入 CPU 监控模块,实时获取当前 CPU,用其作为算法的输入。接着将 CPU 设置在一个期望的值,通过算法来动态的进行控制,算法以当前 CPU 和当前帧率作为输入,计算出下一次算法的帧率。最后,为了保证用户体验,额外设置最大与最小帧率,以防止出现异常。 我们通过下面这张图来看看该方法调节的效果,图分为上下两个部分,上半部分是 CPU 随时间变化的曲线,下半部分是算法输出的时间间隔随时间的变化曲线。(这里注意一下,为什么不是帧率?其实两个是一样的东西,帧率与间隔互为倒数,而间隔比较直观,所以这里让算法输出下一帧的间隔。)这张图以一个示例来表示算法控制的有效性。 可以看到,曲线可以分成几段: 第一段,在 241s 之前,CPU 维持在一个较低的水平,45% 左右,而时间间隔处于 250ms 左右。 第二段,在 241s 时突然 CPU 因为其它任务加压 20%,导致整体 CPU 迅速上升到 65%,但随后又回落至 45%。此时下半部分的时间间隔也发生了变化,间隔从 250ms 快速升到 1700ms 左右,这正是导致上半部分中 CPU 迅速回落的原因,处理的间隔增大引起帧率降低,所以 CPU 回落。 第三段,840s 左右其它任务对 CPU 的加压消失,所以 CPU 迅速下降至 20% 左右,但随后又升至 45% 左右,回到初始的水平。下半部分的时间间隔也同样下降到 250ms,随后稳定,它也正是导致 CPU 上升的真正原因。 由此可见,该方法可以通过自动控制帧率的方式将 CPU 控制在一个适合的水平,达到体验与手机发热的平衡。通过这种自适应调度的方式,也使得各种不同机器都可以自适应的获得非常好的用户体验,同时也会防止手机发热导致的耗电问题。 3. 覆盖率 第三方面我们来聊下覆盖率。所有的业务都希望将它精心设计的体验能够传达给更多的用户,这里以一个 AR 场景来描述 xMedia 框架中做了哪些事情来提升覆盖率。以 AR 为例是因为它比较典型,能够很好的说明机器的多样性对覆盖率提升的影响。 观察上述视频,该 AR 算法简单的说是用视觉的方式来定位当前手机处于空间中的什么位置,比如这个由花组成的穿越门,利用算法可以将它始终放置在地面的某处。在算法已经优化完的前提下,现在华为 P9 Plus 上 18ms 左右一帧,这里讲述 xMedia 框架层在 Android 上的优化。 先来看看上图描述的整体流程:相机采集数据之后有两步操作,一步操作是将相机帧渲染成纹理,同时将帧数据进行预处理,随后同传感器数据一起传给算法。算法处理完返回当前手机的位置,并将该位置用于 3D 场景渲染。接下来这步是关键,与前面手势识别例子不同的是,这里的数据需要同步。什么是同步?它指的是 3D 渲染的场景与相机渲染的场景是同一帧数据。所以整体一帧的处理时间就取决于相机的渲染与算法+3D 渲染的最大时间,整体帧率也由此决定。 这个流程看起来并不算特别复杂,那问题在哪里呢?有过 Android 相机开发经验的同学可能知道,获取相机的数据有两种方式: 一种是直接获取每一帧的 YUV 数据 另外一种是获取每一帧的纹理 看起来很美好,YUV 数据直接传给算法,相机纹理用于相机渲染,两条路处理完之后直接合成即可。然而,它们最大的问题在于,这两份数据是不同步的。也就是说获取到的 YUV 数据可能是几帧之前的,无法与获取的相机纹理对应,两者之间根本没有对应关系。所以如果要同步处理,只能够选择其中一种获取相机帧数据的方式。 那么究竟选择哪一种方式?估计你已经猜到,答案是不能够简单的选择,需要多种策略配合。 多策略适配 对于两种不同获取数据的方式,处理链路完全不同,如下图所示: 第一种方式是直接获取每一帧的 YUV 数据,这种方式对于算法来说比较容易处理,直接传递给算法计算出当前相机的位姿,并由 3D 引擎渲染出当前场景。而对于相机渲染来说就没那么方便了,需要将 YUV 数据上传至 GPU 并且渲染出纹理帧,最后与前面的 3D 场景进行合成。这种方式较为直观。 而对于获取每一帧相机纹理的方式,与上面方式完全不同。于相机帧而言,因为本身拿到的就已经是纹理,所以渲染纹理实景这步不用处理,可以直接拿来使用。对算法来说就麻烦的多,由于算法需要的是相机数据,纹理无法直接使用,因此需要从 GPU 中读出 YUV 数据至 CPU 中,读出的方式也较为复杂,接下来会详细描述。 策略选型 前面分别介绍了两种方式的处理方法,那么应该怎么选择?主要思路是根据 GPU 的特点处理,但 Android 平台上仅就 GPU 而言就有 50+ 种,选择变得困难了很多。但好在经过统计,机型占比绝大部分的 GPU 可以划分为两大类: 针对 Adreno 类型的大部分 GPU,上传纹理的能力强,直接渲染YUV数据并无太大性能问题,可以将相机采集的 YUV 数据一边渲染,一边传给算法运算后再进行 3D 引擎渲染,待两者完成后合成。所以这种类型的 GPU 选择第一种方式。对于大部分高通平台的机器均是搭载的此类 GPU,占比达到 50% 左右。 针对 Mali 类型的 GPU,上传纹理的能力很差,在不进行算法处理的情况下,仅渲染相机采集回调的 YUV 数据,就存在延时的情况,卡顿明显,更不用说加上算法的处理。所以对于此种类型的GPU不能够使用第一种方式。针对该部分机型,渲染时直接使用相机预览回调的GLES11Ext.GL_TEXTURE_EXTERNAL_OES纹理作为相机帧(EGLImage,Android 底层使用的 EGL 扩展,将 YUV 数据转化成了该类型纹理,和硬件紧密相关,该使用方式并不开放给应用层)。 接着使用glReadPixels的方式从 GPU 中读出这一帧纹理,但这里不能够简单的进行读取,有以下几个原因: 通常从相机中拿出来的纹理较大,如 1280x720,而算法需要的却很小,比如只需要 300x300,完整的从 GPU 中读出数据非常耗时。 算法只需要 YUV 数据中的 Y 通道,因此读出所有的数据存在大量的浪费。 glReadPixels从 GPU 读取数据时,是将纹理当成 RGBA 格式进行输出,但现在需要的是只是 Y 通道,无法与像素一一对应,所以不能够简单的处理读取。 正是基于以上原因,在读取之前需要先进行一次渲染,渲染做了几件事情: 将数据进行裁剪、缩放到目标尺寸。 去除 UV 通道,只保留 Y 通道。 将 Y 通道以特定的方式进行排列,以保证glReadPixels读出的方式是连续的。 通过这一次渲染之后,再用glReadPixels读出数据便是仅有 Y 通道且裁剪之后的数据,可以直接输出给算法进行处理,这两部分耗时一般在 5-10ms。 算法计算出相机位姿后等待引擎渲染完毕,得到一帧场景帧,再与相机预览的纹理进行合成得到最终帧。华为和 MTK 的机器大部分搭载的是 Mali 的 GPU,占比大概 40% 左右。 不同机型根据其搭载的 GPU 来配置合适的策略,这样可以让覆盖率大幅度提升。但这样仍然还不够,还需要配合其它的方式让覆盖率进一步提升。 并行+缓存 耗时较多的部分在两处,一处是 GPU 渲染,一处是算法(运行在 CPU 端),而这两部分并不完全互相依赖,可以通过并行来提升性能。另外,使用多级 FBO 来缓存多帧相机帧,并缓存 YUV 数据也可以提升一部分的性能 。但注意一点,过多的 FBO 缓存也有图形内存开销和二次渲染开销。一般来说最多二级,视配置而定。 通过这两步处理之后,整体的算法可以达到 75% 以上,并且保持 22fps 的帧率。下图是完整的策略: 降级算法 在成千上万的 Android 机器面前,75% 的覆盖率对于这样一种耗时的算法来说已经较高,但仍然有大量的机器无法覆盖。所以为了保证剩下这一部分用户也能触达,我们通过算法降级来达到更高的覆盖率,如这里根据陀螺仪计算出相机的角度,放弃最后的帧数据同步等,最终可以使整体覆盖率达到 99% 以上,当然这是以牺牲部分体验为代价了。 xMedia 应用场景 最后,除了在支付宝新春扫五福以外,我们将应用场景归纳为以下四类: 智能交互 智能服务 智能推理 风控安全 智能推理主要用于支付宝中小程序智能预加载,首页腰封推荐等;风控安全包含内容安全检测、视频鉴黄等。目前我们先简单介绍前两类应用场景: 「智能交互」 智能交互是利用算法与用户进行交互,主要用于 AR 中,利用 AR 来替代传统的触摸交互,带来完全不同的体验。比如前面提到的 AR 扫福与小鸡操就是这类场景,小鸡操可以在支付宝-蚂蚁庄园-运动会-手保健操中体验。 覆盖率中描述的蚂蚁森林的 AR 看树活动,可以通过下面的方式进行体验。 另外一个基于头部的互动是颈保健操,可以从支付宝-小目标-颈保健操进行体验,适合办公室人群,每天给自己定个目标锻炼颈椎,缓解疲劳。 上面这些交互方式均采用 AR/AI,体验与传统的交互方式有很大的不同。 「智能服务」 第二类是智能服务类,主要是垂直场景的应用,与支付宝业务紧密关联的,比如银行卡 OCR 识别、身份证 OCR、理赔宝等,可以通过下面几个视频来体验,不再一一赘述。端上的识别具有识别准确率高、速度快、模型等特点,很多垂直场景在支付宝小程序中也已经开放。 如何体验支付宝端上智能化能力? 目前,xMedia 在 mPaaS 中已得到相应的落地应用。基于 App 端与小程序场景的联动,实现“数据计算分析+分析决策引擎+mPaaS 场景”的智能化分析及运营能力。 除此之外,借助如智能创意文案、智能分流、智能投放、AB 实验等能力,形成全面自动化的营销流程,真正提升营销自动化水平。 同时欢迎大家使用钉钉搜索群号“23124039”加入 mPaaS 技术交流群,期待与你交流。
2020年03月
2020年02月
2019年12月
目前提供的日志不是非常全,可否提交一个工单,并且让你们的运维同学写一个能复现的 Demo,并提供给我们工单的同学。
目前提问的内容中,关于异常的部分,目前没有说哪些类找不到,只是 socket timeout。
出错的异常都是 okhttp3,并不是 mPaaS 的堆栈。或者你可以试试你希望的 wire 版本。
可否提供具体的 Demo,帮助我们更好地定位问题。
参考 mPaaS 网关 API 授权部分而非用拦截器解决: https://help.aliyun.com/document_detail/72264.html?spm=a2c4g.11186623.6.683.72a125eaBD4Gh8
2019年10月
2019年09月
2019年06月
目前提供的日志不是非常全,可否提交一个工单,并且让你们的运维同学写一个能复现的 Demo,并提供给我们工单的同学。
目前提问的内容中,关于异常的部分,目前没有说哪些类找不到,只是 socket timeout。
出错的异常都是 okhttp3,并不是 mPaaS 的堆栈。或者你可以试试你希望的 wire 版本。
可否提供具体的 Demo,帮助我们更好地定位问题。
参考 mPaaS 网关 API 授权部分而非用拦截器解决: https://help.aliyun.com/document_detail/72264.html?spm=a2c4g.11186623.6.683.72a125eaBD4Gh8