1 /*
2 * Copyright (c) 2022-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 <regex>
17 #include "usb_port_manager.h"
18 #include <unistd.h>
19 #include "hisysevent.h"
20 #include "usb_errors.h"
21 #include "usb_srv_support.h"
22 #include "if_system_ability_manager.h"
23 #include "usb_connection_notifier.h"
24 #include "system_ability_definition.h"
25 #include "iproxy_broker.h"
26 #include "iservice_registry.h"
27
28 using namespace OHOS::HiviewDFX;
29 using namespace OHOS::HDI::Usb::V1_0;
30
31 namespace OHOS {
32 namespace USB {
33 #ifndef USB_MANAGER_V2_0
34 constexpr int32_t SUPPORTED_MODES = 3;
35 #endif
36 constexpr int32_t PARAM_COUNT_TWO = 2;
37 constexpr int32_t PARAM_COUNT_THR = 3;
38 constexpr int32_t DEFAULT_ROLE_HOST = 1;
39 constexpr uint32_t CMD_INDEX = 1;
40 constexpr uint32_t PARAM_INDEX = 2;
41 constexpr int32_t HOST_MODE = 2;
42 constexpr int32_t WAIT_DELAY_US = 20000;
UsbPortManager()43 UsbPortManager::UsbPortManager()
44 {
45 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::Init start");
46 #ifndef USB_MANAGER_V2_0
47 GetIUsbInterface();
48 #endif // USB_MANAGER_V2_0
49 }
50
~UsbPortManager()51 UsbPortManager::~UsbPortManager()
52 {
53 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::unInit start");
54 }
55
Init()56 void UsbPortManager::Init()
57 {
58 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::QueryPort start");
59 int32_t ret = QueryPort();
60 if (ret) {
61 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::QueryPort false");
62 }
63 AddSupportedMode();
64 }
65
AddSupportedMode()66 void UsbPortManager::AddSupportedMode()
67 {
68 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s:: Enter", __func__);
69 supportedModeMap_.clear();
70 for (const auto& [portId, port] : portMap_) {
71 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s:: portId is %{public}d, supportedModes is %{public}d",
72 __func__, port.id, port.supportedModes);
73 supportedModeMap_[portId] = port.supportedModes;
74 }
75 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s:: successed", __func__);
76 }
77
78 #ifdef USB_MANAGER_V2_0
InitUsbPortInterface()79 bool UsbPortManager::InitUsbPortInterface()
80 {
81 USB_HILOGI(MODULE_USB_SERVICE, "InitUsbPortInterface in");
82 for (int32_t i = 0; i < PARAM_COUNT_THR; i++) {
83 usbPortInterface_ = HDI::Usb::V2_0::IUsbPortInterface::Get();
84 if (usbPortInterface_ == nullptr) {
85 USB_HILOGE(MODULE_USB_SERVICE, "GetIUsbInterface get usbPortInterface_ is nullptr");
86 usleep(WAIT_DELAY_US);
87 } else {
88 break;
89 }
90 }
91 if (usbPortInterface_ == nullptr) {
92 USB_HILOGE(MODULE_USB_SERVICE, "InitUsbPortInterface get usbPortInterface_ is nullptr");
93 return false;
94 }
95 usbManagerSubscriber_ = new (std::nothrow) UsbManagerSubscriber();
96 if (usbManagerSubscriber_ == nullptr) {
97 USB_HILOGE(MODULE_USB_SERVICE, "Init failed");
98 return false;
99 }
100 recipient_ = new UsbdPortDeathRecipient();
101 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<HDI::Usb::V2_0::IUsbPortInterface>(usbPortInterface_);
102 if (!remote->AddDeathRecipient(recipient_)) {
103 USB_HILOGE(MODULE_USB_SERVICE, "add DeathRecipient failed");
104 return false;
105 }
106
107 ErrCode ret = usbPortInterface_->BindUsbdPortSubscriber(usbManagerSubscriber_);
108 USB_HILOGI(MODULE_USB_SERVICE, "entry InitUsbPortInterface ret: %{public}d", ret);
109 return SUCCEEDED(ret);
110 }
111
OnRemoteDied(const wptr<IRemoteObject> & object)112 void UsbPortManager::UsbdPortDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
113 {
114 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
115 if (samgrProxy == nullptr) {
116 USB_HILOGE(MODULE_USB_SERVICE, "get samgr failed");
117 return;
118 }
119
120 auto ret = samgrProxy->UnloadSystemAbility(USB_SYSTEM_ABILITY_ID);
121 if (ret != UEC_OK) {
122 USB_HILOGE(MODULE_USB_SERVICE, "unload failed");
123 }
124 }
125
Stop()126 void UsbPortManager::Stop()
127 {
128 if (usbPortInterface_ == nullptr) {
129 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::usbPortInterface_ is nullptr");
130 return;
131 }
132 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<HDI::Usb::V2_0::IUsbPortInterface>(usbPortInterface_);
133 remote->RemoveDeathRecipient(recipient_);
134 recipient_.clear();
135 usbPortInterface_->UnbindUsbdPortSubscriber(usbManagerSubscriber_);
136 Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 0, USB_SYSTEM_ABILITY_ID);
137 }
138
BindUsbdSubscriber(const sptr<HDI::Usb::V2_0::IUsbdSubscriber> & subscriber)139 int32_t UsbPortManager::BindUsbdSubscriber(const sptr<HDI::Usb::V2_0::IUsbdSubscriber> &subscriber)
140 {
141 if (usbPortInterface_ == nullptr) {
142 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::BulkCancel usbPortInterface_ is nullptr");
143 return UEC_SERVICE_INVALID_VALUE;
144 }
145 return usbPortInterface_->BindUsbdPortSubscriber(subscriber);
146 }
147
UnbindUsbdSubscriber(const sptr<HDI::Usb::V2_0::IUsbdSubscriber> & subscriber)148 int32_t UsbPortManager::UnbindUsbdSubscriber(const sptr<HDI::Usb::V2_0::IUsbdSubscriber> &subscriber)
149 {
150 if (usbPortInterface_ == nullptr) {
151 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::BulkCancel usbPortInterface_ is nullptr");
152 return UEC_SERVICE_INVALID_VALUE;
153 }
154 return usbPortInterface_->UnbindUsbdPortSubscriber(subscriber);
155 }
156 #endif // USB_MANAGER_V2_0
157
IsReverseCharge()158 bool UsbPortManager::IsReverseCharge()
159 {
160 int32_t powerRole_ = 0;
161 int32_t dataRole_ = 0;
162 auto it = portMap_.find(CMD_INDEX);
163 if (it == portMap_.end()) {
164 USB_HILOGE(MODULE_USB_SERVICE, "Port not found");
165 return false;
166 }
167 powerRole_ = it->second.usbPortStatus.currentPowerRole;
168 dataRole_ = it->second.usbPortStatus.currentDataRole;
169 if (powerRole_ == DEFAULT_ROLE_HOST) {
170 return true;
171 }
172 return false;
173 }
174
SetPortRole(int32_t portId,int32_t powerRole,int32_t dataRole)175 int32_t UsbPortManager::SetPortRole(int32_t portId, int32_t powerRole, int32_t dataRole)
176 {
177 #ifdef USB_MANAGER_V2_0
178 if (usbPortInterface_ == nullptr) {
179 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::SetPortRole usbPortInterface_ is nullptr");
180 return UEC_SERVICE_INVALID_VALUE;
181 }
182 int32_t ret = usbPortInterface_->SetPortRole(portId, powerRole, dataRole);
183 if (ret != UEC_OK) {
184 USB_HILOGI(MODULE_USB_SERVICE, "setportrole failed");
185 return ret;
186 }
187 if (IsReverseCharge()) {
188 UsbConnectionNotifier::GetInstance()->SendNotification(USB_FUNC_REVERSE_CHARGE);
189 } else {
190 UsbConnectionNotifier::GetInstance()->SendNotification(USB_FUNC_CHARGE);
191 }
192 return UEC_OK;
193 #else
194 if (usbd_ == nullptr) {
195 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::usbd_ is nullptr");
196 return UEC_SERVICE_INVALID_VALUE;
197 }
198 int32_t ret = usbd_->SetPortRole(portId, powerRole, dataRole);
199 if (ret != UEC_OK) {
200 USB_HILOGE(MODULE_USB_SERVICE, "setportrole failed");
201 }
202 return ret;
203 #endif // USB_MANAGER_V2_0
204 }
205
GetIUsbInterface()206 void UsbPortManager::GetIUsbInterface()
207 {
208 if (usbd_ == nullptr) {
209 for (int32_t i = 0; i < PARAM_COUNT_THR; i++) {
210 usbd_ = IUsbInterface::Get();
211 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s:Get usbd_", __func__);
212 if (usbd_ == nullptr) {
213 USB_HILOGE(MODULE_USB_SERVICE, "Get iUsbInteface failed");
214 usleep(WAIT_DELAY_US);
215 } else {
216 break;
217 }
218 }
219 }
220 }
221
SetUsbd(const sptr<IUsbInterface> & usbd)222 int32_t UsbPortManager::SetUsbd(const sptr<IUsbInterface> &usbd)
223 {
224 if (usbd == nullptr) {
225 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager usbd is nullptr");
226 return UEC_SERVICE_INVALID_VALUE;
227 }
228 usbd_ = usbd;
229 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s:usbd_ = usbd", __func__);
230 return UEC_OK;
231 }
232
GetPorts(std::vector<UsbPort> & ports)233 int32_t UsbPortManager::GetPorts(std::vector<UsbPort> &ports)
234 {
235 std::lock_guard<std::mutex> lock(mutex_);
236 if (portMap_.size() > 0) {
237 for (auto it = portMap_.begin(); it != portMap_.end(); ++it) {
238 USB_HILOGI(MODULE_USB_SERVICE, "%{public}s: portId is %{public}d, supportedModes is %{public}d",
239 __func__, it->second.id, it->second.supportedModes);
240 ports.push_back(it->second);
241 }
242 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::GetPorts success");
243 return UEC_OK;
244 } else {
245 int32_t ret = QueryPort();
246 if (ret == UEC_OK) {
247 for (auto it = portMap_.begin(); it != portMap_.end(); ++it) {
248 ports.push_back(it->second);
249 }
250 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::QueryPort and GetPorts success");
251 return ret;
252 }
253 }
254 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::GetPorts false");
255 return UEC_SERVICE_INVALID_VALUE;
256 }
257
GetSupportedModes(int32_t portId,int32_t & supportedModes)258 int32_t UsbPortManager::GetSupportedModes(int32_t portId, int32_t &supportedModes)
259 {
260 std::lock_guard<std::mutex> lock(mutex_);
261 auto it = supportedModeMap_.find(portId);
262 if (it != supportedModeMap_.end()) {
263 supportedModes = it->second;
264 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::GetSupportedModes port=%{public}d modes=%{public}d",
265 portId, supportedModes);
266 return UEC_OK;
267 }
268 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManagerSupportedModes port %{public}d not found", portId);
269 return UEC_SERVICE_INVALID_VALUE;
270 }
271
QueryPort()272 int32_t UsbPortManager::QueryPort()
273 {
274 #ifdef USB_MANAGER_V2_0
275 if (usbPortInterface_ == nullptr) {
276 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::QueryPort usbPortInterface_ is nullptr");
277 return UEC_SERVICE_INVALID_VALUE;
278 }
279
280 std::vector<HDI::Usb::V2_0::UsbPort> portList;
281 int32_t ret = usbPortInterface_->QueryPorts(portList);
282 if (ret != UEC_OK) {
283 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s QueryPorts failed", __func__);
284 return ret;
285 }
286
287 for (const auto& it : portList) {
288 AddPortInfo(it.id, it.supportedModes,
289 it.usbPortStatus.currentMode, it.usbPortStatus.currentDataRole, it.usbPortStatus.currentPowerRole);
290 }
291 #else
292 GetIUsbInterface();
293 if (usbd_ == nullptr) {
294 USB_HILOGE(MODULE_USB_SERVICE, "UsbPortManager::usbd_ is nullptr");
295 return UEC_SERVICE_INVALID_VALUE;
296 }
297
298 int32_t portId = 0;
299 int32_t powerRole = 0;
300 int32_t dataRole = 0;
301 int32_t mode = 0;
302 int32_t ret = usbd_->QueryPort(portId, powerRole, dataRole, mode);
303 if (ret != UEC_OK) {
304 USB_HILOGE(MODULE_USB_SERVICE, "%{public}s QueryPort failed", __func__);
305 return ret;
306 }
307
308 AddPortInfo(portId, SUPPORTED_MODES, mode, dataRole, powerRole);
309 #endif // USB_MANAGER_V2_0
310 return ret;
311 }
312
UpdatePort(int32_t portId,int32_t powerRole,int32_t dataRole,int32_t mode)313 void UsbPortManager::UpdatePort(int32_t portId, int32_t powerRole, int32_t dataRole, int32_t mode)
314 {
315 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::updatePort run");
316 std::lock_guard<std::mutex> lock(mutex_);
317 auto it = portMap_.find(portId);
318 if (it != portMap_.end()) {
319 if (it->second.id == portId) {
320 ReportPortRoleChangeSysEvent(it->second.usbPortStatus.currentPowerRole, powerRole,
321 it->second.usbPortStatus.currentDataRole, dataRole);
322 it->second.usbPortStatus.currentPowerRole = powerRole;
323 it->second.usbPortStatus.currentDataRole = dataRole;
324 if (it->second.usbPortStatus.currentDataRole == UsbSrvSupport::DATA_ROLE_HOST) {
325 it->second.usbPortStatus.currentMode = UsbSrvSupport::PORT_MODE_HOST;
326 } else if (it->second.usbPortStatus.currentDataRole == UsbSrvSupport::DATA_ROLE_DEVICE) {
327 it->second.usbPortStatus.currentMode = UsbSrvSupport::PORT_MODE_DEVICE;
328 }
329 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::updatePort seccess");
330 return;
331 }
332 }
333 USB_HILOGE(MODULE_USB_SERVICE, "updatePort false");
334 }
335
UpdatePort(int32_t portId,int32_t powerRole,int32_t dataRole,int32_t mode,int32_t supportedModes)336 void UsbPortManager::UpdatePort(int32_t portId, int32_t powerRole, int32_t dataRole,
337 int32_t mode, int32_t supportedModes)
338 {
339 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::updatePort run");
340 std::lock_guard<std::mutex> lock(mutex_);
341 auto it = portMap_.find(portId);
342 if (it != portMap_.end()) {
343 if (it->second.id == portId) {
344 ReportPortRoleChangeSysEvent(it->second.usbPortStatus.currentPowerRole, powerRole,
345 it->second.usbPortStatus.currentDataRole, dataRole);
346 it->second.usbPortStatus.currentPowerRole = powerRole;
347 it->second.usbPortStatus.currentDataRole = dataRole;
348 if (it->second.usbPortStatus.currentDataRole == UsbSrvSupport::DATA_ROLE_HOST) {
349 it->second.usbPortStatus.currentMode = UsbSrvSupport::PORT_MODE_HOST;
350 } else if (it->second.usbPortStatus.currentDataRole == UsbSrvSupport::DATA_ROLE_DEVICE) {
351 it->second.usbPortStatus.currentMode = UsbSrvSupport::PORT_MODE_DEVICE;
352 }
353 USB_HILOGI(MODULE_USB_SERVICE, "UsbPortManager::updatePort seccess");
354 return;
355 }
356 }
357 USB_HILOGE(MODULE_USB_SERVICE, "updatePort false");
358 }
359
AddPortInfo(int32_t portId,int32_t supportedModes,int32_t currentMode,int32_t currentDataRole,int32_t currentPowerRole)360 void UsbPortManager::AddPortInfo(int32_t portId, int32_t supportedModes,
361 int32_t currentMode, int32_t currentDataRole, int32_t currentPowerRole)
362 {
363 UsbPort usbPort;
364 usbPort.id = portId;
365 usbPort.supportedModes = supportedModes;
366 usbPort.usbPortStatus.currentMode = currentMode;
367 usbPort.usbPortStatus.currentDataRole = currentDataRole;
368 usbPort.usbPortStatus.currentPowerRole = currentPowerRole;
369 AddPort(usbPort);
370 }
371
AddPort(UsbPort & port)372 void UsbPortManager::AddPort(UsbPort &port)
373 {
374 USB_HILOGI(MODULE_USB_SERVICE, "addPort run, portId is %{public}d, supportedModes is %{public}d",
375 port.id, port.supportedModes);
376
377 auto res = portMap_.insert(std::map<int32_t, UsbPort>::value_type(port.id, port));
378 if (!res.second) {
379 USB_HILOGW(MODULE_USB_SERVICE, "addPort port id duplicated");
380 return;
381 }
382 USB_HILOGI(MODULE_USB_SERVICE, "addPort successed");
383 }
384
RemovePort(int32_t portId)385 void UsbPortManager::RemovePort(int32_t portId)
386 {
387 USB_HILOGI(MODULE_USB_SERVICE, "removePort run");
388 std::lock_guard<std::mutex> lock(mutex_);
389 size_t num = portMap_.erase(portId);
390 if (num == 0) {
391 USB_HILOGW(MODULE_USB_SERVICE, "removePort false");
392 return;
393 }
394 USB_HILOGI(MODULE_USB_SERVICE, "removePort seccess");
395 }
396
GetPortsInfo(int32_t fd)397 void UsbPortManager::GetPortsInfo(int32_t fd)
398 {
399 std::vector<UsbPort> usbports;
400 int32_t ret = GetPorts(usbports);
401 if (ret != UEC_OK) {
402 dprintf(fd, "%s:GetPorts failed\n", __func__);
403 return;
404 }
405
406 if (usbports[0].usbPortStatus.currentMode == HOST_MODE) {
407 dprintf(fd, "get current port %d: host\n", usbports[0].usbPortStatus.currentMode);
408 } else {
409 dprintf(fd, "get current port %d: device\n", usbports[0].usbPortStatus.currentMode);
410 }
411 }
412
GetDumpHelp(int32_t fd)413 void UsbPortManager::GetDumpHelp(int32_t fd)
414 {
415 dprintf(fd, "=========== dump the all device port ===========\n");
416 dprintf(fd, "usb_port -a: Query All Port List\n");
417 dprintf(fd, "usb_port -p Q: Query Port\n");
418 dprintf(fd, "------------------------------------------------\n");
419 }
420
DumpGetSupportPort(int32_t fd)421 void UsbPortManager::DumpGetSupportPort(int32_t fd)
422 {
423 dprintf(fd, "Usb Port device status:\n");
424 std::vector<UsbPort> ports;
425 if (GetPorts(ports) != UEC_OK) {
426 dprintf(fd, "UsbPortManager::GetPorts failed, port is empty\n");
427 return;
428 }
429
430 if (ports.size() == 0) {
431 dprintf(fd, "all port list is empty\n");
432 return;
433 }
434 for (size_t i = 0; i < ports.size(); ++i) {
435 dprintf(fd, "id: %d | supportedModes: %d | currentMode: %d | currentPowerRole: %d | currentDataRole: %d\n",
436 ports[i].id, ports[i].supportedModes, ports[i].usbPortStatus.currentMode,
437 ports[i].usbPortStatus.currentPowerRole, ports[i].usbPortStatus.currentDataRole);
438 }
439 }
440
DumpSetPortRoles(int32_t fd,const std::string & args)441 void UsbPortManager::DumpSetPortRoles(int32_t fd, const std::string &args)
442 {
443 if (args.compare("Q") == 0) {
444 GetPortsInfo(fd);
445 return;
446 }
447 dprintf(fd, "port param error, please enter again\n");
448 GetDumpHelp(fd);
449 }
450
Dump(int32_t fd,const std::vector<std::string> & args)451 void UsbPortManager::Dump(int32_t fd, const std::vector<std::string> &args)
452 {
453 if (args.size() < PARAM_COUNT_TWO || args.size() > PARAM_COUNT_THR) {
454 GetDumpHelp(fd);
455 return;
456 }
457
458 if (args[CMD_INDEX] == "-a" && args.size() == PARAM_COUNT_TWO) {
459 DumpGetSupportPort(fd);
460 } else if (args[CMD_INDEX] == "-p" && args.size() == PARAM_COUNT_THR) {
461 DumpSetPortRoles(fd, args[PARAM_INDEX]);
462 } else {
463 dprintf(fd, "port param error, please enter again\n");
464 GetDumpHelp(fd);
465 }
466 }
467
ReportPortRoleChangeSysEvent(int32_t currentPowerRole,int32_t updatePowerRole,int32_t currentDataRole,int32_t updateDataRole)468 void UsbPortManager::ReportPortRoleChangeSysEvent(
469 int32_t currentPowerRole, int32_t updatePowerRole, int32_t currentDataRole, int32_t updateDataRole)
470 {
471 USB_HILOGI(MODULE_USB_SERVICE, "Port switch points are as follows:");
472 HiSysEventWrite(HiSysEvent::Domain::USB, "PORT_ROLE_CHANGED",
473 HiSysEvent::EventType::BEHAVIOR, "CURRENT_POWERROLE",
474 currentPowerRole, "UPDATE_POWERROLE", updatePowerRole, "CURRENT_DATAROLE", currentDataRole, "UPDATE_DATAROLE",
475 updateDataRole);
476 }
477 } // namespace USB
478 } // namespace OHOS
479