Android源码编译得到的adb为什么不识别设备?

编译Android源码得到的adb不识别设备,现在把解决过程记录下来,希望对其他人有所帮助。


现象:

Ubuntu 16.04系统,在Android 5.0.2源码上,修改adb源码,编译得到adb,执行adb devices不识别设备,而且adb kill-server后adb start-server总是出现“ADB server didn't ACK”,“cannot connect to daemon”。但SDK自带的adb却能识别。这是什么情况?


分析:

难道是修改错了?看了修改的部分,不会导致这个问题。

正好本地有Android 4.4的源码,试下吧:不经修改得到的adb,仍然不识别设备。


也就是说两套源码都编译成功了,却不好用,这。。。


百度了一下没找到提过这个问题的,Stackoverflow上也没发现。。。


试试Windows版本的吧,SDK依旧识别,自己编译的adb还是不识别。。。。一点安慰是:Windows上adb start-server不提示无法连接ADB server了。


再回到Ubuntu上吧:

如果server没有启动,自然不能识别到设备,先解决这个问题:adb start-server再adb devices发现,ADB server启动了,只是启动的晚了一些。

现在接着解决不识别设备的问题:想一想,adb源码不至于有问题,网上只有编译adb的方法,没有提到运行出问题的。


想一想这么一个工具都弄不明白,这挫败感顿时爆棚。


上Github看一看吧,搜了下adb,排第一的是下面这个项目:

https://github.com/karfield/adb

介绍说是自定义的独立版本adb,应该是可用的,打开先看说明,看到下面的介绍:

=== adb is a useful tool for debugging android devices, you can download the binary from google/android.com(mostly), but it
only supports small amount devices. To support some specific android device, you need to add the VID, add udev rule, etc. If
you want to support your devices natively of adb, you should change the usb_vendors.c code, then build the whole android
source to get the adb tool. It cause too much to gain the benity.

需要修改usb_vendors.c,好吧,看一下:

里面果然有一个VendorID列表:builtInVendorIds,用宏定义了若干厂商,确实没有我这台设备的厂商。

按照格式在内建VID列表中把测试设备的VID填进去(这个VID通过lsusb命令可以获得),然后重新编译,执行adb devices可以看到设备啦!!!


Android的adb对厂商的支持:

在usb_vendors_init(void)方法里,用这个内置列表加上从文件读取的第三方列表组成最终的adb支持设备的VID列表:vendorIds,这个文件是HOME环境变量的目录(或者/tmp目录)下的.android/adb_usb.ini文件,每行一个VendorID。

transport_usb.c中的is_adb_interface()函数,会遍历支持的VID列表,如果不在里面,就不会显示该设备。

int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol)
{
    unsigned i;
    for (i = 0; i < vendorIdCount; i++) {
        if (vid == vendorIds[i]) {
            if (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS &&
                    usb_protocol == ADB_PROTOCOL) {
                return 1;
            }

            return 0;
        }
    }

    return 0;
}

为什么这么设计?为了方便调试?比如PC同时连接多台设备,只想操作一台设备,而不想每次都adb -s制定序列号或者export ANDROID_SERIAL设置序列号。

原因不得而知,可SDK里的adb是怎么支持的呢?没有发现有一个超全的VID列表文件呀(因为本地的只有一个VID文件,而且里面没有填VID),难道填在了内置的VID列表里,每次更新SDK顺便更新?好像很不方便。

看看源码吧,是不是内置了:在AndroidXRef源码网站上,发现5.0、5.1都有这个usb_vendors.c文件,但6.0、7.0、7.1都没有这个文件,看一下做判断的transport_usb.cpp文件,6.0之后已经删除了对VID的判断:

http://androidxref.com/7.1.1_r6/xref/system/core/adb/transport_usb.cpp

97 int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol)
98 {
99    return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL);
100}


原来Android也认为没这个必要,因此6.0之后,adb在不需要修改源码或者VID文件的情况下,就可以识别设备了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值