USB(通用串行总线)主机模式向外设进行供电,使 Android 设备能够驱动 USB 总线,并且可以使用各种 USB 外设(包括音频接口,存储,MIDI),USB 和蓝牙低功耗连接都可以用于传输 MIDI 协议。USB配件模式,受外设供电驱动,包括数据传输,充电。USB开发模式,应用调试,唯一可见的外设功能是 Android fastboot 或 Android 调试桥 (adb)。fastboot 和 adb 协议所在层高于 USB 批量数据传输模式所在层。
Android 平台支持使用即插即用的 USB 摄像头(例如网络摄像头),但前提是这些摄像头采用标准的 Android Camera2 API 和摄像头 HIDL 接口,全新的 USB 摄像头 HAL 进程是外接摄像头提供程序的一部分,该提供程序会监听 USB 设备可用性,并相应地枚举外接摄像头设备。该进程具有与内置摄像头 HAL 进程类似的权限和 SE 策略。直接与 USB 设备通信的第三方网络摄像头应用访问 UVC 设备时所需的摄像头权限与所有常规摄像头应用所需的权限相同。
1. Usb服务启动
frameworks\base\services\usb\java\com\android\server\usb\UsbService.java
public static class Lifecycle extends SystemService {
private UsbService mUsbService;
......
@Override
public void onStart() { mUsbService = new UsbService(getContext());} //USB服务初始化
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mUsbService.systemReady(); //系统准备就绪
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mUsbService.bootCompleted();//系统启动完成
}
}
......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
frameworks\base\services\usb\java\com\android\server\usb\UsbService.java
初始化USB服务
public UsbService(Context context) {
mContext = context;
//多用户管理
mUserManager = context.getSystemService(UserManager.class);
//用户管理设置
mSettingsManager = new UsbSettingsManager(context);
//高级音频管理
mAlsaManager = new UsbAlsaManager(context);
//包管理
final PackageManager pm = mContext.getPackageManager();
//USB主机模式
if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
mHostManager = new UsbHostManager(context, mAlsaManager, mSettingsManager);
}
//USB设备管理
if (new File("/sys/class/android_usb").exists()) {
mDeviceManager = new UsbDeviceManager(context, mAlsaManager, mSettingsManager);
}
//USB端口管理
if (mHostManager != null || mDeviceManager != null) {
mPortManager = new UsbPortManager(context);
}
//切换为系统用户
onSwitchUser(UserHandle.USER_SYSTEM);
//注册设备代理管理
final IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(mReceiver, filter, null, null);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
frameworks\base\services\usb\java\com\android\server\usb\UsbService.java
public void systemReady() {
mAlsaManager.systemReady();
if (mDeviceManager != null) {
mDeviceManager.systemReady();
}
if (mHostManager != null) {
mHostManager.systemReady();
}
if (mPortManager != null) {
mPortManager.systemReady();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
frameworks\base\services\usb\java\com\android\server\usb\UsbAlsaManager.java
frameworks\base\services\usb\java\com\android\server\usb\UsbDeviceManager.java
frameworks\base\services\usb\java\com\android\server\usb\UsbHostManager.java
frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
//系统音频服务
public void systemReady() {
mAudioService = IAudioService.Stub.asInterface(
ServiceManager.getService(Context.AUDIO_SERVICE));
mAlsaObserver.startWatching(); //开始高级音频监听
......
}
//创建USB设备Notification
public void systemReady() {
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
// Ensure that the notification channels are set up
if (isTv()) {
// TV-specific notification channel
mNotificationManager.createNotificationChannel(
new NotificationChannel(ADB_NOTIFICATION_CHANNEL_ID_TV,
mContext.getString(
com.android.internal.R.string
.adb_debugging_notification_channel_tv),
NotificationManager.IMPORTANCE_HIGH));
}
......
mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
}
//启动USB主机模式总线
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();
}
}
//查询USB设备端口转状态
public void systemReady() {
if (mProxy != null) {
try {
mProxy.queryPortStatus();
} catch (RemoteException e) {
.......
}
}
mSystemReady = true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2. USB设备打开
frameworks\base\core\java\android\hardware\usb\UsbManager.java
public UsbDeviceConnection openDevice(UsbDevice device) {
try {
String deviceName = device.getDeviceName();
//打开USB设备,返回文件描述符FD
ParcelFileDescriptor pfd = mService.openDevice(deviceName);
if (pfd != null) {
//创建Socket连接通道,用于数据指令传输
UsbDeviceConnection connection = new UsbDeviceConnection(device);
boolean result = connection.open(deviceName, pfd, mContext);
pfd.close();
if (result) {
return connection;
}
}
} catch (Exception e) {
Log.e(TAG, "exception in UsbManager.openDevice", e);
}
return null;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
frameworks\base\services\usb\java\com\android\server\usb\UsbService.java
/* Opens the specified USB device (host mode) */
@Override
public ParcelFileDescriptor openDevice(String deviceName) {
ParcelFileDescriptor fd = null;
if (mHostManager != null) {
synchronized (mLock) {
if (deviceName != null) {
int userIdInt = UserHandle.getCallingUserId();
boolean isCurrentUser = isCallerInCurrentUserProfileGroupLocked();
//以主机模式打开制定USB
if (isCurrentUser) {
fd = mHostManager.openDevice(deviceName, getSettingsForUser(userIdInt));
} else {
Slog.w(TAG, "Cannot open " + deviceName + " for user " + userIdInt +
" as user is not active.");
}
}
}
}
return fd;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
frameworks\base\services\usb\java\com\android\server\usb\UsbHostManager.java
/* Opens the specified USB device */
public ParcelFileDescriptor openDevice(String deviceName, UsbUserSettingsManager settings) {
synchronized (mLock) {
if (isBlackListed(deviceName)) {
throw new SecurityException("USB device is on a restricted bus");
}
//从已存在的USB设备列表中查找一个
UsbDevice device = mDevices.get(deviceName);
......
settings.checkPermission(device);
return nativeOpenDevice(deviceName);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
frameworks\base\services\core\jni\com_android_server_UsbHostManager.cpp
static jobject android_server_UsbHostManager_openDevice(JNIEnv *env, jobject /* thiz */,
jstring deviceName)
{
const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
//调用系统提供的USB设备打开函数
struct usb_device* device = usb_device_open(deviceNameStr);
env->ReleaseStringUTFChars(deviceName, deviceNameStr);
//获得USB设备的文件描述符
int fd = usb_device_get_fd(device);
if (fd < 0) {
usb_device_close(device);
return NULL;
}
int newFD = dup(fd);
usb_device_close(device);
jobject fileDescriptor = jniCreateFileDescriptor(env, newFD);
if (fileDescriptor == NULL) {
return NULL;
}
return env->NewObject(gParcelFileDescriptorOffsets.mClass,
gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
system\core\libusbhost\usbhost.c
struct usb_device *usb_device_open(const char *dev_name)
{
int fd, did_retry = 0, writeable = 1;
D("usb_device_open %s\n", dev_name);
retry:
fd = open(dev_name, O_RDWR); //打开设备
if (fd < 0) {
/* if we fail, see if have read-only access */
//失败则以只读模式打开
fd = open(dev_name, O_RDONLY);
D("usb_device_open open returned %d errno %d\n", fd, errno);
if (fd < 0 && (errno == EACCES || errno == ENOENT) && !did_retry) {
/* work around race condition between inotify and permissions management */
sleep(1);
did_retry = 1;
goto retry;
}
if (fd < 0)
return NULL;
writeable = 0;
D("[ usb open read-only %s fd = %d]\n", dev_name, fd);
}
//新建一个USB设备
struct usb_device* result = usb_device_new(dev_name, fd);
if (result)
result->writeable = writeable;
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
system\core\libusbhost\usbhost.c
struct usb_device *usb_device_new(const char *dev_name, int fd)
{
struct usb_device *device = calloc(1, sizeof(struct usb_device)); //分配内存
int length;
D("usb_device_new %s fd: %d\n", dev_name, fd);
if (lseek(fd, 0, SEEK_SET) != 0)
goto failed;
length = read(fd, device->desc, sizeof(device->desc)); //读取设备描述符长度
D("usb_device_new read returned %d errno %d\n", length, errno);
if (length < 0)
goto failed;
strncpy(device->dev_name, dev_name, sizeof(device->dev_name) - 1);
device->fd = fd;
device->desc_length = length;
// assume we are writeable, since usb_device_get_fd will only return writeable fds
device->writeable = 1;
return device;
failed:
close(fd);
free(device);
return NULL;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
frameworks\base\core\java\android\hardware\usb\UsbDeviceConnection.java
public UsbDeviceConnection(UsbDevice device) {
mDevice = device;
}
/* package */ boolean open(String name, ParcelFileDescriptor pfd, @NonNull Context context) {
mContext = context.getApplicationContext();
boolean wasOpened = native_open(name, pfd.getFileDescriptor());
......
return wasOpened;
}
1
2
3
4
5
6
7
8
9
frameworks\base\core\jni\android_hardware_UsbDeviceConnection.cpp
调用JNI层打开指定的USB设备
static jboolean
android_hardware_UsbDeviceConnection_open(JNIEnv *env, jobject thiz, jstring deviceName,
jobject fileDescriptor)
{
int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
// duplicate the file descriptor, since ParcelFileDescriptor will eventually close its copy
fd = dup(fd);
if (fd < 0)
return JNI_FALSE;
const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
struct usb_device* device = usb_device_new(deviceNameStr, fd); //新建
if (device) {
env->SetLongField(thiz, field_context, (jlong)device);
} else {
ALOGE("usb_device_open failed for %s", deviceNameStr);
close(fd);
}
env->ReleaseStringUTFChars(deviceName, deviceNameStr);
return (device != NULL) ? JNI_TRUE : JNI_FALSE;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
3.USB设备检测
frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
设备端口管理
public UsbPortManager(Context context) {
mContext = context;
try {
//HIDL层的Service
boolean ret = IServiceManager.getService()
.registerForNotifications("[email protected]::IUsb",
"", mServiceNotification);
......
} catch (RemoteException e) {
......
return;
}
connectToProxy(null);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
private void connectToProxy(IndentingPrintWriter pw) {
synchronized (mLock) {
try {
//获取HIDL服务
mProxy = IUsb.getService();
mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);
//设置回调,一会儿再回头看
mProxy.setCallback(mHALCallback);
mProxy.queryPortStatus();
} catch (NoSuchElementException e) {
......
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
hardware\interfaces\usb\1.0\default\Usb.cpp
Return
pthread_mutex_lock(&mLock);
if ((mCallback == NULL && callback == NULL) ||
(mCallback != NULL && callback != NULL)) {
mCallback = callback;
pthread_mutex_unlock(&mLock);
return Void();
}
......
destroyThread = false;
signal(SIGUSR1, sighandler);
//创建线程,运行work
if (pthread_create(&mPoll, NULL, work, this)) {
ALOGE("pthread creation failed %d", errno);
mCallback = NULL;
}
pthread_mutex_unlock(&mLock);
return Void();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
hardware\interfaces\usb\1.0\default\Usb.cpp
使用EPOLL,UEVENT机制,多路IO阻塞复用
void* work(void* param) {
int epoll_fd, uevent_fd;
struct epoll_event ev;
int nevents = 0;
struct data payload;
uevent_fd = uevent_open_socket(64*1024, true); //创建套接
//payload是个转换结构体
payload.uevent_fd = uevent_fd;
payload.usb = (android::hardware::usb::V1_0::implementation::Usb *)param;
fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
ev.events = EPOLLIN;
//绑定事件处理函数uevent_event
ev.data.ptr = (void *)uevent_event;
epoll_fd = epoll_create(64);
//循环等待UEVENT事件
while (!destroyThread) {
struct epoll_event events[64];
nevents = epoll_wait(epoll_fd, events, 64, -1);
for (int n = 0; n < nevents; ++n) {
if (events[n].data.ptr)
(*(void (*)(int, struct data *payload))events[n].data.ptr)
(events[n].events, &payload);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
hardware\interfaces\usb\1.0\default\Usb.cpp
处理来自内核的USB驱动事件
static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
char msg[UEVENT_MSG_LEN + 2];
char *cp;
int n;
n = uevent_kernel_multicast_recv(payload->uevent_fd, msg, UEVENT_MSG_LEN);
if (n <= 0)
return;
if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
return;
msg[n] = '\0';
msg[n + 1] = '\0';
cp = msg;
//如果有数据,继续处理
while (*cp) {
if (!strcmp(cp, "SUBSYSTEM=dual_role_usb")) {
ALOGE("uevent received %s", cp);
if (payload->usb->mCallback != NULL) {
hidl_vec
Status status = getPortStatusHelper(currentPortStatus);
//执行上层的回调
Return
payload->usb->mCallback->notifyPortStatusChange(currentPortStatus, status);
}
break;
}
/* advance to after the next \0 */
while (*cp++);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
现在我们来看看刚刚的遇到的mHALCallback
private static class HALCallback extends IUsbCallback.Stub {
public IndentingPrintWriter pw;
public UsbPortManager portManager;
.......
public void notifyPortStatusChange(ArrayList
ArrayList
//处理USB端口状态
for (PortStatus current : currentPortStatus) {
RawPortInfo temp = new RawPortInfo(current.portName,
current.supportedModes, current.currentMode,
current.canChangeMode, current.currentPowerRole,
current.canChangePowerRole,
current.currentDataRole, current.canChangeDataRole);
newPortInfo.add(temp);
logAndPrint(Log.INFO, pw, "ClientCallback: " + current.portName);
}
//转给UsbPortManager的Handler来处理
Message message = portManager.mHandler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
message.what = MSG_UPDATE_PORTS;
message.setData(bundle);
portManager.mHandler.sendMessage(message);
return;
}
......
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
private final Handler mHandler = new Handler(FgThread.get().getLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_PORTS: {
Bundle b = msg.getData();
ArrayList
synchronized (mLock) {
updatePortsLocked(null, PortInfo);
}
break;
}
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
private void updatePortsLocked(IndentingPrintWriter pw, ArrayList
//处理USB设备的插入删除移除
// Process the updates.
// Once finished, the list of ports will only contain ports in DISPOSITION_READY.
for (int i = mPorts.size(); i-- > 0; ) {
final PortInfo portInfo = mPorts.valueAt(i);
switch (portInfo.mDisposition) {
case PortInfo.DISPOSITION_ADDED:
handlePortAddedLocked(portInfo, pw);
portInfo.mDisposition = PortInfo.DISPOSITION_READY;
break;
case PortInfo.DISPOSITION_CHANGED:
handlePortChangedLocked(portInfo, pw);
portInfo.mDisposition = PortInfo.DISPOSITION_READY;
break;
case PortInfo.DISPOSITION_REMOVED:
mPorts.removeAt(i);
portInfo.mUsbPortStatus = null; // must do this early
handlePortRemovedLocked(portInfo, pw);
break;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
终于发送了一个广播将端口状态信息发送出去
private void sendPortChangedBroadcastLocked(PortInfo portInfo) {
final Intent intent = new Intent(UsbManager.ACTION_USB_PORT_CHANGED);
intent.addFlags(
Intent.FLAG_RECEIVER_FOREGROUND |
Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
intent.putExtra(UsbManager.EXTRA_PORT, portInfo.mUsbPort);
intent.putExtra(UsbManager.EXTRA_PORT_STATUS, portInfo.mUsbPortStatus);
// Guard against possible reentrance by posting the broadcast from the handler
// instead of from within the critical section.
mHandler.post(new Runnable() {
@Override
public void run() {
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
4. USB设备事务处理
frameworks\base\services\usb\java\com\android\server\usb\UsbDeviceManager.java
public UsbDeviceManager(Context context, UsbAlsaManager alsaManager,
UsbSettingsManager settingsManager) {
//USB配件模式检查
mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
if (nativeIsStartRequested()) {
if (DEBUG) Slog.d(TAG, "accessory attached at boot");
startAccessoryMode();
}
mHandler = new UsbHandler(FgThread.get().getLooper());
//开发人员adb调试是否打开
boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));
if (secureAdbEnabled && !dataEncrypted) {
mDebuggingManager = new UsbDebuggingManager(context); //usb调试管理
}
//对应上面发送的广播
mContext.registerReceiver(mHostReceiver,
new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
mContext.registerReceiver(mChargingReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
frameworks\base\services\usb\java\com\android\server\usb\UsbDeviceManager.java
监听消息转发处理事务
//adb调试模式开关监听
private class AdbSettingsObserver extends ContentObserver {
public AdbSettingsObserver() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
boolean enable = (Settings.Global.getInt(mContentResolver,
Settings.Global.ADB_ENABLED, 0) > 0);
mHandler.sendMessage(MSG_ENABLE_ADB, enable);
}
}
//监听来自内核的Uevent
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();
}
}
};
//接收USB状态变化
private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT);
UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS);
mHandler.updateHostState(port, status); //交给内部Handler处理,不再深入了
}
};
//接受USB拔插状态
private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharging = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
mHandler.sendMessage(MSG_UPDATE_CHARGING_STATE, usbCharging);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
最后在UsbHandler里处理包括MIDI,主机/配件模式,音频,adb调试,状态Notification,设备的增减状态变化等事务。具体就不再细究了,以后遇到再分析。
————————————————
版权声明:本文为CSDN博主「SherlockCharlie」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013928208/article/details/84586238