Android 8.1 usb gadget configuration

  • Android的usb gadget配置流程
  • 开机过程中usb gadget配置
    • 第一种:rc脚本
    • 第二种:UsbDeviceManager.java

平台:MT6739
系统:Android 8.1

Android的usb gadget配置流程

对于Android系统,和应用,要改变usb gadget是通过配置如下两个prop属性:
persist.sys.usb.config
sys.usb.config

配置“sys.usb.config”之后,系统会执行.rc脚本里面对应的规则,来改变kernel的usb configs对应节点的值,进而控制usb gadget驱动切换到对应的device,例如:

on property:sys.usb.ffs.ready=1 && property:sys.usb.config=adb && property:sys.usb.configfs=1write /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/f1write /config/usb_gadget/g1/UDC ${sys.usb.controller}setprop sys.usb.state ${sys.usb.config}

开机过程中usb gadget配置

开机过程直到开机完成,这一阶段,有两个地方去配置“sys.usb.config”:一是在.rc脚本里面,在“on boot”或者其他阶段,去执行了“setprop”;另外是在“UsbDeviceManager.java”文件里,“MSG_BOOT_COMPLETED”开机完成消息的时候。

第一种:rc脚本

一般系统都会设置一个“persist.sys.usb.config”的默认配置,比如在文件:
device/mediatek/mt6739/device.mk

ifeq ($(TARGET_BUILD_VARIANT),user)PRODUCT_DEFAULT_PROPERTY_OVERRIDES += persist.sys.usb.config=mtp
elsePRODUCT_DEFAULT_PROPERTY_OVERRIDES += persist.sys.usb.config=adb
endif

区分user和eng模式,设置不同的默认配置,然后用如下python脚本:
build/make/tools/post_process_props.py

# Put the modifications that you need to make into the /system/etc/prop.default into this
# function. The prop object has get(name) and put(name,value) methods.
def mangle_default_prop(prop):# If ro.debuggable is 1, then enable adb on USB by default# (this is for userdebug builds)if prop.get("ro.debuggable") == "1":val = prop.get("persist.sys.usb.config")if "adb" not in val:if val == "":val = "adb"else:val = val + ",adb"prop.put("persist.sys.usb.config", val)# UsbDeviceManager expects a value here.  If it doesn't get it, it will# default to "adb". That might not the right policy there, but it's better# to be explicit.if not prop.get("persist.sys.usb.config"):prop.put("persist.sys.usb.config", "none");

将默认“persist.sys.usb.config”写入out目录输出文件:
/system/etc/prop.default

这个“persist.sys.usb.config”属性起作用是在脚本文件:
system/core/rootdir/init.usb.rc(也有可能在源码device目录下的.rc脚本里)

# Used to set USB configuration at boot and to switch the configuration
# when changing the default configuration
on boot && property:persist.sys.usb.config=*setprop sys.usb.config ${persist.sys.usb.config}

可以看到,最终还是执行了“setprop sys.usb.config”。

这样开机的时候,就会设置usb gadget为“persist.sys.usb.config”默认的配置,我们也可手动添加config,实现想要的device,例如:

on bootsetprop sys.usb.config mtp,adb

第二种:UsbDeviceManager.java

这个文件目录:
frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java

    /*** The persistent property which stores whether adb is enabled or not.* May also contain vendor-specific default functions for testing purposes.*/private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config";/*** The non-persistent property which stores the current USB settings.*/private static final String USB_CONFIG_PROPERTY = "sys.usb.config";

主要的逻辑都在:private final class UsbHandler extends Handler {}
这个私有类里面。其构造方法如下:

        //这是私有类“UsbHandler”的构造方法public UsbHandler(Looper looper) {super(looper);try {// Restore default functions.//获取到当前“sys.usb.config”的配置if (isNormalBoot()) {mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,UsbManager.USB_FUNCTION_NONE);mCurrentFunctionsApplied = mCurrentFunctions.equals(SystemProperties.get(USB_STATE_PROPERTY));} else {mCurrentFunctions = SystemProperties.get(getPersistProp(true),UsbManager.USB_FUNCTION_NONE);mCurrentFunctionsApplied = SystemProperties.get(USB_CONFIG_PROPERTY,UsbManager.USB_FUNCTION_NONE).equals(SystemProperties.get(USB_STATE_PROPERTY));}/** Use the normal bootmode persistent prop to maintain state of adb across* all boot modes.*///根据“persist.sys.usb.config”的配置是否包含ADB,来记录是否使能ADBmAdbEnabled = UsbManager.containsFunction(SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY),UsbManager.USB_FUNCTION_ADB);/** Previous versions can set persist config to mtp/ptp but it does not* get reset on OTA. Reset the property here instead.*///如果“persist.sys.usb.config”里面包含“mtp/ptp”,则去除之后,重新设置“persist.sys.usb.config”String persisted = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY);if (UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_MTP)|| UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_PTP)) {SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY,UsbManager.removeFunction(UsbManager.removeFunction(persisted,UsbManager.USB_FUNCTION_MTP), UsbManager.USB_FUNCTION_PTP));}String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();updateState(state);// register observer to listen for settings changesmContentResolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),false, new AdbSettingsObserver());// Watch for USB configuration changesmUEventObserver.startObserving(USB_STATE_MATCH);mUEventObserver.startObserving(ACCESSORY_START_MATCH);} catch (Exception e) {Slog.e(TAG, "Error initializing UsbHandler", e);}}

其他一些主要的方法有:
1.private void setUsbConfig(String config) {}
设置“sys.usb.config”属性用的方法,等同于“setprop”命令

        private void setUsbConfig(String config) {if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");// set the new configuration// we always set it due to b/23631400, where adbd was getting killed// and not restarted due to property timeouts on some devicesSystemProperties.set(USB_CONFIG_PROPERTY, config);}

2.private String applyAdbFunction(String functions) {}
根据变量“mAdbEnabled”来决定,给传入的参数增加还是去除ADB配置

        private String applyAdbFunction(String functions) {// Do not pass null pointer to the UsbManager.// There isnt a check there.if (functions == null) {functions = "";}if (mAdbEnabled) {functions = UsbManager.addFunction(functions, UsbManager.USB_FUNCTION_ADB);} else {functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_ADB);}return functions;}

3.private void setAdbEnabled(boolean enable) {}
控制ADB功能的使能和关闭

        private void setAdbEnabled(boolean enable) {if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);if (enable != mAdbEnabled) {mAdbEnabled = enable;String oldFunctions = mCurrentFunctions;//重新设置“persist.sys.usb.config”属性// Persist the adb settingString newFunction = applyAdbFunction(SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_NONE));SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunction);// Remove mtp from the config if file transfer is not enabledif (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) &&!mUsbDataUnlocked && enable) {oldFunctions = UsbManager.USB_FUNCTION_NONE;}setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked);updateAdbNotification(false);}if (mDebuggingManager != null) {mDebuggingManager.setAdbEnabled(mAdbEnabled);}}

4.private String getDefaultFunctions() {}
获取系统默认的配置

        private String getDefaultFunctions() {String func = SystemProperties.get(getPersistProp(true),UsbManager.USB_FUNCTION_NONE);// if ADB is enabled, reset functions to ADB// else enable MTP as usual.if (UsbManager.containsFunction(func, UsbManager.USB_FUNCTION_ADB)) {return UsbManager.USB_FUNCTION_ADB;} else {return UsbManager.USB_FUNCTION_MTP;}}

5.private void setEnabledFunctions(String functions, boolean forceRestart,boolean usbDataUnlocked) {}
判断并设置系统需要的配置,设置的动作调用的方法“trySetEnabledFunctions”

        private void setEnabledFunctions(String functions, boolean forceRestart,boolean usbDataUnlocked) {if (DEBUG) {Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "+ "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked);}if (usbDataUnlocked != mUsbDataUnlocked) {mUsbDataUnlocked = usbDataUnlocked;updateUsbNotification(false);forceRestart = true;}// Try to set the enabled functions.final String oldFunctions = mCurrentFunctions;final boolean oldFunctionsApplied = mCurrentFunctionsApplied;if (trySetEnabledFunctions(functions, forceRestart)) {return;}......}

6.private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {}
有上面“setEnabledFunctions”方法调用,执行最终的设置动作

        private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {//对参数“functions”做判断,不符合条件的话,使用默认配置if (functions == null || applyAdbFunction(functions).equals(UsbManager.USB_FUNCTION_NONE)) {functions = getDefaultFunctions();}//判断是否需要ADBfunctions = applyAdbFunction(functions);String oemFunctions = applyOemOverrideFunction(functions);if (!isNormalBoot() && !mCurrentFunctions.equals(functions)) {SystemProperties.set(getPersistProp(true), functions);}if ((!functions.equals(oemFunctions) &&(mCurrentOemFunctions == null ||!mCurrentOemFunctions.equals(oemFunctions)))|| !mCurrentFunctions.equals(functions)|| !mCurrentFunctionsApplied|| forceRestart) {Slog.i(TAG, "Setting USB config to " + functions);mCurrentFunctions = functions;mCurrentOemFunctions = oemFunctions;mCurrentFunctionsApplied = false;// Kick the USB stack to close existing connections.//先关闭usb gadgetsetUsbConfig(UsbManager.USB_FUNCTION_NONE);if (!waitForState(UsbManager.USB_FUNCTION_NONE)) {Slog.e(TAG, "Failed to kick USB config");return false;}// Set the new USB configuration.//再设置需要的配置setUsbConfig(oemFunctions);if (mBootCompleted&& (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)|| UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) {// Start up dependent services.updateUsbStateBroadcastIfNeeded(true);}if (!waitForState(oemFunctions)) {Slog.e(TAG, "Failed to switch USB config to " + functions);return false;}mCurrentFunctionsApplied = true;}return true;}

7.public void handleMessage(Message msg) {}
消息处理方法,开机完成的“MSG_BOOT_COMPLETED”消息就是在这里处理

        @Overridepublic void handleMessage(Message msg) {switch (msg.what) {......case MSG_BOOT_COMPLETED:mBootCompleted = true;if (mPendingBootBroadcast) {updateUsbStateBroadcastIfNeeded(false);mPendingBootBroadcast = false;}//可以在这里重新设置usb gadget//例如:null --> SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY)setEnabledFunctions(null, false, false);if (mCurrentAccessory != null) {getCurrentSettings().accessoryAttached(mCurrentAccessory);}if (mDebuggingManager != null) {mDebuggingManager.setAdbEnabled(mAdbEnabled);}break;......}}

Android 8.1 usb gadget configuration相关推荐

  1. linux/android系统的USB gadget configfs用户空间配置USB HID U盘 adb dcd等模式的使用

    USB gadget configfs模式的使用: 即可android或linux在用户空间配置实现设备终端为HID,U盘.Adb以及cdc等功能 1.创建gadgets 每个gadget都必须创建自 ...

  2. android usb gadget分析

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

  3. USB gadget 驱动之 android.c

    1. Gadget驱动 1.1 Gadget框架结构 kernel/drivers/usb/gadget,这个目录是android下usb gadget的主要目录. (1)Gadget功能组织单元:主 ...

  4. Android USB gadget

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

  5. android usb_disk2,Android USB gadget configfs学习笔记总结

    1.一个config_item 是通过显式用户空间mkdir操作创建的,通过rmdir销毁.属性(文件)在mkdir之后出现,可以通过read和write读取或修改属性文件.与sysfs一样,read ...

  6. usb gadget configfs 验证

    内核打开对应的宏 1.必须打开CONFIG_CONFIGFS_FS和CONFIG_USB_LIBCOMPOSITE的宏,前者为用户空间提供访问配置内核驱动的configfs文件系统,后者提供usb g ...

  7. 继续写usb gadget驱动(解决枚举失败问题)

    上个小patch吧... 关于昨天的usb枚举失败(获取配置描述符失败) 简要描述下: 1. 我的gadget配置成了usb3.2版本,  (设置成1.0, 2.0也遇到一些问题, 暂表不论) Pro ...

  8. linux usb gadget 日志

    1,USB 协议入门 几种USB控制器类型:OHCI,UHCI,EHCI,XHCI 遇到过一些关于USB的东西(如下),一直没搞明白什么USB1.0/1.1/2.0/3.0之类的,当然我知道它们的各自 ...

  9. USB gadget(1)----gadget driver

    USB gadget----gadget driver USB gadget Driver USB gadget(1)----controller driver中,匹配gadget driver时,调 ...

最新文章

  1. R包stringr处理字符串
  2. ftp安装遇到的问题
  3. Ruby --- gem(RubyGems)安装与使用
  4. 彻底掌握Linux文件与目录管理命令?进来看看硬核总结
  5. Windows FFMPEG开发环境配置
  6. ubuntu 清空/tmp目录
  7. Waymo无人出租车年底发射,现已进入定价环节 | 公交部门竟成友军?
  8. Python+OpenCV:直方图均衡化(Histogram Equalization)
  9. 16进制字符串转字节数组
  10. Filestream 使用简单步骤
  11. Codeforces Round #518 (Div. 2) B LCM
  12. 计算机组装与维护精品,国家精品课程——《计算机组装与维护》.pdf
  13. dbutilsjar包下载_commons dbutils 下载-commons dbutils.jar下载 v1.6官方版--pc6下载站
  14. 无缝轮播图无缝轮播图
  15. Warshall算法C语言实现
  16. 什么是苹果cms?苹果cms如何安装及使用?
  17. chrome中了flash过期的解决方法
  18. 如何下载打印计算机二级准考证(江西)
  19. kali终端打不开以及msfconsole打不开
  20. nginx是什么?有什么用?

热门文章

  1. 数商云石油化工行业B2B集采平台解决方案:提高采购议价能力,规范化采购流程
  2. 如何在MDTools中设置不同种类元件的装配参考
  3. 【joysticker】【Linux】Python脚本实现USB游戏手柄的驱动
  4. 【java游戏项目】适合初学者练习的java小游戏--大鱼吃小鱼
  5. taichi随时暂停运行
  6. 服务器win和linux系统安装教程,Win+linux双系统安装
  7. 管理学理论(SWOT分析等八种理论)
  8. python怎么获取所有文件名_python 获取当前文件夹下所有文件名
  9. 计算机面试英语四级,震惊!男子未过四级,却说考研英语面试太简单!
  10. 【使用Blazor构建web应用程序 .NET 6篇 中】