转载请注明出处: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不能同时兼容。上层能够设定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。故剩余步骤可参考2.
原文:http://blog.csdn.net/droyon/article/details/45098027