您的位置:首页 > 移动开发 > Android开发

android usb相关知识总结

2015-04-18 21:07 309 查看
转载请注明出处:http://blog.csdn.net/droyon/article/details/45098027

1、android背景介绍

UsbService,在系统启动时创建,在该文件中,和usb状态息息相关的操作类是UsbDeviceManager,大部分的usb以及adb相关的逻辑,在这个类中做处理。UsbDeviceManager中,我们需要关注三部分内容。一、配置文件。二、  private final UEventObserver mUEventObserver = new UEventObserver() ,接受UEvent事件。三、UsbHandler。

其中配置文件,保存当前usb状态。UEventObserver接受usb事件,push给UsbHandler来处理。UsbHandler是用来处理Usb事件的关键类。

2、Usb默认状态从哪里获取,当前的默认状态又是什么?

Usb的当前状态保存在mCurrentFunctions成员变量中,该变量在UsbHandler的构造中进行初始化。

mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb");

// Check if USB mode needs to be overridden depending on OEM specific bootmode.
mDefaultFunctions = processOemUsbOverride(mDefaultFunctions);

// sanity check the sys.usb.config system property
// this may be necessary if we crashed while switching USB configurations
String config = SystemProperties.get("sys.usb.config", "none");
if (!config.equals(mDefaultFunctions)) {
Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions);
SystemProperties.set("sys.usb.config", mDefaultFunctions);
}

mCurrentFunctions = mDefaultFunctions;

3、插入usb时,弹出adb以及Notification通知的大体流程是什么?

插入usb时,我们的UEventObserver会收到信息,最终push给UsbHandler。

UEvent信息:

04-17 14:20:03.352 V/UsbDeviceManager(  759): USB UEVENT: {USB_STATE=DISCONNECTED, SUBSYSTEM=android_usb, SEQNUM=7528, ACTION=change, DEVPATH=/devices/virtual/android_usb/android0}
然后执行UsbHandler的updateState方法。
private final UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString());

String state = event.get("USB_STATE");
String accessory = event.get("ACCESSORY");
if (state != null) {
mHandler.updateState(state);
} else if ("START".equals(accessory)) {
if (DEBUG) Slog.d(TAG, "got accessory start");
startAccessoryMode();
}
}
};


updateState方法:更新mConnection状态。

public void updateState(String state) {
int connected, configured;

if ("DISCONNECTED".equals(state)) {
connected = 0;
configured = 0;
} else if ("CONNECTED".equals(state)) {
connected = 1;
configured = 0;
} else if ("CONFIGURED".equals(state)) {
connected = 1;
configured = 1;
} else {
Slog.e(TAG, "unknown state " + state);
return;
}
removeMessages(MSG_UPDATE_STATE);
Message msg = Message.obtain(this, MSG_UPDATE_STATE);
msg.arg1 = connected;
msg.arg2 = configured;
// debounce disconnects to avoid problems bringing up USB tethering
sendMessageDelayed(msg, (connected == 0) ? UPDATE_DELAY : 0);
}
最后在UsbHandler中进行更新状态,进而弹出adb以及usb的Notification

case MSG_UPDATE_STATE:
mConnected = (msg.arg1 == 1);
mConfigured = (msg.arg2 == 1);
updateUsbNotification();
updateAdbNotification();
if (containsFunction(mCurrentFunctions,
UsbManager.USB_FUNCTION_ACCESSORY)) {
updateCurrentAccessory();
} else if (!mConnected) {
// restore defaults when USB is disconnected
setEnabledFunctions(mDefaultFunctions, false);
}
if (mBootCompleted) {
updateUsbState();
updateAudioSourceFunction();
}
break;
4、可设置的usb类型有哪些?
public static final String USB_FUNCTION_MASS_STORAGE = "mass_storage";

/**
* Name of the adb USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
* {@hide}
*/
public static final String USB_FUNCTION_ADB = "adb";

/**
* Name of the RNDIS ethernet USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
* {@hide}
*/
public static final String USB_FUNCTION_RNDIS = "rndis";

/**
* Name of the MTP USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
* {@hide}
*/
public static final String USB_FUNCTION_MTP = "mtp";

/**
* Name of the PTP USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
* {@hide}
*/
public static final String USB_FUNCTION_PTP = "ptp";

/**
* Name of the CHARGING USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
* {@hide}
*/
public static final String USB_FUNCTION_CHARGING = "charging";

/**
* Name of the audio source USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
* {@hide}
*/
public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";

/**
* Name of the Accessory USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*
* {@hide}
*/
public static final String USB_FUNCTION_ACCESSORY = "accessory";

这些是其定义。其中adb与charging不能同时兼容。

ps:Charging在底层是没有设备文件与之对应的,设定充电模式,会将adb等配置移除.

5、设置usb的流程是什么?

上层能够设定usb类型的类名叫做:UsbSettings,在其中,用户可以设定当前UsbSettings状态为mtp、ptp以及厂商定义的其他usb状态。

在用户操作时,会调用mUsbManager.setCurrentFunction(function, true);

tring function = USB_FUNCTION_DEFAULT;
if (preference == mMtp && mMtp.isChecked()) {
function = UsbManager.USB_FUNCTION_MTP;
} else if (preference == mPtp && mPtp.isChecked()) {
function = UsbManager.USB_FUNCTION_PTP;
} else if (preference == mCharging && mCharging.isChecked()) {
function = UsbManager.USB_FUNCTION_CHARGING;
} else if (preference == mSDCard && mSDCard.isChecked()) {
function = UsbManager.USB_FUNCTION_MASS_STORAGE;
}

operateInprogress = true;
mUsbManager.setCurrentFunction(function, true);
updateToggles(function);
USBManager会继而调用UsbService的setCurrentFunction

UsbService.java

@Override
public void setCurrentFunction(String function, boolean makeDefault) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);

// If attempt to change USB function while file transfer is restricted, ensure that
// the current function is set to "none", and return.
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
if (mDeviceManager != null) mDeviceManager.setCurrentFunctions("none", false);
return;
}

if (mDeviceManager != null) {
mDeviceManager.setCurrentFunctions(function, makeDefault);
} else {
throw new IllegalStateException("USB device mode not supported");
}
}

最终还是会调用UsbDeviceManager中的setCurrentFunction。

UsbDeviceManager.java

public void setCurrentFunctions(String functions, boolean makeDefault) {
if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ") default: " + makeDefault);
mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, makeDefault);
}在内部类UsbHandler中:
case MSG_SET_CURRENT_FUNCTIONS:
String functions = (String)msg.obj;
boolean makeDefault = (msg.arg1 == 1);
setEnabledFunctions(functions, makeDefault);
break;setEnabledFunctions方法中:
private void setEnabledFunctions(String functions, boolean makeDefault) {
if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions
+ " makeDefault: " + makeDefault);

// Do not update persystent.sys.usb.config if the device is booted up
// with OEM specific mode.
if (functions != null && makeDefault && !needsOemUsbOverride()) {//0,persist.sys.usb.config为usb的默认配置值,makeDefault是说在每次Usb切换时,是否改变默认配置.

if (!UsbManager.USB_FUNCTION_CHARGING.equals(functions)
&& mAdbEnabled) {//1,首先UsbManager是否设定为充电模式,如果是,从当前UsbFuncton中移除adb,否则,为当前UsbFunctions增加adb.
functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
} else {
functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
}
if (!mDefaultFunctions.equals(functions)) {//2,如果当前模式与当前默认模式不一致
if (!setUsbConfig("none")) {//3,设定sys.usb.config为none[在由一种usb模式切换为另一种usb模式时,需要先将之前的模式设定为none,因为
//init.rc中有如下触发器:on property:persist.sys.usb.config=* setprop sys.usb.config $persist.sys.usb.config]
Slog.e(TAG, "Failed to disable USB");
// revert to previous configuration if we fail
setUsbConfig(mCurrentFunctions);
return;
}
// setting this property will also change the current USB state
// via a property trigger
SystemProperties.set("persist.sys.usb.config", functions);//4,设定当前usb 功能配置,同时sys.usb.config也会随着改变,因为触发器的原因.
if (waitForState(functions)) {
mCurrentFunctions = functions;
mDefaultFunctions = functions;
} else {
Slog.e(TAG, "Failed to switch persistent USB config to " + functions);
// revert to previous configuration if we fail
SystemProperties.set("persist.sys.usb.config", mDefaultFunctions);
}
}
} else {
if (functions == null) {
functions = mDefaultFunctions;
}

// Override with bootmode specific usb mode if needed
functions = processOemUsbOverride(functions);

if (!UsbManager.USB_FUNCTION_CHARGING.equals(functions)
&& mAdbEnabled) {//5,首先UsbManager是否设定为充电模式,如果是,从当前UsbFuncton中移除adb,否则,为当前UsbFunctions增加adb.
functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
} else {
functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
}
if (!mCurrentFunctions.equals(functions)) {//6,当前模式与设定不一致时,设定sys.usb.config,底层会读取该属性,进而启用相应的设备文件节点.
if (!setUsbConfig("none")) {
Slog.e(TAG, "Failed to disable USB");
// revert to previous configuration if we fail
setUsbConfig(mCurrentFunctions);
return;
}
if (setUsbConfig(functions)) {
mCurrentFunctions = functions;
} else {
Slog.e(TAG, "Failed to switch USB config to " + functions);
// revert to previous configuration if we fail
setUsbConfig(mCurrentFunctions);
}
}
}
}

总结:

1,在usb链接状态时,sys.usb.config与persist.sys.usb.config由于触发器的原因会保持一致.

2,当Usb状态断开时,sys.usb.config由于与persist.sys.usb.config触发器的原因,本应保持一致,但应移除是否含有adb功能配置.

3,充电模式与adb不可同时共存.

附:log文件:

1,由ptp切换模式至mtp模式log信息:

07-15 20:34:56.862 D/UsbDeviceManager(  761): setEnabledFunctions - functions: mtp

07-15 20:34:56.862 D/UsbDeviceManager(  761): setEnabledFunctions - mDefaultFunctions: ptp,adb

07-15 20:34:56.862 D/UsbDeviceManager(  761): setEnabledFunctions - mCurrentFunctions: ptp,adb

07-15 20:34:56.862 D/UsbDeviceManager(  761): setEnabledFunctions - mSettingFunction: ptp,adb

07-15 20:34:56.862 D/UsbDeviceManager(  761): Add adb into mtp

07-15 20:34:56.862 D/UsbDeviceManager(  761): sys.usb.acm_idx=,mAcmPortIdx=

07-15 20:34:56.867 D/UsbDeviceManager(  761): setEnabledFunctions - functions: mtp,adb

07-15 20:34:56.868 D/UsbDeviceManager(  761): setUsbConfig(none)

07-15 20:34:56.868 D/UsbDeviceManager(  761): setUsbConfig - config: none

07-15 20:34:56.976 D/UsbDeviceManager(  761): handleMessage - MSG_SET_CURRENT_FUNCTION - functions: mtp

07-15 20:34:57.241 V/UsbDeviceManager(  761): USB UEVENT: {USB_STATE=DISCONNECTED, SUBSYSTEM=android_usb, SEQNUM=2751, ACTION=change, DEVPATH=/devices/virtual/android_usb/android0}

07-15 20:34:57.242 D/UsbDeviceManager(  761): mUEventObserver - onUEvent - state: DISCONNECTED

07-15 20:34:57.242 D/UsbDeviceManager(  761): updateState - DISCONNECTED

07-15 20:34:57.242 D/UsbDeviceManager(  761): updateState - RNDIS_UPDATE_DELAY  DISCONNECTED mSettingFunction: mtp

07-15 20:34:57.331 V/UsbDeviceManager(  761): USB UEVENT: {USB_STATE=CONNECTED, SUBSYSTEM=android_usb, SEQNUM=2756, ACTION=change, DEVPATH=/devices/virtual/android_usb/android0}

07-15 20:34:57.331 D/UsbDeviceManager(  761): mUEventObserver - onUEvent - state: CONNECTED

07-15 20:34:57.331 D/UsbDeviceManager(  761): updateState - CONNECTED

07-15 20:34:57.331 D/UsbDeviceManager(  761): updateState - RNDIS_UPDATE_DELAY  CONNECTED mSettingFunction: mtp

07-15 20:34:57.332 W/UsbDeviceManager(  761): handleMessage - 0

07-15 20:34:57.332 D/UsbDeviceManager(  761): updateUsbNotification - mNotificationManager: android.app.NotificationManager@230489b9

07-15 20:34:57.332 D/UsbDeviceManager(  761): updateUsbNotification - mUseUsbNotification: true

07-15 20:34:57.332 W/UsbDeviceManager(  761): updateUsbNotification - mConnected: true

07-15 20:34:57.332 W/UsbDeviceManager(  761): updateUsbNotification - mCurrentFunctions: mtp,adb

07-15 20:34:57.332 D/UsbDeviceManager(  761): updateUsbNotification - containsFunction:  USB_FUNCTION_MTP

07-15 20:34:57.332 D/UsbDeviceManager(  761): UsbDeviceManager updateUsbNotification mConnected is:true,mBootCompleted is:true,mUsbNotificationId is:17040616,id is:17040615,mCurrentFunctions is:mtp,adb,mDefaultFunctions is:mtp,adb

07-15 20:34:57.334 V/UsbDeviceManager(  761): USB UEVENT: {USB_STATE=CONFIGURED, SUBSYSTEM=android_usb, SEQNUM=2757, ACTION=change, DEVPATH=/devices/virtual/android_usb/android0}

07-15 20:34:57.334 D/UsbDeviceManager(  761): mUEventObserver - onUEvent - state: CONFIGURED

07-15 20:34:57.334 D/UsbDeviceManager(  761): updateState - CONFIGURED

07-15 20:34:57.334 D/UsbDeviceManager(  761): updateState - RNDIS_UPDATE_DELAY  CONFIGURED mSettingFunction: mtp

07-15 20:34:57.340 D/UsbDeviceManager(  761): UsbDeviceManager updateUsbNotification mConnected is:true,mBootCompleted is:true,show is:true,setupWized is:true,isInCall is:false

07-15 20:34:57.342 D/UsbDeviceManager(  761): broadcasting Intent { act=android.hardware.usb.action.USB_STATE flg=0x20000000 (has extras) } connected: true configured: false

07-15 20:34:57.347 W/UsbDeviceManager(  761): sys.usb.mtpConnect = mtpConnection

07-15 20:34:57.347 D/UsbDeviceManager(  761): sys.usb.acm_idx=

07-15 20:34:57.347 D/UsbDeviceManager(  761): handleMessage mConnected:true,mConfigured:false, mHwDisconnected:false

07-15 20:34:57.347 W/UsbDeviceManager(  761): handleMessage - 0

07-15 20:34:57.347 D/UsbDeviceManager(  761): updateUsbNotification - mNotificationManager: android.app.NotificationManager@230489b9

07-15 20:34:57.347 D/UsbDeviceManager(  761): updateUsbNotification - mUseUsbNotification: true

07-15 20:34:57.347 W/UsbDeviceManager(  761): updateUsbNotification - mConnected: true

07-15 20:34:57.347 W/UsbDeviceManager(  761): updateUsbNotification - mCurrentFunctions: mtp,adb

07-15 20:34:57.347 D/UsbDeviceManager(  761): updateUsbNotification - containsFunction:  USB_FUNCTION_MTP

07-15 20:34:57.347 D/UsbDeviceManager(  761): UsbDeviceManager updateUsbNotification mConnected is:true,mBootCompleted is:true,mUsbNotificationId is:17040615,id is:17040615,mCurrentFunctions is:mtp,adb,mDefaultFunctions is:mtp,adb

07-15 20:34:57.348 D/UsbDeviceManager(  761): broadcasting Intent { act=android.hardware.usb.action.USB_STATE flg=0x20000000 (has extras) } connected: true configured: true

07-15 20:34:57.381 W/UsbDeviceManager(  761): sys.usb.mtpConnect = mtpConnection

07-15 20:34:57.381 D/UsbDeviceManager(  761): sys.usb.acm_idx=

07-15 20:34:57.381 D/UsbDeviceManager(  761): handleMessage mConnected:true,mConfigured:true, mHwDisconnected:false

2,由ptp切换为仅充电模式:

07-15 21:18:34.226 D/UsbDeviceManager(  753): setEnabledFunctions - functions: charging

07-15 21:18:34.226 D/UsbDeviceManager(  753): setEnabledFunctions - mDefaultFunctions: ptp,adb

07-15 21:18:34.226 D/UsbDeviceManager(  753): setEnabledFunctions - mCurrentFunctions: adb

07-15 21:18:34.226 D/UsbDeviceManager(  753): setEnabledFunctions - mSettingFunction: ptp

07-15 21:18:34.226 D/UsbDeviceManager(  753): sys.usb.acm_idx=,mAcmPortIdx=

07-15 21:18:34.232 D/UsbDeviceManager(  753): setEnabledFunctions - functions: charging

07-15 21:18:34.232 D/UsbDeviceManager(  753): setUsbConfig(none)

07-15 21:18:34.232 D/UsbDeviceManager(  753): setUsbConfig - config: none

07-15 21:18:48.838 D/UsbDeviceManager(  753): handleMessage - MSG_SET_CURRENT_FUNCTION - functions: ptp

07-15 21:18:49.344 D/UsbDeviceManager(  753): onReceive - BATTERY_CHANGED - mPlugType: 2, mSettingUsbCharging: false, mConnected: false, mSettingUsbBicr: false

07-15 21:18:49.425 V/UsbDeviceManager(  753): USB UEVENT: {USB_STATE=CONNECTED, SUBSYSTEM=android_usb, SEQNUM=2327, ACTION=change, DEVPATH=/devices/virtual/android_usb/android0}

07-15 21:18:49.426 D/UsbDeviceManager(  753): mUEventObserver - onUEvent - state: CONNECTED

07-15 21:18:49.426 D/UsbDeviceManager(  753): updateState - CONNECTED

07-15 21:18:49.426 D/UsbDeviceManager(  753): updateState - RNDIS_UPDATE_DELAY  CONNECTED mSettingFunction: ptp

07-15 21:18:49.427 W/UsbDeviceManager(  753): handleMessage - 0

07-15 21:18:49.427 D/UsbDeviceManager(  753): updateUsbNotification - mNotificationManager: android.app.NotificationManager@2f18b8c

07-15 21:18:49.427 D/UsbDeviceManager(  753): updateUsbNotification - mUseUsbNotification: true

07-15 21:18:49.427 W/UsbDeviceManager(  753): updateUsbNotification - mConnected: true

07-15 21:18:49.428 W/UsbDeviceManager(  753): updateUsbNotification - mCurrentFunctions: ptp,adb

07-15 21:18:49.428 D/UsbDeviceManager(  753): updateUsbNotification - containsFunction:  USB_FUNCTION_PTP

07-15 21:18:49.428 D/UsbDeviceManager(  753): UsbDeviceManager updateUsbNotification mConnected is:true,mBootCompleted is:true,mUsbNotificationId is:134545580,id is:17040616,mCurrentFunctions is:ptp,adb,mDefaultFunctions is:ptp,adb

07-15 21:18:49.435 V/UsbDeviceManager(  753): USB UEVENT: {USB_STATE=CONFIGURED, SUBSYSTEM=android_usb, SEQNUM=2328, ACTION=change, DEVPATH=/devices/virtual/android_usb/android0}

07-15 21:18:49.436 D/UsbDeviceManager(  753): mUEventObserver - onUEvent - state: CONFIGURED

07-15 21:18:49.436 D/UsbDeviceManager(  753): updateState - CONFIGURED

07-15 21:18:49.436 D/UsbDeviceManager(  753): updateState - RNDIS_UPDATE_DELAY  CONFIGURED mSettingFunction: ptp

07-15 21:18:49.449 D/UsbDeviceManager(  753): UsbDeviceManager updateUsbNotification mConnected is:true,mBootCompleted is:true,show is:true,setupWized is:true,isInCall is:false

07-15 21:18:49.453 D/UsbDeviceManager(  753): broadcasting Intent { act=android.hardware.usb.action.USB_STATE flg=0x20000000 (has extras) } connected: true configured: false

07-15 21:18:49.486 D/UsbDeviceManager(  753): onReceive - BATTERY_CHANGED - mPlugType: 2, mSettingUsbCharging: false, mConnected: true, mSettingUsbBicr: false

07-15 21:18:49.495 W/UsbDeviceManager(  753): sys.usb.mtpConnect = ptpConnection

07-15 21:18:49.496 D/UsbDeviceManager(  753): sys.usb.acm_idx=

07-15 21:18:49.496 D/UsbDeviceManager(  753): handleMessage mConnected:true,mConfigured:false, mHwDisconnected:false

07-15 21:18:49.497 W/UsbDeviceManager(  753): handleMessage - 0

07-15 21:18:49.498 D/UsbDeviceManager(  753): updateUsbNotification - mNotificationManager: android.app.NotificationManager@2f18b8c

07-15 21:18:49.498 D/UsbDeviceManager(  753): updateUsbNotification - mUseUsbNotification: true

07-15 21:18:49.498 W/UsbDeviceManager(  753): updateUsbNotification - mConnected: true

07-15 21:18:49.498 W/UsbDeviceManager(  753): updateUsbNotification - mCurrentFunctions: ptp,adb

07-15 21:18:49.498 D/UsbDeviceManager(  753): updateUsbNotification - containsFunction:  USB_FUNCTION_PTP

07-15 21:18:49.498 D/UsbDeviceManager(  753): UsbDeviceManager updateUsbNotification mConnected is:true,mBootCompleted is:true,mUsbNotificationId is:17040616,id is:17040616,mCurrentFunctions is:ptp,adb,mDefaultFunctions is:ptp,adb

07-15 21:18:49.499 D/UsbDeviceManager(  753): broadcasting Intent { act=android.hardware.usb.action.USB_STATE flg=0x20000000 (has extras) } connected: true configured: true

07-15 21:18:49.513 W/UsbDeviceManager(  753): sys.usb.mtpConnect = ptpConnection

07-15 21:18:49.513 D/UsbDeviceManager(  753): sys.usb.acm_idx=

07-15 21:18:49.513 D/UsbDeviceManager(  753): handleMessage mConnected:true,mConfigured:true, mHwDisconnected:false
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息