之前在Android5.1的时候我们分析过UsbDevicemanager,现在Android6.0我们不准备分析UsbDevicemanager了,因为大致原理差不多。而UsbDeviceManager是将手机作为一个设备,比如手机连上电脑,使用adb、mtp等。而这里准备分析的UsbHostManager,是将手机作为一个host,比如手机连接usb鼠标、usb摄像头等。
UsbHostManager的初始化
UsbHostManager和UsbDeviceManager一样都是在UsbService中新建的。
public UsbService(Context context) {
mContext = context;
mAlsaManager = new UsbAlsaManager(context);
final PackageManager pm = mContext.getPackageManager();
if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
mHostManager = new UsbHostManager(context, mAlsaManager);
}
然后在UsbService的systemReady中调用了UsbHostManager的systemReady函数。
public void systemReady() {
mAlsaManager.systemReady();
if (mDeviceManager != null) {
mDeviceManager.systemReady();
}
if (mHostManager != null) {
mHostManager.systemReady();
}
if (mPortManager != null) {
mPortManager.systemReady();
}
}
UsbHostManager的构造函数就是新建一些对象,我们直接看systemReady函数。这个函数在新的线程中调用了monitorUsbHostBus函数。
public void systemReady() {
synchronized (mLock) {
// Create a thread to call into native code to wait for USB host events.
// This thread will call us back on usbDeviceAdded and usbDeviceRemoved.
Runnable runnable = new Runnable() {
public void run() {
monitorUsbHostBus();
}
};
new Thread(null, runnable, "UsbService host thread").start();
}
}
而monitorUsbHostBus函数是一个JNI函数。
private native void monitorUsbHostBus();
UsbHostManager的hal层
monitorUsbHostBus对应的JNI函数是在com_android_server_UsbHostManager.cpp的android_server_UsbHostManager_monitorUsbHostBus函数,在这个函数调用了usb_host_init函数,创建了一个INotify的fd,以及创建了一个usb_host_context对象。usb_host_run函数就是循环读取INotify的fd的事件,我们把usb_device_added, usb_device_removed两个回调函数也传入了usb_host_run函数了。
static void android_server_UsbHostManager_monitorUsbHostBus(JNIEnv* /* env */, jobject thiz)
{
struct usb_host_context* context = usb_host_init();
if (!context) {
ALOGE("usb_host_init failed");
return;
}
// this will never return so it is safe to pass thiz directly
usb_host_run(context, usb_device_added, usb_device_removed, NULL, (void *)thiz);
}
usb_host_init是在system\core\libusbhost\usbhost.c文件中,这个函数中新建一个usb_host_context对象,还有新建了一个INotify,并且usb_host_context的fd就是INotify的fd。
struct usb_host_context *usb_host_init()
{
struct usb_host_context *context = calloc(1, sizeof(struct usb_host_context));//新建一个usb_host_context对象
if (!context) {
fprintf(stderr, "out of memory in usb_host_context\n");
return NULL;
}
context->fd = inotify_init();//新建一个INotify
if (context->fd < 0) {
fprintf(stderr, "inotify_init failed\n");
free(context);
return NULL;
}
return context;
}
我们再来看看usb_host_run函数。先调用了usb_host_load函数,这个函数主要把add和remove的回调,放到context相应的成员变量中,然后增加了dev目录放入INotify的观察。下面循环调用usb_host_read_event函数去读取INotify fd的事件。
void usb_host_run(struct usb_host_context *context,
usb_device_added_cb added_cb,
usb_device_removed_cb removed_cb,
usb_discovery_done_cb discovery_done_cb,
void *client_data)
{
int done;
done = usb_host_load(context, added_cb, removed_cb, discovery_done_cb, client_data);
while (!done) {
done = usb_host_read_event(context);
}
}
usb_host_load函数先把add和remove的两个回调设置到usb_host_context 中,然后将dev目录放入INotify观察。然后调用watch_existing_subdirs将/dev/bus/usb下的目录都添加到INotify中观察,最后再调用find_existing_devices函数,把找到的设备调用added_cb(增加的回调函数)
int usb_host_load(struct usb_host_context *context,
usb_device_added_cb added_cb,
usb_device_removed_cb removed_cb,
usb_discovery_done_cb discovery_done_cb,
void *client_data)
{
int done = 0;
int i;
context->cb_added = added_cb;//回调赋值
context->cb_removed = removed_cb;
context->data = client_data;
D("Created device discovery thread\n");
/* watch for files added and deleted within USB_FS_DIR */
context->wddbus = -1;
for (i = 0; i < MAX_USBFS_WD_COUNT; i++)
context->wds[i] = -1;
/* watch the root for new subdirectories */
context->wdd = inotify_add_watch(context->fd, DEV_DIR, IN_CREATE | IN_DELETE);//将dev目录放入INotify观察
if (context->wdd < 0) {
fprintf(stderr, "inotify_add_watch failed\n");
if (discovery_done_cb)
discovery_done_cb(client_data);
return done;
}