4OD简介
4OD是英国channel4的一个视频应用, 在英国非常流行,类似于国内的优酷,腾讯视频等等. 可以在google play store上面下载.
channel4的官网是:http://www.channel4.com/
问题现象
某些M版本的手机刚安装上这个应用,打开的时候会出现如下提示:
或者进入以后,点击某个具体的视频播放的时候出现:
看提示貌似是应用本身的问题,但我们也需要找出到底缺失了什么component.
问题分析
- 初步分析
第一个截图是刚安装上应用第一次打开的时候出现的Activity, 所以可以在log里面搜索”ActivityManager: START u0” 来查看这个Activity的名字.
200 07-26 15:59:01.684 1526 3091 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.channel4.ondemand/com.novoda.all4.home.HomeActivity (has extras)} from uid 10096 on display 0
252 07-26 15:59:02.276 1526 2546 I ActivityManager: START u0 {act=com.channel4.ondemand.MISSING_COMPONENT cmp=com.channel4.ondemand/com.novoda.all4.home.MissingDrmActivity (has extras)} from uid 10169 on display 0
所以这个Activity叫MissingDrmActivity, 可以猜测是和DRM相关.
问题定位
由于adb log没有更详细的信息, 需要加log来进一步分析, 我们都知道,DRM标准的接口一般都是在./frameworks/base/drm/java/android/drm/DrmManagerClient.java
所以使用比较笨拙的方法在DrmManagerClient.java的一些主要接口里面加了log,并且把
./frameworks/av/drm/drmserver/DrmManagerService.cpp
中的log打开. 然后再次抓取log, 发现了如下打印:
07-07 10:07:18.348 V/DrmManagerService(Native)( 586): Entering getAllSupportInfo
所以在DrmManagerClient.java的getAvailableDrmEngines方法里面添加调用栈打印来确定是否被4OD调用了.
结果如下:07-07 10:07:18.338 W/System.err(11140): java.lang.Exception: 4OD 07-07 10:07:18.338 W/System.err(11140): at android.drm.DrmManagerClient.getAvailableDrmEngines(DrmManagerClient.java:360) 07-07 10:07:18.339 W/System.err(11140): at o.bsz.ˋ(:105) 07-07 10:07:18.339 W/System.err(11140): at o.bsy.ˊ(:26) 07-07 10:07:18.339 W/System.err(11140): at o.aye$7.ˊ(:164) 07-07 10:07:18.339 W/System.err(11140): at o.aye$7.ˊ(:161)
通过反编译,我们可以确认调用栈所示的o.bsz等就是4OD这个应用.
问题确认
我们在DrmManagerClient.java->getAvailableDrmEngines添加更多log来确认可以获取到的Drm plugin.for (int i = 0; i < supportInfos.length; i++) { Log.e("MyDrm","supportInfos is "+supportInfos[i].getDescriprition() +","+supportInfos[i].getDescription()+","+supportInfos[i].getMimeTypeIterator()+","+supportInfos[i].getFileSuffixIterator()); descriptions.add(supportInfos[i].getDescriprition()); } Log.e("MyDrm","descriptions size "+descriptions.size()); String[] drmEngines = new String[descriptions.size()]; Log.e("MyDrm","descriptions.toArray is "+descriptions.toString()); return descriptions.toArray(drmEngines);
打印的log如下:
07-07 10:07:18.349 E/MyDrm (11140): supportInfos is OMA V1 Forward Lock,OMA V1 Forward Lock,java.util.ArrayList$ArrayListIterator@20b5558,java.util.ArrayList$ArrayListIterator@ce456b1
07-07 10:07:18.349 E/MyDrm (11140): descriptions size 1
07-07 10:07:18.349 E/MyDrm (11140): descriptions.toArray is [OMA V1 Forward Lock]
这个调用找到的plugin是OMA V1 Forward Lock.
对比另一个没有这个问题的手机的log, 打印的是:
07-07 10:09:23.106 E/MyDrm (10152): supportInfos is Widevine DRM plug-in
然后对比两个手机DRM和Widevine相关的库,发现问题手机没有libdrmwvmplugin.so.
将没有问题的手机的/system/vendor/lib/drm/libdrmwvmplugin.so这个库给删掉.
问题出现!!!
问题总结
经过查阅相关文档, libdrmwvmplugin.so属于Widevine Classic, 在M上已经可以不需要集成了. 所以有些厂商的Widevine没有集成这个库.