Android USB 在framework相关源码分析
USB插拔这一块内容比较多,在实际开发过程中,暴露出来的问题也比较多,而且有些问题还比较不好解决,定位过程中不能一下就定位出是framework层还是kernal层部分的问题(就比如遇到的一个平板连接多设备,有打印机,2D扫描类Hub的方式)。因此,对于做frameowork开发来讲,深入理解这一块(至少在App/Framework层要理解透彻)是非常有必要的。
由于在写这篇博客的时候,是以写->补->写->补的方式来的,没有按照一定的顺序,比如遵循从kernal—>framework—>到app,或者app—>framework—>kernal有条理的来,而只是按照了一些小的流程线来说的,源码看到哪,就说哪。
第一节
Kernal 与 Framework层交互 UEventObserver;插入与拔出USB设备,事件监听以及上报.UEventObserver
涉及到的类文件:
- android_os_UEventObserver.cpp
./frameworks/base/core/jni/android_os_UEventObserver.cpp
- UEventObserver.java
./frameworks/base/core/java/android/os/UEventObserver.java
插拔U盘,usb事件上报
在UsbDeviceManager.java的构造方法中,添加了USB_STATE_MATCH和ACCESSORY_START_MATCH监听。因此,下面我们就按照源码跟踪framework与kernal交互的这段边界部分。
...
// Watch for USB configuration changes
mUEventObserver.startObserving(USB_STATE_MATCH);
mUEventObserver.startObserving();
...
下面我们转到UEventObserver中,UEventObserver 是一个Interface,定义了一个回调方法,onUEvent,通过它将kernal 上报事件传递至app/framework层、
/*mUEventObserver的声明:
* Listens for uevent messages from the kernel to monitor the USB state
*/
private final UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) { //这里从UEventThead
String state = event.get("USB_STATE");
String accessory = event.get("ACCESSORY");
if (state != null) {
mHandler.updateState(state); //更新USB当前的状态,CONNECTED ,DISCONNECTED,CONFIGURED
} else if ...
}
};
先看UEventObserver中的startObservering方法
public final void startObserving(String match) {
...
//The UEventThread is Singleton pattern.
final UEventThread t = getThread();
t.addObserver(match, this); //this参数,当onUEvent回调时,则回调到注册的这个Observer中。
}
接下来,startObserving方法转到了UEventThread中。UEventThread是个线程是UEventObserver的内部类,run方法中是个死循环,不断地监听UEvent,当有事件从Kernal上报时,则通过Handler一步步上传。UEventThread 在UEventObserver中以单例模式存在。
//Create the thread and start it
private static UEventThread getThread() {
synchronized (UEventObserver.class) { //keep it sysncronized
if (sThread == null) {
sThread = new UEventThread(); //第一次创建并start
sThread.start();
}
return sThread;
}
}
UEventThread:
private static final class UEventThread extends Thread {
/** Many to many mapping of string match to observer.
* Multimap would be better, but not available in android, so use
* an ArrayList where even elements are the String match and odd
* elements the corresponding(相关的) UEventObserver observer */
private final ArrayList<Object> mKeysAndObservers = new ArrayList<Object>();
private final ArrayList<UEventObserver> mTempObserversToSignal =
new ArrayList<UEventObserver>();
public UEventThread() {
super("UEventObserver");
}
@Override
public void run() {
nativeSetup();
while (true) {
// a loop to get Event everytime
String message = nativeWaitForNextEvent();//wait for the next Event
if (message != null) {
sendEvent(message);
}
}
}
//向上层发送Event
private void sendEvent(String message) {
synchronized (mKeysAndObservers) {
final int N = mKeysAndObservers.size();
for (int i = 0; i < N; i += 2) {
final String key = (String)mKeysAndObservers.get(i); // the match String index is i
//遍历list中所有的match String
if (message.contains(key)) {
final UEventObserver observer =
(UEventObserver)mKeysAndObservers.get(i + 1); // then , the Observer object in ArrayList index is (i+1)
mTempObserversToSignal.add(observer);
}
}
}
if (!mTempObserversToSignal.isEmpty()) {
final UEvent event = new UEvent(message);
//mTempObserversToSignal存储是的与该message相配套的Observer,所以这里遍历后,将message全部发出去。
final int N = mTempObserversToSignal.size();
for</