转载请注明出处: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