diff --git a/interfaces/innerkits/native/include/iusb_srv.h b/interfaces/innerkits/native/include/iusb_srv.h index d8b5782a27ccd507300c0639489ab99afd1a1de9..b7310970c4cfdb93150a8ee32ec357e22a3ef208 100644 --- a/interfaces/innerkits/native/include/iusb_srv.h +++ b/interfaces/innerkits/native/include/iusb_srv.h @@ -21,6 +21,7 @@ #include "usb_device.h" #include "usb_port.h" #include "v1_0/usb_types.h" +#include "usb_interface_type.h" namespace OHOS { namespace USB { @@ -67,7 +68,9 @@ public: sptr &ashmem) = 0; virtual int32_t BulkCancel(const HDI::Usb::V1_0::UsbDev &devInfo, const HDI::Usb::V1_0::UsbPipe &pipe) = 0; virtual int32_t AddRight(const std::string &bundleName, const std::string &deviceName) = 0; - + virtual int32_t ManageGlobalInterface(bool disable) = 0; + virtual int32_t ManageDevice(int32_t vendorId, int32_t productId, bool disable) = 0; + virtual int32_t ManageInterfaceType(InterfaceType interfaceType, bool disable) = 0; public: DECLARE_INTERFACE_DESCRIPTOR(u"ohos.usb.IUsbSrv"); }; diff --git a/interfaces/innerkits/native/include/usb_interface_type.h b/interfaces/innerkits/native/include/usb_interface_type.h new file mode 100644 index 0000000000000000000000000000000000000000..4a94cc7efa86294bce775be94e37464cf652ac8d --- /dev/null +++ b/interfaces/innerkits/native/include/usb_interface_type.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef USB_INTERFACE_TYPE_H +#define USB_INTERFACE_TYPE_H + +namespace OHOS { +namespace USB { +enum InterfaceType { + TYPE_STORAGE, + TYPE_AUDIO, + TYPE_HID, + TYPE_PHYSICAL, + TYPE_IMAGE, + TYPE_PRINTER, +}; + +struct UsbDeviceId { + int32_t productId; + int32_t vendorId; +}; + +} // namespace USB +} // namespace OHOS +#endif // USB_INTERFACE_TYPE_H diff --git a/interfaces/innerkits/native/include/usb_srv_client.h b/interfaces/innerkits/native/include/usb_srv_client.h index eede5ee9f3d6c37b0fc19afc32491377595d381c..b72c0711f263b043dfed3800fe616f5d5821a9d9 100644 --- a/interfaces/innerkits/native/include/usb_srv_client.h +++ b/interfaces/innerkits/native/include/usb_srv_client.h @@ -28,6 +28,7 @@ #include "usb_device_pipe.h" #include "usb_port.h" #include "usb_request.h" +#include "usb_interface_type.h" namespace OHOS { namespace USB { @@ -84,7 +85,9 @@ public: int32_t BulkWrite(USBDevicePipe &pip, const USBEndpoint &endpoint, sptr &ashmem); int32_t BulkCancel(USBDevicePipe &pip, const USBEndpoint &endpoint); int32_t AddRight(const std::string &bundleName, const std::string &deviceName); - + int32_t ManageGlobalInterface(bool disable); + int32_t ManageDevice(int32_t vendorId, int32_t productId, bool disable); + int32_t ManageInterfaceType(InterfaceType interfaceType, bool disable); private: class UsbSrvDeathRecipient : public IRemoteObject::DeathRecipient { public: diff --git a/interfaces/innerkits/native/src/usb_srv_client.cpp b/interfaces/innerkits/native/src/usb_srv_client.cpp index 5568075f961de081dde17d0179180dcf65fb683a..5e36978cf923df45e157f2ef87bb72e4b3286113 100644 --- a/interfaces/innerkits/native/src/usb_srv_client.cpp +++ b/interfaces/innerkits/native/src/usb_srv_client.cpp @@ -422,5 +422,35 @@ int32_t UsbSrvClient::AddRight(const std::string &bundleName, const std::string } return ret; } + +int32_t UsbSrvClient::ManageGlobalInterface(bool disable) +{ + RETURN_IF_WITH_RET(proxy_ == nullptr, UEC_INTERFACE_NO_INIT); + int32_t ret = proxy_->ManageGlobalInterface(disable); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_INNERKIT, "failed width ret = %{public}d !", ret); + } + return ret; +} + +int32_t UsbSrvClient::ManageDevice(int32_t vendorId, int32_t productId, bool disable) +{ + RETURN_IF_WITH_RET(proxy_ == nullptr, UEC_INTERFACE_NO_INIT); + int32_t ret = proxy_->ManageDevice(vendorId, productId, disable); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_INNERKIT, "failed width ret = %{public}d !", ret); + } + return ret; +} + +int32_t UsbSrvClient::ManageInterfaceType(InterfaceType interfaceType, bool disable) +{ + RETURN_IF_WITH_RET(proxy_ == nullptr, UEC_INTERFACE_NO_INIT); + int32_t ret = proxy_->ManageInterfaceType(interfaceType, disable); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_INNERKIT, "failed width ret = %{public}d !", ret); + } + return ret; +} } // namespace USB } // namespace OHOS diff --git a/services/native/include/usb_service.h b/services/native/include/usb_service.h index 5ec1e180f9dbfe2d4bef2ec3fcfd513378cd9712..be6c93dd89630505e85d66d8a0703a8b22af39ac 100644 --- a/services/native/include/usb_service.h +++ b/services/native/include/usb_service.h @@ -18,10 +18,15 @@ #include #include +#include +#include +#include +#include #include "delayed_sp_singleton.h" #include "iremote_object.h" #include "iusb_srv.h" +#include "usb_interface_type.h" #include "system_ability.h" #include "system_ability_status_change_stub.h" #include "timer.h" @@ -116,7 +121,9 @@ public: int32_t BulkCancel(const HDI::Usb::V1_0::UsbDev &devInfo, const HDI::Usb::V1_0::UsbPipe &pipe) override; int32_t AddRight(const std::string &bundleName, const std::string &deviceName) override; void UnLoadSelf(UnLoadSaType type); - + int32_t ManageGlobalInterface(bool disable) override; + int32_t ManageDevice(int32_t vendorId, int32_t productId, bool disable) override; + int32_t ManageInterfaceType(InterfaceType interfaceType, bool disable) override; private: class SystemAbilityStatusChangeListener : public SystemAbilityStatusChangeStub { public: @@ -144,10 +151,22 @@ private: std::string GetDevStringValFromIdx(uint8_t busNum, uint8_t devAddr, uint8_t idx); int32_t InitUsbRight(); void DumpHelp(int32_t fd); + int32_t PreManageInterface(); + bool IsEdmEnabled(); + int32_t ExecuteManageDevicePolicy(std::vector &whiteList); + int32_t GetEdmPolicy(bool &IsGlobalDisabled, std::unordered_map &typeDisableMap, + std::vector &trustUsbDeviceId); + int32_t GetUsbPolicy(bool &IsGlobalDisabled, std::unordered_map &typeDisableMap, + std::vector &trustUsbDeviceId); + void ExecuteStrategy(UsbDevice *devInfo); + int32_t GetEdmTypePolicy(sptr remote, std::unordered_map &typeDisableMap); + int32_t GetEdmGlobalPolicy(sptr remote, bool &IsGlobalDisabled); + int32_t GetEdmWhiteListPolicy(sptr remote, std::vector &trustUsbDeviceId); + int32_t ManageInterface(const HDI::Usb::V1_0::UsbDev &dev, uint8_t interfaceId, bool disable); bool ready_ = false; int32_t commEventRetryTimes_ = 0; std::mutex mutex_; - std::shared_ptr usbHostManger_; + std::shared_ptr usbHostManager_; std::shared_ptr usbRightManager_; std::shared_ptr usbPortManager_; std::shared_ptr usbDeviceManager_; diff --git a/services/native/src/usb_service.cpp b/services/native/src/usb_service.cpp index 6ec6de3423ba6b828133c488f843ead0e82b772c..1b44a5d297267bc798e4222ac4c31331f08d4824 100644 --- a/services/native/src/usb_service.cpp +++ b/services/native/src/usb_service.cpp @@ -21,7 +21,9 @@ #include #include #include +#include +#include "parameters.h" #include "bundle_mgr_interface.h" #include "bundle_mgr_proxy.h" #include "common_timer_errors.h" @@ -57,6 +59,31 @@ constexpr int32_t BIT_HIGH_4 = 0xF0; constexpr int32_t BIT_LOW_4 = 0x0F; constexpr int32_t SERVICE_STARTUP_MAX_TIME = 30; constexpr uint32_t UNLOAD_SA_TIMER_INTERVAL = 30 * 1000; +constexpr uint32_t MANAGE_INTERFACE_INTERVAL = 100; +constexpr uint32_t EDM_SA_MAX_TIME_OUT = 5000; +constexpr uint32_t EDM_SYSTEM_ABILITY_ID = 1601; +const std::u16string DESCRIPTOR = u"ohos.edm.IEnterpriseDeviceMgr"; +constexpr uint32_t WITHOUT_USERID = 0; +constexpr uint32_t WITHOUT_ADMIN = 1; +constexpr uint32_t EMD_MASK_CODE = 20; +constexpr uint32_t DISABLE_USB = 1043; +constexpr uint32_t ALLOWED_USB_DEVICES = 1044; +constexpr uint32_t USB_STORAGE_DEVICE_ACCESS_POLICY = 1026; +constexpr int32_t WHITELIST_POLICY_MAX_DEVICES = 1000; +constexpr uint32_t EDM_SA_TIME_OUT_CODE = 9200007; +constexpr int32_t BASECLASS_INDEX = 0; +constexpr int32_t SUBCLASS_INDEX = 1; +constexpr int32_t PROTOCAL_INDEX = 2; +constexpr int32_t RANDOM_VALUE_INDICATE = -1; + +std::unordered_map> typeMap = { + {InterfaceType::TYPE_STORAGE, {8, -1, -1}}, + {InterfaceType::TYPE_AUDIO, {1, -1, -1}}, + {InterfaceType::TYPE_HID, {3, -1, -1}}, + {InterfaceType::TYPE_PHYSICAL, {5, -1, -1}}, + {InterfaceType::TYPE_IMAGE, {6, 1, 1}}, + {InterfaceType::TYPE_PRINTER, {7, -1, -1}} +}; } // namespace auto g_serviceInstance = DelayedSpSingleton::GetInstance(); @@ -65,7 +92,7 @@ const bool G_REGISTER_RESULT = UsbService::UsbService() : SystemAbility(USB_SYSTEM_ABILITY_ID, true) { - usbHostManger_ = std::make_shared(nullptr); + usbHostManager_ = std::make_shared(nullptr); usbRightManager_ = std::make_shared(); usbPortManager_ = std::make_shared(); usbDeviceManager_ = std::make_shared(); @@ -206,6 +233,7 @@ bool UsbService::Init() bool UsbService::InitUsbd() { + usbd_ = IUsbInterface::Get(); usbdSubscriber_ = new (std::nothrow) UsbServiceSubscriber(); if (usbdSubscriber_ == nullptr) { USB_HILOGE(MODULE_USB_SERVICE, "Init failed\n"); @@ -373,12 +401,12 @@ int32_t UsbService::GetDevices(std::vector &deviceList) { std::map devices; - if (usbHostManger_ == nullptr) { - USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManger_"); + if (usbHostManager_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManager_"); return UEC_SERVICE_INVALID_VALUE; } - usbHostManger_->GetDevices(devices); + usbHostManager_->GetDevices(devices); USB_HILOGI(MODULE_USB_SERVICE, "list size %{public}zu", devices.size()); for (auto it = devices.begin(); it != devices.end(); ++it) { if (!(usbRightManager_->IsSystemHap())) { @@ -880,6 +908,228 @@ int32_t UsbService::GetDeviceInfo(uint8_t busNum, uint8_t devAddr, UsbDevice &de return UEC_OK; } +int32_t UsbService::GetEdmGlobalPolicy(sptr remote, bool &IsGlobalDisabled) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteInterfaceToken(DESCRIPTOR); + data.WriteInt32(WITHOUT_USERID); + data.WriteInt32(WITHOUT_ADMIN); + + uint32_t funcCode = (1 << EMD_MASK_CODE) | DISABLE_USB; + int32_t ErrCode = remote->SendRequest(funcCode, data, reply, option); + int32_t ret = ERR_INVALID_VALUE; + bool isSuccess = reply.ReadInt32(ret) && (ret == UEC_OK); + if (!isSuccess) { + USB_HILOGE(MODULE_USB_SERVICE, "GetGlobalPolicy failed. ErrCode = %{public}d, ret = %{public}d", + ErrCode, ret); + return UEC_SERVICE_EDM_SEND_REQUEST_FAILED; + } + + reply.ReadBool(IsGlobalDisabled); + return UEC_OK; +} + +int32_t UsbService::GetEdmTypePolicy(sptr remote, + std::unordered_map &typeDisableMap) +{ + bool IsStorageDisabled = false; + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteInterfaceToken(DESCRIPTOR); + data.WriteInt32(WITHOUT_USERID); + data.WriteInt32(WITHOUT_ADMIN); + + uint32_t funcCode = (1 << EMD_MASK_CODE) | USB_STORAGE_DEVICE_ACCESS_POLICY; + int32_t ErrCode = remote->SendRequest(funcCode, data, reply, option); + int32_t ret = ERR_INVALID_VALUE; + bool isSuccess = reply.ReadInt32(ret) && (ret == ERR_OK); + if (!isSuccess) { + USB_HILOGE(MODULE_USB_SERVICE, "GetEdmTypePolicy failed. ErrCode = %{public}d, ret = %{public}d", + ErrCode, ret); + return UEC_SERVICE_EDM_SEND_REQUEST_FAILED; + } + + reply.ReadBool(IsStorageDisabled); + typeDisableMap[InterfaceType::TYPE_STORAGE] = IsStorageDisabled; + return UEC_OK; +} + +int32_t UsbService::GetEdmWhiteListPolicy(sptr remote, std::vector &trustUsbDeviceIds) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteInterfaceToken(DESCRIPTOR); + data.WriteInt32(WITHOUT_USERID); + data.WriteInt32(WITHOUT_ADMIN); + + uint32_t funcCode = (1 << EMD_MASK_CODE) | ALLOWED_USB_DEVICES; + int32_t ErrCode = remote->SendRequest(funcCode, data, reply, option); + int32_t ret = ERR_INVALID_VALUE; + bool IsSuccess = reply.ReadInt32(ret) && (ret == ERR_OK); + if (!IsSuccess) { + USB_HILOGE(MODULE_USB_SERVICE, "GetEdmWhiteListPolicy failed. ErrCode = %{public}d, ret = %{public}d", + ErrCode, ret); + return UEC_SERVICE_EDM_SEND_REQUEST_FAILED; + } + + int32_t size = reply.ReadInt32(); + if (size > WHITELIST_POLICY_MAX_DEVICES) { + USB_HILOGE(MODULE_USB_SERVICE, "EdmWhiteList size=[%{public}d] is too large", size); + return UEC_SERVICE_EDM_DEVICE_SIZE_EXCEED; + } + USB_HILOGI(MODULE_USB_SERVICE, "GetEdmWhiteListPolicy return size:%{public}d", size); + for (int32_t i = 0; i < size; i++) { + UsbDeviceId usbDeviceId; + usbDeviceId.vendorId = reply.ReadInt32(); + usbDeviceId.productId = reply.ReadInt32(); + trustUsbDeviceIds.emplace_back(usbDeviceId); + } + return UEC_OK; +} + +int32_t UsbService::GetEdmPolicy(bool &IsGlobalDisabled, std::unordered_map &typeDisableMap, + std::vector &trustUsbDeviceIds) +{ + sptr sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (sm == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "fail to get SystemAbilityManager"); + return UEC_SERVICE_GET_SYSTEM_ABILITY_MANAGER_FAILED; + } + sptr remote = sm->CheckSystemAbility(EDM_SYSTEM_ABILITY_ID); + if (remote == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "Get Edm SystemAbility failed."); + return UEC_SERVICE_GET_EDM_SERVICE_FAILED; + } + + int32_t ret = GetEdmGlobalPolicy(remote, IsGlobalDisabled); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "GetEdmGlobalPolicy failed."); + return ret; + } + ret = GetEdmTypePolicy(remote, typeDisableMap); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "GetEdmTypePolicy failed."); + return ret; + } + ret = GetEdmWhiteListPolicy(remote, trustUsbDeviceIds); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "GetEdmWhiteListPolicy failed."); + return ret; + } + return UEC_OK; +} + +int32_t UsbService::GetUsbPolicy(bool &IsGlobalDisabled, std::unordered_map &typeDisableMap, + std::vector &trustUsbDeviceIds) +{ + auto startTime = std::chrono::steady_clock::now(); + while (true) { + int32_t ret = GetEdmPolicy(IsGlobalDisabled, typeDisableMap, trustUsbDeviceIds); + if (ret == UEC_OK) { + USB_HILOGI(MODULE_USB_SERVICE, "GetUsbPolicy succeed"); + break; + } else if (ret == EDM_SA_TIME_OUT_CODE) { + auto currentTime = std::chrono::steady_clock::now(); + auto elapsedTime = std::chrono::duration_cast(currentTime - startTime).count(); + if (elapsedTime >= EDM_SA_MAX_TIME_OUT) { + USB_HILOGE(MODULE_USB_SERVICE, "Time out, exit loop"); + return UEC_SERVICE_EDM_SA_TIME_OUT_FAILED; + } + std::this_thread::sleep_for(std::chrono::milliseconds(MANAGE_INTERFACE_INTERVAL)); + } else { + USB_HILOGE(MODULE_USB_SERVICE, "EDM sa failed"); + return UEC_SERVICE_PREPARE_EDM_SA_FAILED; + } + } + return UEC_OK; +} + +int32_t UsbService::ExecuteManageDevicePolicy(std::vector &whiteList) +{ + std::map devices; + usbHostManager_->GetDevices(devices); + int32_t ret; + USB_HILOGI(MODULE_USB_SERVICE, "list size %{public}zu", devices.size()); + for (auto it = devices.begin(); it != devices.end(); ++it) { + for (auto dev : whiteList) { + if (it->second->GetProductId() == dev.productId && it->second->GetVendorId() == dev.vendorId) { + ret = ManageDevice(it->second->GetVendorId(), it->second->GetProductId(), false); + } else { + ret = ManageDevice(it->second->GetVendorId(), it->second->GetProductId(), true); + } + std::this_thread::sleep_for(std::chrono::milliseconds(MANAGE_INTERFACE_INTERVAL)); + } + } + if (ret != UEC_OK) { + USB_HILOGI(MODULE_USB_SERVICE, "ManageDevice failed"); + return UEC_SERVICE_EXECUTE_POLICY_FAILED; + } + return UEC_OK; +} + +bool UsbService::IsEdmEnabled() +{ + std::string edmParaValue = OHOS::system::GetParameter("persist.edm.edm_enable", "false"); + USB_HILOGI(MODULE_USB_SERVICE, "edmParaValue is %{public}s", edmParaValue.c_str()); + return edmParaValue == "true"; +} + +void UsbService::ExecuteStrategy(UsbDevice *devInfo) +{ + if (PreManageInterface() != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "PreManageInterface failed"); + return; + } + if (!IsEdmEnabled()) { + USB_HILOGE(MODULE_USB_SERVICE, "edm is not activate, skip"); + return; + } + bool isGlobalDisabled = false; + std::unordered_map typeDisableMap{}; + std::vector trustUsbDeviceIds{}; + + int32_t ret = GetUsbPolicy(isGlobalDisabled, typeDisableMap, trustUsbDeviceIds); + if (ret == UEC_SERVICE_EDM_SA_TIME_OUT_FAILED || ret == UEC_SERVICE_PREPARE_EDM_SA_FAILED) { + USB_HILOGE(MODULE_USB_SERVICE, "EDM sa time out or prepare failed, ret = %{public}d", ret); + return; + } + + if (isGlobalDisabled) { + ret = ManageGlobalInterface(isGlobalDisabled); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "ManageGlobalInterface failed"); + } + return; + } + bool flag = false; + for (auto result : typeDisableMap) { + flag |= result.second; + if (result.second) { + ret = ManageInterfaceType(result.first, true); + } + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "ManageInterfaceType failed, type is %{public}d", (int32_t)result.first); + } + } + if (flag) { + USB_HILOGI(MODULE_USB_SERVICE, "Execute ManageInterfaceType finish"); + return; + } + if (trustUsbDeviceIds.empty()) { + USB_HILOGI(MODULE_USB_SERVICE, "trustUsbDeviceIds is empty, no devices disable"); + return; + } + ret = ExecuteManageDevicePolicy(trustUsbDeviceIds); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "ExecuteManageDevicePolicy failed"); + } + return; +} + bool UsbService::AddDevice(uint8_t busNum, uint8_t devAddr) { UsbDevice *devInfo = new (std::nothrow) UsbDevice(); @@ -910,12 +1160,13 @@ bool UsbService::AddDevice(uint8_t busNum, uint8_t devAddr) deviceVidPidMap_.insert(std::pair(name, uniqueName)); } - if (usbHostManger_ == nullptr) { - USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManger_"); + if (usbHostManager_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManager_"); return false; } - usbHostManger_->AddDevice(devInfo); + usbHostManager_->AddDevice(devInfo); + ExecuteStrategy(devInfo); return true; } @@ -927,8 +1178,8 @@ bool UsbService::DelDevice(uint8_t busNum, uint8_t devAddr) USB_HILOGE(MODULE_USBD, "Close device failed width ret = %{public}d", ret); } - if (usbHostManger_ == nullptr || usbRightManager_ == nullptr) { - USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManger_ or usbRightManager_"); + if (usbHostManager_ == nullptr || usbRightManager_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManager_ or usbRightManager_"); return false; } @@ -947,7 +1198,7 @@ bool UsbService::DelDevice(uint8_t busNum, uint8_t devAddr) } } - return usbHostManger_->DelDevice(busNum, devAddr); + return usbHostManager_->DelDevice(busNum, devAddr); } int32_t UsbService::InitUsbRight() @@ -1144,7 +1395,7 @@ int UsbService::Dump(int fd, const std::vector &args) } if (argList[0] == USB_HOST) { - usbHostManger_->Dump(fd, argList[1]); + usbHostManager_->Dump(fd, argList[1]); } else if (argList[0] == USB_DEVICE) { usbDeviceManager_->Dump(fd, argList); } else if (argList[0] == USB_PORT) { @@ -1189,8 +1440,8 @@ void UsbService::UnLoadSelf(UnLoadSaType type) return; } - if (usbHostManger_ == nullptr || usbDeviceManager_ == nullptr) { - USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManger_ or usbDeviceManager_"); + if (usbHostManager_ == nullptr || usbDeviceManager_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManager_ or usbDeviceManager_"); return; } @@ -1198,7 +1449,7 @@ void UsbService::UnLoadSelf(UnLoadSaType type) unloadSelfTimer_.Shutdown(); std::map devices; - usbHostManger_->GetDevices(devices); + usbHostManager_->GetDevices(devices); if (devices.size() != 0 || usbDeviceManager_->IsGadgetConnected()) { // delay unload conditions USB_HILOGW(MODULE_USB_SERVICE, "not need unload"); return; @@ -1220,5 +1471,144 @@ void UsbService::UsbdDeathRecipient::OnRemoteDied(const wptr &obj } pms->UnLoadSelf(UNLOAD_SA_IMMEDIATELY); } + +int32_t UsbService::PreManageInterface() +{ + usbd_ = IUsbInterface::Get(); + if (usbRightManager_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid usbRightManager_"); + return UEC_SERVICE_INVALID_VALUE; + } + if (!(usbRightManager_->IsSystemHap())) { + USB_HILOGW(MODULE_USB_SERVICE, "is not system app"); + return UEC_SERVICE_PERMISSION_DENIED_SYSAPI; + } + + if (usbHostManager_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid usbHostManager_"); + return UEC_SERVICE_INVALID_VALUE; + } + + if (usbd_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "usbd_ is nullptr"); + return UEC_SERVICE_INVALID_VALUE; + } + return UEC_OK; +} + +int32_t UsbService::ManageGlobalInterface(bool disable) +{ + if (PreManageInterface() != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "PreManageInterface failed"); + return UEC_SERVICE_PRE_MANAGE_INTERFACE_FAILED; + } + std::map devices; + usbHostManager_->GetDevices(devices); + USB_HILOGI(MODULE_USB_SERVICE, "list size %{public}zu", devices.size()); + for (auto it = devices.begin(); it != devices.end(); ++it) { + UsbDev dev = {it->second->GetBusNum(), it->second->GetDevAddr()}; + uint8_t configIndex = 0; + if (usbd_->GetConfig(dev, configIndex)) { + USB_HILOGW(MODULE_USB_SERVICE, "get device active config failed."); + continue; + } + USBConfig configs; + if (it->second->GetConfig(static_cast(configIndex) - 1, configs)) { + USB_HILOGW(MODULE_USB_SERVICE, "get device config info failed."); + continue; + } + + std::vector interfaces = configs.GetInterfaces(); + for (uint32_t i = 0; i < interfaces.size(); i++) { + ManageInterface(dev, interfaces[i].GetId(), disable); + std::this_thread::sleep_for(std::chrono::milliseconds(MANAGE_INTERFACE_INTERVAL)); + } + } + return UEC_OK; +} + +int32_t UsbService::ManageDevice(int32_t vendorId, int32_t productId, bool disable) +{ + if (PreManageInterface() != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "PreManageInterface failed"); + return UEC_SERVICE_PRE_MANAGE_INTERFACE_FAILED; + } + std::map devices; + usbHostManager_->GetDevices(devices); + USB_HILOGI(MODULE_USB_SERVICE, "list size %{public}zu", devices.size()); + for (auto it = devices.begin(); it != devices.end(); ++it) { + if (it->second->GetVendorId() == vendorId && it->second->GetProductId() == productId) { + UsbDev dev = {it->second->GetBusNum(), it->second->GetDevAddr()}; + uint8_t configIndex = 0; + if (usbd_->GetConfig(dev, configIndex)) { + USB_HILOGW(MODULE_USB_SERVICE, "get device active config failed."); + continue; + } + USBConfig configs; + if (it->second->GetConfig(static_cast(configIndex) - 1, configs)) { + USB_HILOGW(MODULE_USB_SERVICE, "get device config info failed."); + continue; + } + std::vector interfaces = configs.GetInterfaces(); + for (uint32_t i = 0; i < interfaces.size(); i++) { + ManageInterface(dev, interfaces[i].GetId(), disable); + std::this_thread::sleep_for(std::chrono::milliseconds(MANAGE_INTERFACE_INTERVAL)); + } + } + } + return UEC_OK; +} + +int32_t UsbService::ManageInterfaceType(InterfaceType interfaceType, bool disable) +{ + if (PreManageInterface() != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "PreManageInterface failed"); + return UEC_SERVICE_PRE_MANAGE_INTERFACE_FAILED; + } + auto iterInterface = typeMap.find(interfaceType); + if (iterInterface == typeMap.end()) { + USB_HILOGE(MODULE_USB_SERVICE, "UsbService::not find interface type"); + return UEC_SERVICE_INVALID_VALUE; + } + + std::map devices; + usbHostManager_->GetDevices(devices); + USB_HILOGI(MODULE_USB_SERVICE, "list size %{public}zu", devices.size()); + for (auto it = devices.begin(); it != devices.end(); ++it) { + UsbDev dev = {it->second->GetBusNum(), it->second->GetDevAddr()}; + uint8_t configIndex = 0; + if (usbd_->GetConfig(dev, configIndex)) { + USB_HILOGW(MODULE_USB_SERVICE, "get device active config failed."); + continue; + } + USBConfig configs; + if (it->second->GetConfig(static_cast(configIndex) - 1, configs)) { + USB_HILOGW(MODULE_USB_SERVICE, "get device config info failed."); + continue; + } + std::vector interfaces = configs.GetInterfaces(); + + for (uint32_t i = 0; i < interfaces.size(); i++) { + // 0 indicate base class, 1 indicate subclass, 2 indicate protocal. -1 indicate any value. + if (interfaces[i].GetClass() == iterInterface->second[BASECLASS_INDEX] && (interfaces[i].GetClass() == + iterInterface->second[SUBCLASS_INDEX] || iterInterface->second[SUBCLASS_INDEX] == + RANDOM_VALUE_INDICATE) && (interfaces[i].GetProtocol() == iterInterface->second[PROTOCAL_INDEX] || + iterInterface->second[PROTOCAL_INDEX] == RANDOM_VALUE_INDICATE)) { + ManageInterface(dev, interfaces[i].GetId(), disable); + std::this_thread::sleep_for(std::chrono::milliseconds(MANAGE_INTERFACE_INTERVAL)); + } + } + } + return UEC_OK; +} + +int32_t UsbService::ManageInterface(const HDI::Usb::V1_0::UsbDev &dev, uint8_t interfaceId, bool disable) +{ + if (usbd_ == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "usbd_ is nullptr"); + return UEC_SERVICE_INVALID_VALUE; + } + return usbd_->ManageInterface(dev, interfaceId, disable); +} } // namespace USB } // namespace OHOS diff --git a/services/usb_service.cfg b/services/usb_service.cfg index 245842e2821debefa901d7d7ffd6dca11e0d7845..f01c419897f8c409f901a65fa07e7f057585f80c 100644 --- a/services/usb_service.cfg +++ b/services/usb_service.cfg @@ -8,7 +8,8 @@ "gid" : ["usb", "shell"], "permission" : [ "ohos.permission.LISTEN_BUNDLE_CHANGE", - "ohos.permission.DISTRIBUTED_DATASYNC" + "ohos.permission.DISTRIBUTED_DATASYNC", + "ohos.permission.ENTERPRISE_MANAGE_USB" ], "apl" : "system_basic", "secon" : "u:r:usb_service:s0" diff --git a/services/zidl/include/usb_server_proxy.h b/services/zidl/include/usb_server_proxy.h index 92c4da5756b198da91b7dc3011be99ebbdd5aa37..29233649706a403ac77b2e355ed9f88f10a03066 100644 --- a/services/zidl/include/usb_server_proxy.h +++ b/services/zidl/include/usb_server_proxy.h @@ -22,6 +22,7 @@ #include "iusb_srv.h" #include "nocopyable.h" #include "usb_device.h" +#include "usb_interface_type.h" #include "usb_service_ipc_interface_code.h" namespace OHOS { @@ -75,7 +76,9 @@ public: sptr &ashmem) override; int32_t BulkCancel(const HDI::Usb::V1_0::UsbDev &dev, const HDI::Usb::V1_0::UsbPipe &pipe) override; int32_t AddRight(const std::string &bundleName, const std::string &deviceName) override; - + int32_t ManageGlobalInterface(bool disable) override; + int32_t ManageDevice(int32_t vendorId, int32_t productId, bool disable) override; + int32_t ManageInterfaceType(InterfaceType interfaceType, bool disable) override; private: static inline BrokerDelegator delegator_; int32_t ParseUsbPort(MessageParcel &reply, std::vector &result); diff --git a/services/zidl/include/usb_server_stub.h b/services/zidl/include/usb_server_stub.h index b76a177bad4142ccc2b0c14f3e84fe89a59e68ee..9a59aed5537ea4104ea5a99256cf3d8c9e3d8826 100644 --- a/services/zidl/include/usb_server_stub.h +++ b/services/zidl/include/usb_server_stub.h @@ -84,6 +84,10 @@ private: int32_t DoBulkWrite(MessageParcel &data, MessageParcel &reply, MessageOption &option); int32_t DoBulkCancel(MessageParcel &data, MessageParcel &reply, MessageOption &option); int32_t DoAddRight(MessageParcel &data, MessageParcel &reply, MessageOption &option); + + int32_t DoManageGlobalInterface(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DoManageDevice(MessageParcel &data, MessageParcel &reply, MessageOption &option); + int32_t DoManageInterfaceType(MessageParcel &data, MessageParcel &reply, MessageOption &option); }; } // namespace USB } // namespace OHOS diff --git a/services/zidl/include/usb_service_ipc_interface_code.h b/services/zidl/include/usb_service_ipc_interface_code.h index 31c8db8a7560e2a5c06cdce5f066c37204ca274d..1b77242f0e765f55627f17a63e560c66777f29ad 100644 --- a/services/zidl/include/usb_service_ipc_interface_code.h +++ b/services/zidl/include/usb_service_ipc_interface_code.h @@ -53,6 +53,9 @@ namespace USB { USB_FUN_REG_BULK_CALLBACK, USB_FUN_UNREG_BULK_CALLBACK, USB_FUN_ADD_RIGHT, + USB_FUN_DISABLE_GLOBAL_INTERFACE, + USB_FUN_DISABLE_DEVICE, + USB_FUN_DISABLE_INTERFACE_TYPE, }; } // namespace USB } // namespace OHOS diff --git a/services/zidl/src/usb_srv_proxy.cpp b/services/zidl/src/usb_srv_proxy.cpp index 74ebe85533289037966665948518dc6348089707..440ba5bb5db48fc6a7bf95299cd7175d93cebdf5 100644 --- a/services/zidl/src/usb_srv_proxy.cpp +++ b/services/zidl/src/usb_srv_proxy.cpp @@ -1098,5 +1098,75 @@ int32_t UsbServerProxy::AddRight(const std::string &bundleName, const std::strin } return ret; } + +int32_t UsbServerProxy::ManageGlobalInterface(bool disable) +{ + sptr remote = Remote(); + RETURN_IF_WITH_RET(remote == nullptr, UEC_INTERFACE_INVALID_VALUE); + + MessageParcel data; + if (!data.WriteInterfaceToken(UsbServerProxy::GetDescriptor())) { + USB_HILOGE(MODULE_USB_SERVICE, "write descriptor failed!"); + return ERR_ENOUGH_DATA; + } + WRITE_PARCEL_WITH_RET(data, Bool, disable, UEC_SERVICE_WRITE_PARCEL_ERROR); + + MessageOption option; + MessageParcel reply; + int32_t ret = remote->SendRequest(static_cast(UsbInterfaceCode::USB_FUN_DISABLE_GLOBAL_INTERFACE), + data, reply, option); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "SendRequest is failed, error code: %d", ret); + } + return ret; +} + +int32_t UsbServerProxy::ManageDevice(int32_t vendorId, int32_t productId, bool disable) +{ + sptr remote = Remote(); + RETURN_IF_WITH_RET(remote == nullptr, UEC_INTERFACE_INVALID_VALUE); + + MessageParcel data; + if (!data.WriteInterfaceToken(UsbServerProxy::GetDescriptor())) { + USB_HILOGE(MODULE_USB_SERVICE, "write descriptor failed!"); + return ERR_ENOUGH_DATA; + } + WRITE_PARCEL_WITH_RET(data, Int32, vendorId, UEC_SERVICE_WRITE_PARCEL_ERROR); + WRITE_PARCEL_WITH_RET(data, Int32, productId, UEC_SERVICE_WRITE_PARCEL_ERROR); + WRITE_PARCEL_WITH_RET(data, Bool, disable, UEC_SERVICE_WRITE_PARCEL_ERROR); + + MessageOption option; + MessageParcel reply; + int32_t ret = remote->SendRequest(static_cast(UsbInterfaceCode::USB_FUN_DISABLE_DEVICE), + data, reply, option); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "SendRequest is failed, error code: %d", ret); + } + return ret; +} + +int32_t UsbServerProxy::ManageInterfaceType(InterfaceType interfaceType, bool disable) +{ + sptr remote = Remote(); + RETURN_IF_WITH_RET(remote == nullptr, UEC_INTERFACE_INVALID_VALUE); + + MessageParcel data; + if (!data.WriteInterfaceToken(UsbServerProxy::GetDescriptor())) { + USB_HILOGE(MODULE_USB_SERVICE, "write descriptor failed!"); + return ERR_ENOUGH_DATA; + } + int32_t ifaceType = (int32_t)interfaceType; + WRITE_PARCEL_WITH_RET(data, Int32, ifaceType, UEC_SERVICE_WRITE_PARCEL_ERROR); + WRITE_PARCEL_WITH_RET(data, Bool, disable, UEC_SERVICE_WRITE_PARCEL_ERROR); + + MessageOption option; + MessageParcel reply; + int32_t ret = remote->SendRequest(static_cast(UsbInterfaceCode::USB_FUN_DISABLE_INTERFACE_TYPE), + data, reply, option); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "SendRequest is failed, error code: %d", ret); + } + return ret; +} } // namespace USB } // namespace OHOS diff --git a/services/zidl/src/usb_srv_stub.cpp b/services/zidl/src/usb_srv_stub.cpp index 90141fb54f1e591bce9d4193f42136e298161608..01859db311446e9a9f51e609426554940927b254 100644 --- a/services/zidl/src/usb_srv_stub.cpp +++ b/services/zidl/src/usb_srv_stub.cpp @@ -19,6 +19,7 @@ #include "usb_common.h" #include "usb_errors.h" #include "usb_server_stub.h" +#include "usb_interface_type.h" using namespace OHOS::HDI::Usb::V1_0; namespace OHOS { @@ -182,6 +183,15 @@ bool UsbServerStub::StubHost( case static_cast(UsbInterfaceCode::USB_FUN_GET_DESCRIPTOR): result = DoGetRawDescriptor(data, reply, option); return true; + case static_cast(UsbInterfaceCode::USB_FUN_DISABLE_GLOBAL_INTERFACE): + result = DoManageGlobalInterface(data, reply, option); + return true; + case static_cast(UsbInterfaceCode::USB_FUN_DISABLE_DEVICE): + result = DoManageDevice(data, reply, option); + return true; + case static_cast(UsbInterfaceCode::USB_FUN_DISABLE_INTERFACE_TYPE): + result = DoManageInterfaceType(data, reply, option); + return true; default:; } return false; @@ -864,5 +874,44 @@ int32_t UsbServerStub::DoAddRight(MessageParcel &data, MessageParcel &reply, Mes } return ret; } + +int32_t UsbServerStub::DoManageGlobalInterface(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + bool disable = false; + READ_PARCEL_WITH_RET(data, Bool, disable, UEC_SERVICE_READ_PARCEL_ERROR); + int32_t ret = ManageGlobalInterface(disable); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USBD, "ret:%{public}d", ret); + } + return ret; +} + +int32_t UsbServerStub::DoManageDevice(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + int32_t vendorId = 0; + int32_t productId = 0; + bool disable = false; + READ_PARCEL_WITH_RET(data, Int32, vendorId, UEC_SERVICE_READ_PARCEL_ERROR); + READ_PARCEL_WITH_RET(data, Int32, productId, UEC_SERVICE_READ_PARCEL_ERROR); + READ_PARCEL_WITH_RET(data, Bool, disable, UEC_SERVICE_READ_PARCEL_ERROR); + int32_t ret = ManageDevice(vendorId, productId, disable); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USBD, "ret:%{public}d", ret); + } + return ret; +} + +int32_t UsbServerStub::DoManageInterfaceType(MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + int32_t interfaceType = 0; + bool disable = false; + READ_PARCEL_WITH_RET(data, Int32, interfaceType, UEC_SERVICE_READ_PARCEL_ERROR); + READ_PARCEL_WITH_RET(data, Bool, disable, UEC_SERVICE_READ_PARCEL_ERROR); + int32_t ret = ManageInterfaceType((InterfaceType)interfaceType, disable); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USBD, "ret:%{public}d", ret); + } + return ret; +} } // namespace USB } // namespace OHOS diff --git a/utils/native/include/usb_errors.h b/utils/native/include/usb_errors.h index 195994bf3396db1aae0183c47fc40831a56f371d..1fda0ffc680f59637092fbacc532f65ac86a85bb 100644 --- a/utils/native/include/usb_errors.h +++ b/utils/native/include/usb_errors.h @@ -77,6 +77,13 @@ enum UsbErrCode { UEC_SERVICE_PERMISSION_CHECK_HDC, UEC_SERVICE_NOT_SUPPORT_SWITCH_PORT, UEC_SERVICE_END, + UEC_SERVICE_PRE_MANAGE_INTERFACE_FAILED, + UEC_SERVICE_EXECUTE_POLICY_FAILED, + UEC_SERVICE_PREPARE_EDM_SA_FAILED, + UEC_SERVICE_GET_EDM_SERVICE_FAILED, + UEC_SERVICE_EDM_DEVICE_SIZE_EXCEED, + UEC_SERVICE_EDM_SA_TIME_OUT_FAILED, + UEC_SERVICE_EDM_SEND_REQUEST_FAILED, }; enum UsbRightErrCode {