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