记录Android实现USB功能裁剪和adb限制的经验
USB功能剪裁 首先我们要了解init.rc,init.rc会加载init.usb.rc和init.usb.configfs.rc,上层usb功能的选择会修改sys.usb.config,然后会触发init.usb.configfs.rc的选项。
以下截取了一部分init.usb.configfs.rc的代码,可以看到sys.usb.config这个属性的值会触发不同的usb模块功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 on property:sys.usb.ffs.ready =1 && property:sys.usb.config =adb && property:sys.usb.configfs=1 write /config /usb_gadget/g1/configs/b.1 /strings/0x409 /configuration "adb" symlink /config /usb_gadget/g1/functions/ffs.adb /config /usb_gadget/g1/configs/b.1 /f1 write /config /usb_gadget/g1/UDC ${sys.usb.controller} setprop sys.usb.state ${sys.usb.config } on property:sys.usb.config =mtp && property:sys.usb.configfs=1 write /config /usb_gadget/g1/configs/b.1 /strings/0x409 /configuration "mtp" symlink /config /usb_gadget/g1/functions/mtp.gs0 /config /usb_gadget/g1/configs/b.1 /f1 write /config /usb_gadget/g1/UDC ${sys.usb.controller} setprop sys.usb.state ${sys.usb.config } on property:sys.usb.config =mtp,adb && property:sys.usb.configfs=1 start adbd on property:sys.usb.ffs.ready =1 && property:sys.usb.config =mtp,adb && property:sys.usb.configfs=1 write /config /usb_gadget/g1/configs/b.1 /strings/0x409 /configuration "mtp_adb" symlink /config /usb_gadget/g1/functions/mtp.gs0 /config /usb_gadget/g1/configs/b.1 /f1 symlink /config /usb_gadget/g1/functions/ffs.adb /config /usb_gadget/g1/configs/b.1 /f2 write /config /usb_gadget/g1/UDC ${sys.usb.controller} setprop sys.usb.state ${sys.usb.config } on property:sys.usb.config =ptp && property:sys.usb.configfs=1 write /config /usb_gadget/g1/configs/b.1 /strings/0x409 /configuration "ptp" symlink /config /usb_gadget/g1/functions/ptp.gs1 /config /usb_gadget/g1/configs/b.1 /f1 write /config /usb_gadget/g1/UDC ${sys.usb.controller} setprop sys.usb.state ${sys.usb.config } on property:sys.usb.config =ptp,adb && property:sys.usb.configfs=1 start adbd
所以我们要裁剪USB功能选择,很简单,修改这个init.usb.configfs.rc,去除一些可触发的选项。比如我的需求是只保留adb,去除所有mtp,ptp等usb功能。
那么我们新建一个文件system/core/rootdir/init.usb.configfs_limit.rc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 on property:sys.usb.config =none && property:sys.usb.configfs=1 write /config /usb_gadget/g1/UDC "none" stop adbd setprop sys.usb.ffs.ready 0 setprop sys.usb.ffs.mtp.ready 0 write /config /usb_gadget/g1/bDeviceClass 0 write /config /usb_gadget/g1/bDeviceSubClass 0 write /config /usb_gadget/g1/bDeviceProtocol 0 rm /config /usb_gadget/g1/configs/b.1 /f1 rm /config /usb_gadget/g1/configs/b.1 /f2 rm /config /usb_gadget/g1/configs/b.1 /f3 rmdir /config /usb_gadget/g1/functions/rndis.gs4 setprop sys.usb.state ${sys.usb.config } on property:init.svc.adbd=stopped setprop sys.usb.ffs.ready 0 on property:sys.usb.config =adb && property:sys.usb.configfs=1 start adbd on property:sys.usb.ffs.ready =1 && property:sys.usb.config =adb && property:sys.usb.configfs=1 write /config /usb_gadget/g1/configs/b.1 /strings/0x409 /configuration "adb" symlink /config /usb_gadget/g1/functions/ffs.adb /config /usb_gadget/g1/configs/b.1 /f1 write /config /usb_gadget/g1/UDC ${sys.usb.controller} setprop sys.usb.state ${sys.usb.config } on property:sys.usb.config =mtp,adb && property:sys.usb.configfs=1 start adbd
然后在项目mk文件里执行拷贝操作即可
1 2 PRODUCT_COPY_FILES += \ system/core/rootdir/init.usb.configfs_limit.rc:root/init.usb.configfs.rc
adb限制 客户有个需求,想要另外的开关来控制adb开启关闭,另外不想让原生的adb开关起效。
其实android上层控制adb开关,都是通过设置persist.sys.usb.config和sys.usb.config这两个属性值来控制的。如果这两个属性的值包含adb这个字段则会触发打开adb功能。
所以我们使用一个额外的属性persist.adb.enable来控制adb开关。 然后我们直接修改frameworks/base/core/java/android/os/SystemProperties.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public static void set (String key, String val) { if (val != null && val.length() > PROP_VALUE_MAX) { throw newValueTooLargeException(key, val); } if (key.equals(USB_PERSISTENT_CONFIG_PROPERTY)||key.equals(USB_CONFIG_PROPERTY)) { if (containsFunction(val,"adb" )&&getInt("persist.adb.enable" , 0 )>0 ){ val = "adb" ; }else { val = "none" ; } } if (TRACK_KEY_ACCESS) onKeyAccess(key); native_set(key, val); }
这样就可以通过persist.adb.enable属性来控制adb的开启和关闭,而原生的adb开关则不会起作用。