日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android8.0 USB系统框架

發(fā)布時(shí)間:2023/12/15 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android8.0 USB系统框架 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

USB(通用串行總線)主機(jī)模式向外設(shè)進(jìn)行供電,使 Android 設(shè)備能夠驅(qū)動(dòng) USB 總線,并且可以使用各種 USB 外設(shè)(包括音頻接口,存儲(chǔ),MIDI),USB 和藍(lán)牙低功耗連接都可以用于傳輸 MIDI 協(xié)議。USB配件模式,受外設(shè)供電驅(qū)動(dòng),包括數(shù)據(jù)傳輸,充電。USB開發(fā)模式,應(yīng)用調(diào)試,唯一可見的外設(shè)功能是 Android fastboot 或 Android 調(diào)試橋 (adb)。fastboot 和 adb 協(xié)議所在層高于 USB 批量數(shù)據(jù)傳輸模式所在層。

Android 平臺(tái)支持使用即插即用的 USB 攝像頭(例如網(wǎng)絡(luò)攝像頭),但前提是這些攝像頭采用標(biāo)準(zhǔn)的 Android Camera2 API 和攝像頭 HIDL 接口,全新的 USB 攝像頭 HAL 進(jìn)程是外接攝像頭提供程序的一部分,該提供程序會(huì)監(jiān)聽 USB 設(shè)備可用性,并相應(yīng)地枚舉外接攝像頭設(shè)備。該進(jìn)程具有與內(nèi)置攝像頭 HAL 進(jìn)程類似的權(quán)限和 SE 策略。直接與 USB 設(shè)備通信的第三方網(wǎng)絡(luò)攝像頭應(yīng)用訪問 UVC 設(shè)備時(shí)所需的攝像頭權(quán)限與所有常規(guī)攝像頭應(yīng)用所需的權(quán)限相同。

1. Usb服務(wù)啟動(dòng)

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

public static class Lifecycle extends SystemService {private UsbService mUsbService;......@Overridepublic void onStart() { mUsbService = new UsbService(getContext());} //USB服務(wù)初始化@Overridepublic void onBootPhase(int phase) {if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {mUsbService.systemReady(); //系統(tǒng)準(zhǔn)備就緒} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {mUsbService.bootCompleted();//系統(tǒng)啟動(dòng)完成}}......}

frameworks\base\services\usb\java\com\android\server\usb\UsbService.java
初始化USB服務(wù)

public UsbService(Context context) {mContext = context;//多用戶管理mUserManager = context.getSystemService(UserManager.class);//用戶管理設(shè)置mSettingsManager = new UsbSettingsManager(context);//高級(jí)音頻管理mAlsaManager = new UsbAlsaManager(context);//包管理final PackageManager pm = mContext.getPackageManager();//USB主機(jī)模式if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {mHostManager = new UsbHostManager(context, mAlsaManager, mSettingsManager);}//USB設(shè)備管理if (new File("/sys/class/android_usb").exists()) {mDeviceManager = new UsbDeviceManager(context, mAlsaManager, mSettingsManager);}//USB端口管理if (mHostManager != null || mDeviceManager != null) {mPortManager = new UsbPortManager(context);}//切換為系統(tǒng)用戶onSwitchUser(UserHandle.USER_SYSTEM);//注冊(cè)設(shè)備代理管理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

//系統(tǒng)音頻服務(wù) public void systemReady() {mAudioService = IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE));mAlsaObserver.startWatching(); //開始高級(jí)音頻監(jiān)聽......}//創(chuàng)建USB設(shè)備Notification public void systemReady() {mNotificationManager = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);// Ensure that the notification channels are set upif (isTv()) {// TV-specific notification channelmNotificationManager.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);}//啟動(dòng)USB主機(jī)模式總線 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設(shè)備端口轉(zhuǎn)狀態(tài) public void systemReady() {if (mProxy != null) {try {mProxy.queryPortStatus();} catch (RemoteException e) {.......}}mSystemReady = true;}

2. USB設(shè)備打開

frameworks\base\core\java\android\hardware\usb\UsbManager.java

public UsbDeviceConnection openDevice(UsbDevice device) {try {String deviceName = device.getDeviceName();//打開USB設(shè)備,返回文件描述符FDParcelFileDescriptor pfd = mService.openDevice(deviceName);if (pfd != null) {//創(chuàng)建Socket連接通道,用于數(shù)據(jù)指令傳輸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) */@Overridepublic ParcelFileDescriptor openDevice(String deviceName) {ParcelFileDescriptor fd = null;if (mHostManager != null) {synchronized (mLock) {if (deviceName != null) {int userIdInt = UserHandle.getCallingUserId();boolean isCurrentUser = isCallerInCurrentUserProfileGroupLocked();//以主機(jī)模式打開制定USBif (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設(shè)備列表中查找一個(gè)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);//調(diào)用系統(tǒng)提供的USB設(shè)備打開函數(shù)struct usb_device* device = usb_device_open(deviceNameStr);env->ReleaseStringUTFChars(deviceName, deviceNameStr);//獲得USB設(shè)備的文件描述符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); //打開設(shè)備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);}//新建一個(gè)USB設(shè)備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)); //分配內(nèi)存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)); //讀取設(shè)備描述符長(zhǎng)度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 fdsdevice->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
調(diào)用JNI層打開指定的USB設(shè)備

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 copyfd = 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設(shè)備檢測(cè)

frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
設(shè)備端口管理

public UsbPortManager(Context context) {mContext = context;try {//HIDL層的Serviceboolean ret = IServiceManager.getService().registerForNotifications("android.hardware.usb@1.0::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服務(wù)mProxy = IUsb.getService(); mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);//設(shè)置回調(diào),一會(huì)兒再回頭看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);//創(chuàng)建線程,運(yùn)行workif (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機(jī)制,多路IO阻塞復(fù)用

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); //創(chuàng)建套接//payload是個(gè)轉(zhuǎn)換結(jié)構(gòu)體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;//綁定事件處理函數(shù)uevent_eventev.data.ptr = (void *)uevent_event;epoll_fd = epoll_create(64);//循環(huán)等待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
處理來自內(nèi)核的USB驅(qū)動(dòng)事件

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;//如果有數(shù)據(jù),繼續(xù)處理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);//執(zhí)行上層的回調(diào)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
現(xiàn)在我們來看看剛剛的遇到的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端口狀態(tài)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);}//轉(zhuǎn)給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()) {@Overridepublic 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設(shè)備的插入刪除移除// 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 earlyhandlePortRemovedLocked(portInfo, pw);break;}}}

frameworks\base\services\usb\java\com\android\server\usb\UsbPortManager.java
終于發(fā)送了一個(gè)廣播將端口狀態(tài)信息發(fā)送出去

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() {@Overridepublic void run() {mContext.sendBroadcastAsUser(intent, UserHandle.ALL);}});}

4. USB設(shè)備事務(wù)處理

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());//開發(fā)人員adb調(diào)試是否打開boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));if (secureAdbEnabled && !dataEncrypted) {mDebuggingManager = new UsbDebuggingManager(context); //usb調(diào)試管理}//對(duì)應(yīng)上面發(fā)送的廣播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
監(jiān)聽消息轉(zhuǎn)發(fā)處理事務(wù)

//adb調(diào)試模式開關(guān)監(jiān)聽private class AdbSettingsObserver extends ContentObserver {public AdbSettingsObserver() {super(null);}@Overridepublic void onChange(boolean selfChange) {boolean enable = (Settings.Global.getInt(mContentResolver,Settings.Global.ADB_ENABLED, 0) > 0);mHandler.sendMessage(MSG_ENABLE_ADB, enable);}}//監(jiān)聽來自內(nèi)核的Ueventprivate final UEventObserver mUEventObserver = new UEventObserver() {@Overridepublic 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狀態(tài)變化private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() {@Overridepublic 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); //交給內(nèi)部Handler處理,不再深入了}};//接受USB拔插狀態(tài)private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() {@Overridepublic 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,主機(jī)/配件模式,音頻,adb調(diào)試,狀態(tài)Notification,設(shè)備的增減狀態(tài)變化等事務(wù)。具體就不再細(xì)究了,以后遇到再分析。

總結(jié)

以上是生活随笔為你收集整理的Android8.0 USB系统框架的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。