• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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