Android 8.1 usb gadget configuration
平台: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;
......
}
}