天天看点

Android 8.1 usb gadget configurationAndroid的usb gadget配置流程开机过程中usb gadget配置

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=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}
           

开机过程中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
else
  PRODUCT_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 boot
    setprop 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,来记录是否使能ADB
                mAdbEnabled = 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 changes
                mContentResolver.registerContentObserver(
                        Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
                        false, new AdbSettingsObserver());

                // Watch for USB configuration changes
                mUEventObserver.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 devices
            SystemProperties.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 setting
                String 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 enabled
                if (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();
            }
            //判断是否需要ADB
            functions = 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 gadget
                setUsbConfig(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”消息就是在这里处理

@Override
        public 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;
                    
     			......
            }
        }