记录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开关则不会起作用。