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("android.hardware.usb@1.0::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<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();
}
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<PortStatus> currentPortStatus;
                Status status = getPortStatusHelper(currentPortStatus);
                //执行上层的回调
                Return<void> ret =
                    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<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;
        }
        ......
    };
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<RawPortInfo> PortInfo = b.getParcelableArrayList(PORT_INFO);
                    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<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;
            }
        }
    }
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

Android8.0 USB系统框架相关推荐

  1. Android8.0 USB系统框架

    USB(通用串行总线)主机模式向外设进行供电,使 Android 设备能够驱动 USB 总线,并且可以使用各种 USB 外设(包括音频接口,存储,MIDI),USB 和蓝牙低功耗连接都可以用于传输 M ...

  2. Android8.0 蓝牙系统

    Android 提供支持经典蓝牙和蓝牙低功耗的默认蓝牙堆栈.借助蓝牙,Android 设备可以创建个人区域网络,以便通过附近的蓝牙设备发送和接收数据,在 Android 4.3 及更高版本中,Andr ...

  3. Android8.0以上系统ROOT时,Magisk框架替代SpuerSU

    9月末,我负责的一个手机评测业务,有ROOT手机的刚需. 手机是刚上市华为Nova3,Android版本8.1. 按照"祖传"刷机手法,使用SuperSU来ROOT手机一直没有成功 ...

  4. Android8.0 Audio系统之AudioFlinger

    继上一篇AudioTrack的分析,本篇我们来看AudioFlinger,AF主要承担音频混合输出,是Audio系统的核心,从AudioTrack来的数据最终都会在这里处理,并被写入到Audio的HA ...

  5. Android8.0 Media系统(一)

    以上四篇对Audio系统的简要分析,由于Audio涉及的范围比较广,以后分析其他子系统时在做详细分析.我们继续Media系统的征程,Media系统仍然是一个庞大的系统,以MediaPlayer为例,贯 ...

  6. Android8.0 Audio系统之AudioPolicy

    上一篇我们跟踪分析了AudioFlinger,它是Audio系统的核心,但是AudioFlinger却不能脱离AudioPolicy工作.AudioPolicy模块承载着音频切换,音轨路由的重要工作, ...

  7. android8.0调用系统浏览器,ie浏览器在线使用,ie浏览器8.0手机安卓版-

    Ie浏览器是微软开发的浏览器,这种浏览器是目前最常见的兼容性最强的浏览器. Ie浏览器也是世界上最早期出现的网络浏览器,主要是用于查资料和上网使用的. 过去的年代里没有太多的播放器和图片查看软件,人们 ...

  8. android8.1.0官方下载,官方Xposed框架For Android8.0/8.1(Oreo)发布v90-beta3版本

    去年12月份的时候记得跟大家提到过Android8.0(Oreo)版本的Xposed框架的作者也带来的新消息,说是代码部分与已经完成了大约95%,但是剩余的5%都是比较难的,而且由于上面那个aosp的 ...

  9. 华为android贡献度,Android8.0系统占比大幅提升,华为、荣耀、小米成为主要贡献...

    原标题:Android8.0系统占比大幅提升,华为.荣耀.小米成为主要贡献 安卓推出Android8.0系统至今已半年有余,如今Android8.1稳定版.Android9.0开发者预览版也发布了,但 ...

最新文章

  1. Scaleform GFx
  2. matlab 编辑器设置,编辑器设置,包括语言、备份和显示设置
  3. Nginx之升级和构建后添加新的模块
  4. pix4d无人机影像处理_让无人机创造更大价值?你还差一个Pix4D培训会!
  5. diybox路由器设置教程_家庭无线路由器怎么设置 家庭无线路由器设置教程【详细方法】...
  6. mysql批量导入txt数据_MySQL批量导入Excel、txt数据
  7. 等待线程3秒返回结果_Excel小白超级讨厌的计算,原来只用3秒就能出结果!
  8. matlab直接终止程序,怎么终止matlab程序
  9. 好用的代码加密软件,编程,编译数据安全
  10. 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码
  11. Java获取汉字对应的拼音(全拼或首字母)
  12. [DDC]Deep Domain Confusion: Maximizing for Domain Invariance
  13. 虚拟桌面和云桌面办公系统
  14. ubuntu安装中文环境 zh_CN.GB2312 zh_CN.GBK
  15. LinkedList面试要点总结
  16. java doc转图片_使用Java实现word文档转图片 在线预览
  17. 设计模式 - 创建型模式_工厂方法模式
  18. matlab tic tac toe,详解Tic-Tac-Toe人工智能实现
  19. 如何将数据指标异常监控和归因分析自动化
  20. 30.set-UID set-gid stic_bit

热门文章

  1. 使用kms导致Windows defender安全中心空白还原方法(windows defender被关闭仍然显示病毒)
  2. 编程中的心流模式flow
  3. Homekit智能家居DIY一智能插座
  4. 一基一石,代餐的成长与内卷
  5. 逍遥模拟器的安装和使用
  6. 深度揭秘Xshell后门事件:入侵感染供应链软件的大规模定向攻击
  7. Linux 多个留后门姿势
  8. android利用EpMedia给录像添加时间水印
  9. php 抓取淘宝商品详情
  10. 计算机专业助我成长400字作文,关于助我成长的作文400字(精选20篇)