1 /* 2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "usb_device_manager.h" 17 #include <hdf_base.h> 18 #include "common_event_data.h" 19 #include "common_event_manager.h" 20 #include "common_event_support.h" 21 #include "hisysevent.h" 22 #include "usb_errors.h" 23 #include "usb_srv_support.h" 24 #include "usbd_type.h" 25 26 using namespace OHOS::AAFwk; 27 using namespace OHOS::EventFwk; 28 using namespace OHOS::HiviewDFX; 29 using namespace OHOS::HDI::Usb::V1_0; 30 31 namespace OHOS { 32 namespace USB { 33 constexpr int32_t PARAM_COUNT_TWO = 2; 34 constexpr int32_t PARAM_COUNT_THR = 3; 35 constexpr uint32_t CMD_INDEX = 1; 36 constexpr uint32_t PARAM_INDEX = 2; 37 constexpr uint32_t DELAY_CONNECT_INTERVAL = 300; 38 constexpr uint32_t DELAY_DISCONN_INTERVAL = 1400; 39 const std::map<std::string_view, uint32_t> UsbDeviceManager::FUNCTION_MAPPING_N2C = { 40 {UsbSrvSupport::FUNCTION_NAME_NONE, UsbSrvSupport::FUNCTION_NONE}, 41 {UsbSrvSupport::FUNCTION_NAME_ACM, UsbSrvSupport::FUNCTION_ACM}, 42 {UsbSrvSupport::FUNCTION_NAME_ECM, UsbSrvSupport::FUNCTION_ECM}, 43 {UsbSrvSupport::FUNCTION_NAME_HDC, UsbSrvSupport::FUNCTION_HDC}, 44 {UsbSrvSupport::FUNCTION_NAME_MTP, UsbSrvSupport::FUNCTION_MTP}, 45 {UsbSrvSupport::FUNCTION_NAME_PTP, UsbSrvSupport::FUNCTION_PTP}, 46 {UsbSrvSupport::FUNCTION_NAME_RNDIS, UsbSrvSupport::FUNCTION_RNDIS}, 47 {UsbSrvSupport::FUNCTION_NAME_STORAGE, UsbSrvSupport::FUNCTION_STORAGE}, 48 }; 49 UsbDeviceManager()50 UsbDeviceManager::UsbDeviceManager() 51 { 52 USB_HILOGI(MODULE_USB_SERVICE, "UsbDeviceManager::Init start"); 53 usbd_ = IUsbInterface::Get(); 54 if (usbd_ == nullptr) { 55 USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager::Get inteface failed"); 56 } 57 auto ret = delayDisconn_.Setup(); 58 if (ret != UEC_OK) { 59 USB_HILOGE(MODULE_USB_SERVICE, "set up timer failed %{public}u", ret); 60 } 61 } 62 ~UsbDeviceManager()63 UsbDeviceManager::~UsbDeviceManager() 64 { 65 delayDisconn_.Shutdown(); 66 } 67 Init()68 int32_t UsbDeviceManager::Init() 69 { 70 std::shared_ptr<UsbFunctionSwitchWindow> window_ = UsbFunctionSwitchWindow::GetInstance(); 71 if (window_ == nullptr) { 72 USB_HILOGE(MODULE_USB_SERVICE, "get usb function switch window failed"); 73 return UEC_SERVICE_INNER_ERR; 74 } 75 76 int32_t ret = window_->Init(); 77 if (ret != UEC_OK) { 78 USB_HILOGE(MODULE_USB_SERVICE, "Init usb function switch window failed"); 79 } 80 return ret; 81 } 82 SetUsbd(const sptr<IUsbInterface> & usbd)83 int32_t UsbDeviceManager::SetUsbd(const sptr<IUsbInterface> &usbd) 84 { 85 if (usbd == nullptr) { 86 USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager usbd is nullptr"); 87 return UEC_SERVICE_INVALID_VALUE; 88 } 89 usbd_ = usbd; 90 return UEC_OK; 91 } 92 AreSettableFunctions(int32_t funcs)93 bool UsbDeviceManager::AreSettableFunctions(int32_t funcs) 94 { 95 return static_cast<uint32_t>(funcs) == UsbSrvSupport::FUNCTION_NONE || 96 ((~functionSettable_ & static_cast<uint32_t>(funcs)) == 0); 97 } 98 ConvertFromString(std::string_view strFun)99 uint32_t UsbDeviceManager::ConvertFromString(std::string_view strFun) 100 { 101 if (strFun == UsbSrvSupport::FUNCTION_NAME_NONE) { 102 return UsbSrvSupport::FUNCTION_NONE; 103 } 104 105 size_t len = strFun.length(); 106 if (len == 0) { 107 return UEC_SERVICE_INVALID_VALUE; 108 } 109 110 std::vector<std::string_view> vModeStr; 111 size_t pos = 0; 112 while (pos < len) { 113 size_t findPos = strFun.find(",", pos); 114 if (findPos == strFun.npos) { 115 vModeStr.push_back(strFun.substr(pos, len - pos)); 116 break; 117 } 118 vModeStr.push_back(strFun.substr(pos, findPos - pos)); 119 pos = findPos + 1; 120 } 121 122 uint32_t ret = 0; 123 for (auto &&item : vModeStr) { 124 auto it = FUNCTION_MAPPING_N2C.find(item); 125 if (it != FUNCTION_MAPPING_N2C.end()) { 126 ret |= it->second; 127 } else { 128 USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager::ConvertFromString Invalid argument of usb function"); 129 return UEC_SERVICE_INVALID_VALUE; 130 } 131 } 132 133 return ret; 134 } 135 ConvertToString(uint32_t function)136 std::string UsbDeviceManager::ConvertToString(uint32_t function) 137 { 138 std::string stream; 139 if (function <= UsbSrvSupport::FUNCTION_NONE || function > functionSettable_) { 140 stream = std::string {UsbSrvSupport::FUNCTION_NAME_NONE}; 141 return stream; 142 } 143 bool flag = false; 144 for (auto it = FUNCTION_MAPPING_N2C.begin(); it != FUNCTION_MAPPING_N2C.end(); ++it) { 145 if ((function & it->second) != 0) { 146 if (flag) { 147 stream += ","; 148 } 149 stream += std::string {it->first}; 150 flag = true; 151 } 152 } 153 USB_HILOGI(MODULE_USB_SERVICE, "UsbDeviceManager::ConvertToString success"); 154 return stream; 155 } 156 UpdateFunctions(int32_t func)157 void UsbDeviceManager::UpdateFunctions(int32_t func) 158 { 159 if (func == currentFunctions_) { 160 return; 161 } 162 ReportFuncChangeSysEvent(currentFunctions_, func); 163 currentFunctions_ = func; 164 BroadcastFuncChange(connected_, currentFunctions_); 165 } 166 GetCurrentFunctions()167 int32_t UsbDeviceManager::GetCurrentFunctions() 168 { 169 return currentFunctions_; 170 } 171 HandleEvent(int32_t status)172 void UsbDeviceManager::HandleEvent(int32_t status) 173 { 174 if (usbd_ == nullptr) { 175 return; 176 } 177 bool curConnect = false; 178 switch (status) { 179 case ACT_UPDEVICE: 180 curConnect = true; 181 gadgetConnected_ = true; 182 break; 183 184 case ACT_DOWNDEVICE: 185 curConnect = false; 186 gadgetConnected_ = false; 187 break; 188 case ACT_ACCESSORYUP: 189 case ACT_ACCESSORYDOWN: 190 case ACT_ACCESSORYSEND: 191 ProcessFunctionSwitchWindow(false); 192 return; 193 default: 194 USB_HILOGE(MODULE_USB_SERVICE, "invalid status %{public}d", status); 195 return; 196 } 197 delayDisconn_.Unregister(delayDisconnTimerId_); 198 if (curConnect && (connected_ != curConnect)) { 199 auto task = [&]() { 200 connected_ = true; 201 usbd_->GetCurrentFunctions(currentFunctions_); 202 ProcessFuncChange(connected_, currentFunctions_); 203 }; 204 delayDisconnTimerId_ = delayDisconn_.Register(task, DELAY_CONNECT_INTERVAL, true); 205 } else if (!curConnect && (connected_ != curConnect)) { 206 auto task = [&]() { 207 connected_ = false; 208 if ((currentFunctions_ & USB_FUNCTION_MTP) != 0 || (currentFunctions_ & USB_FUNCTION_PTP) != 0) { 209 currentFunctions_ = currentFunctions_ & (~USB_FUNCTION_MTP) & (~USB_FUNCTION_PTP); 210 USB_HILOGI(MODULE_USB_SERVICE, "usb function reset %{public}u", currentFunctions_); 211 currentFunctions_ = currentFunctions_ == 0 ? USB_FUNCTION_STORAGE : currentFunctions_; 212 usbd_->SetCurrentFunctions(currentFunctions_); 213 } 214 ProcessFuncChange(connected_, currentFunctions_); 215 return; 216 }; 217 delayDisconnTimerId_ = delayDisconn_.Register(task, DELAY_DISCONN_INTERVAL, true); 218 } else { 219 USB_HILOGI(MODULE_USB_SERVICE, "else info cur status %{public}d, bconnected: %{public}d", status, connected_); 220 } 221 } 222 UserChangeProcess()223 int32_t UsbDeviceManager::UserChangeProcess() 224 { 225 if ((currentFunctions_ & USB_FUNCTION_MTP) != 0 || (currentFunctions_ & USB_FUNCTION_PTP) != 0) { 226 currentFunctions_ = currentFunctions_ & (~USB_FUNCTION_MTP) & (~USB_FUNCTION_PTP); 227 currentFunctions_ = currentFunctions_ == 0 ? USB_FUNCTION_STORAGE : currentFunctions_; 228 USB_HILOGI(MODULE_USB_SERVICE, "usb function reset %{public}d", currentFunctions_); 229 return usbd_->SetCurrentFunctions(currentFunctions_); 230 } 231 return UEC_OK; 232 } 233 BroadcastFuncChange(bool connected,int32_t currentFunc)234 void UsbDeviceManager::BroadcastFuncChange(bool connected, int32_t currentFunc) 235 { 236 USB_HILOGI(MODULE_USB_SERVICE, "Current Connect %{public}d,bconnected: %{public}d", connected, currentFunc); 237 Want want; 238 want.SetAction(CommonEventSupport::COMMON_EVENT_USB_STATE); 239 240 want.SetParam(std::string {UsbSrvSupport::CONNECTED}, connected); 241 uint32_t remainderFunc = static_cast<uint32_t>(currentFunc); 242 // start from bit 1 243 uint32_t bit = 1; 244 while (remainderFunc != 0) { 245 if (remainderFunc & bit) { 246 want.SetParam(ConvertToString(bit), true); 247 // set current bit to zero 248 remainderFunc &= ~bit; 249 } 250 // 1 means to next bit 251 bit = bit << 1; 252 } 253 CommonEventData data(want); 254 CommonEventPublishInfo publishInfo; 255 USB_HILOGI(MODULE_SERVICE, "send COMMON_EVENT_USB_STATE broadcast connected:%{public}d, " 256 "currentFunctions:%{public}d", connected, currentFunc); 257 CommonEventManager::PublishCommonEvent(data, publishInfo); 258 ReportDevicePlugSysEvent(currentFunc, connected); 259 } 260 ProcessFuncChange(bool connected,int32_t currentFunc)261 void UsbDeviceManager::ProcessFuncChange(bool connected, int32_t currentFunc) 262 { 263 BroadcastFuncChange(connected, currentFunc); 264 ProcessFunctionSwitchWindow(connected); 265 } 266 ProcessFunctionSwitchWindow(bool connected)267 void UsbDeviceManager::ProcessFunctionSwitchWindow(bool connected) 268 { 269 std::shared_ptr<UsbFunctionSwitchWindow> window_ = UsbFunctionSwitchWindow::GetInstance(); 270 if (window_ == nullptr) { 271 USB_HILOGE(MODULE_USB_SERVICE, "show window: get usb function switch window failed"); 272 return; 273 } 274 275 if (connected) { 276 USB_HILOGD(MODULE_USB_SERVICE, "start pop up usb service switch window"); 277 if (!window_->PopUpFunctionSwitchWindow()) { 278 USB_HILOGE(MODULE_USB_SERVICE, "start pop up usb service switch window failed"); 279 } 280 } else { 281 USB_HILOGD(MODULE_USB_SERVICE, "start dismiss usb service switch window"); 282 if (!window_->DismissFunctionSwitchWindow()) { 283 USB_HILOGE(MODULE_USB_SERVICE, "start dismiss usb service switch window failed"); 284 } 285 } 286 } 287 GetDumpHelp(int32_t fd)288 void UsbDeviceManager::GetDumpHelp(int32_t fd) 289 { 290 dprintf(fd, "========= dump the all device function =========\n"); 291 dprintf(fd, "usb_device -a: Query all function\n"); 292 dprintf(fd, "usb_device -f Q: Query Current function\n"); 293 dprintf(fd, "usb_device -f 0: Switch to function:none\n"); 294 dprintf(fd, "usb_device -f 1: Switch to function:acm\n"); 295 dprintf(fd, "usb_device -f 2: Switch to function:ecm\n"); 296 dprintf(fd, "usb_device -f 3: Switch to function:acm&ecm\n"); 297 dprintf(fd, "usb_device -f 4: Switch to function:hdc\n"); 298 dprintf(fd, "usb_device -f 5: Switch to function:acm&hdc\n"); 299 dprintf(fd, "usb_device -f 6: Switch to function:ecm&hdc\n"); 300 dprintf(fd, "usb_device -f 32: Switch to function:rndis\n"); 301 dprintf(fd, "usb_device -f 512:Switch to function:storage\n"); 302 dprintf(fd, "usb_device -f 36: Switch to function:rndis&hdc\n"); 303 dprintf(fd, "usb_device -f 516:Switch to function:storage&hdc\n"); 304 dprintf(fd, "------------------------------------------------\n"); 305 } 306 DumpGetSupportFunc(int32_t fd)307 void UsbDeviceManager::DumpGetSupportFunc(int32_t fd) 308 { 309 dprintf(fd, "Usb Device function list info:\n"); 310 dprintf(fd, "current function: %s\n", ConvertToString(currentFunctions_).c_str()); 311 dprintf(fd, "supported functions list: %s\n", ConvertToString(functionSettable_).c_str()); 312 } 313 DumpSetFunc(int32_t fd,const std::string & args)314 void UsbDeviceManager::DumpSetFunc(int32_t fd, const std::string &args) 315 { 316 int32_t currentFunction; 317 int32_t ret; 318 if (usbd_ == nullptr) { 319 USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager::DumpSetFunc usbd_ is nullptr"); 320 return; 321 } 322 if (args.compare("Q") == 0) { 323 ret = usbd_->GetCurrentFunctions(currentFunction); 324 if (ret != UEC_OK) { 325 dprintf(fd, "GetCurrentFunctions failed: %d\n", __LINE__); 326 return; 327 } 328 dprintf(fd, "current function: %s\n", ConvertToString(currentFunction).c_str()); 329 return; 330 } 331 332 int32_t mode = stoi(args); 333 ret = usbd_->SetCurrentFunctions(mode); 334 if (ret != UEC_OK) { 335 dprintf(fd, "SetCurrentFunctions failed"); 336 return; 337 } 338 ret = usbd_->GetCurrentFunctions(currentFunction); 339 if (ret != UEC_OK) { 340 dprintf(fd, "GetCurrentFunctions failed: %d\n", __LINE__); 341 return; 342 } 343 344 dprintf(fd, "current function: %s\n", ConvertToString(currentFunction).c_str()); 345 } 346 Dump(int32_t fd,const std::vector<std::string> & args)347 void UsbDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args) 348 { 349 if (args.size() < PARAM_COUNT_TWO || args.size() > PARAM_COUNT_THR) { 350 GetDumpHelp(fd); 351 return; 352 } 353 354 if (args[CMD_INDEX] == "-a" && args.size() == PARAM_COUNT_TWO) { 355 DumpGetSupportFunc(fd); 356 } else if (args[CMD_INDEX] == "-f" && args.size() == PARAM_COUNT_THR) { 357 DumpSetFunc(fd, args[PARAM_INDEX]); 358 } else { 359 dprintf(fd, "func param error, please enter again\n"); 360 GetDumpHelp(fd); 361 } 362 } 363 ReportFuncChangeSysEvent(int32_t currentFunctions,int32_t updateFunctions)364 void UsbDeviceManager::ReportFuncChangeSysEvent(int32_t currentFunctions, int32_t updateFunctions) 365 { 366 USB_HILOGI(MODULE_USB_SERVICE, "Device function Indicates the switch point information:"); 367 HiSysEventWrite(HiSysEvent::Domain::USB, "FUNCTION_CHANGED", 368 HiSysEvent::EventType::BEHAVIOR, "CURRENT_FUNCTION", 369 currentFunctions_, "UPDATE_FUNCTION", updateFunctions); 370 } 371 ReportDevicePlugSysEvent(int32_t currentFunctions,bool connected)372 void UsbDeviceManager::ReportDevicePlugSysEvent(int32_t currentFunctions, bool connected) 373 { 374 USB_HILOGI(MODULE_USB_SERVICE, "Device mode Indicates the insertion and removal information:"); 375 HiSysEventWrite(HiSysEvent::Domain::USB, "PLUG_IN_OUT_DEVICE_MODE", 376 HiSysEvent::EventType::BEHAVIOR, "CURRENT_FUNCTIONS", 377 currentFunctions, "CONNECTED", connected); 378 } IsGadgetConnected(void)379 bool UsbDeviceManager::IsGadgetConnected(void) 380 { 381 return gadgetConnected_; 382 } 383 } // namespace USB 384 } // namespace OHOS 385