Android8.0 USB系统框架

USB(通用串行总线)主机模式向外设进行供电,使 Android 设备能够驱动 USB 总线,并且可以使用各种 USB 外设(包括音频接口,存储,MIDI),USB 和蓝牙低功耗连接都可以用于传输 MIDI 协议。USB配件模式,受外设供电驱动,包括数据传输,充电。USB开发模式,应用调试,唯一可见的外设功能是 Android fastboot 或 Android 调试桥 (adb)。fastboot 和 adb 协议所在层高于 USB 批量数据传输模式所在层。
Android8.0 USB系统框架_第1张图片
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();//系统启动完成
            }
        }
        ......
    }

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);
    }

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();
        }
    }

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;
    }

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;
    }

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;
    }

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);
        }
    }

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);
}

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;
}

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;
}

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;
    }

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;
}

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);
    }

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) {
               ......
            }
        }
    }

hardware\interfaces\usb\1.0\default\Usb.cpp

Return<void> Usb::setCallback(const sp<IUsbCallback>& callback) {

    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();
}

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);
        }
    }
}

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<PortStatus> currentPortStatus;
                Status status = getPortStatusHelper(currentPortStatus);
                //执行上层的回调
                Return<void> ret =
                    payload->usb->mCallback->notifyPortStatusChange(currentPortStatus, status);
            }
            break;
        }
        /* advance to after the next \0 */
        while (*cp++);
    }
}

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<PortStatus> currentPortStatus, int retval) {
            ArrayList<RawPortInfo> newPortInfo = new ArrayList<RawPortInfo>();
            //处理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;
        }
        ......
    };

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<RawPortInfo> PortInfo = b.getParcelableArrayList(PORT_INFO);
                    synchronized (mLock) {
                        updatePortsLocked(null, PortInfo);
                    }
                    break;
                }
            }
        }
    };

frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java

private void updatePortsLocked(IndentingPrintWriter pw, ArrayList<RawPortInfo> newPortInfo) {
        //处理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;
            }
        }
    }

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);
            }
        });
    }

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));
    }

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);
        }
    };

最后在UsbHandler里处理包括MIDI,主机/配件模式,音频,adb调试,状态Notification,设备的增减状态变化等事务。具体就不再细究了,以后遇到再分析。

你可能感兴趣的:(Android)