天天看點

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;
                    
     			......
            }
        }