• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_DISCONN_INTERVAL = 1 * 1000;
38 const std::map<std::string_view, uint32_t> UsbDeviceManager::FUNCTION_MAPPING_N2C = {
39     {UsbSrvSupport::FUNCTION_NAME_NONE, UsbSrvSupport::FUNCTION_NONE},
40     {UsbSrvSupport::FUNCTION_NAME_ACM, UsbSrvSupport::FUNCTION_ACM},
41     {UsbSrvSupport::FUNCTION_NAME_ECM, UsbSrvSupport::FUNCTION_ECM},
42     {UsbSrvSupport::FUNCTION_NAME_HDC, UsbSrvSupport::FUNCTION_HDC},
43     {UsbSrvSupport::FUNCTION_NAME_MTP, UsbSrvSupport::FUNCTION_MTP},
44     {UsbSrvSupport::FUNCTION_NAME_PTP, UsbSrvSupport::FUNCTION_PTP},
45     {UsbSrvSupport::FUNCTION_NAME_RNDIS, UsbSrvSupport::FUNCTION_RNDIS},
46     {UsbSrvSupport::FUNCTION_NAME_STORAGE, UsbSrvSupport::FUNCTION_STORAGE},
47 };
48 
UsbDeviceManager()49 UsbDeviceManager::UsbDeviceManager()
50 {
51     USB_HILOGI(MODULE_USB_SERVICE, "UsbDeviceManager::Init start");
52     usbd_ = IUsbInterface::Get();
53     if (usbd_ == nullptr) {
54         USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager::Get inteface failed");
55     }
56 }
57 
Init()58 int32_t UsbDeviceManager::Init()
59 {
60     std::shared_ptr<UsbFunctionSwitchWindow> window_ = UsbFunctionSwitchWindow::GetInstance();
61     if (window_ == nullptr) {
62         USB_HILOGE(MODULE_USB_SERVICE, "get usb function switch window failed");
63         return UEC_SERVICE_INNER_ERR;
64     }
65 
66     int32_t ret = window_->Init();
67     if (ret != UEC_OK) {
68         USB_HILOGE(MODULE_USB_SERVICE, "Init usb function switch window failed");
69     }
70     return ret;
71 }
72 
SetUsbd(const sptr<IUsbInterface> & usbd)73 int32_t UsbDeviceManager::SetUsbd(const sptr<IUsbInterface> &usbd)
74 {
75     if (usbd == nullptr) {
76         USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager usbd is nullptr");
77         return UEC_SERVICE_INVALID_VALUE;
78     }
79     usbd_ = usbd;
80     return UEC_OK;
81 }
82 
AreSettableFunctions(int32_t funcs)83 bool UsbDeviceManager::AreSettableFunctions(int32_t funcs)
84 {
85     return static_cast<uint32_t>(funcs) == UsbSrvSupport::FUNCTION_NONE ||
86         ((~functionSettable_ & static_cast<uint32_t>(funcs)) == 0);
87 }
88 
ConvertFromString(std::string_view strFun)89 uint32_t UsbDeviceManager::ConvertFromString(std::string_view strFun)
90 {
91     if (strFun == UsbSrvSupport::FUNCTION_NAME_NONE) {
92         return UsbSrvSupport::FUNCTION_NONE;
93     }
94 
95     size_t len = strFun.length();
96     if (len == 0) {
97         return UEC_SERVICE_INVALID_VALUE;
98     }
99 
100     std::vector<std::string_view> vModeStr;
101     size_t pos = 0;
102     while (pos < len) {
103         size_t findPos = strFun.find(",", pos);
104         if (findPos == strFun.npos) {
105             vModeStr.push_back(strFun.substr(pos, len - pos));
106             break;
107         }
108         vModeStr.push_back(strFun.substr(pos, findPos - pos));
109         pos = findPos + 1;
110     }
111 
112     uint32_t ret = 0;
113     for (auto &&item : vModeStr) {
114         auto it = FUNCTION_MAPPING_N2C.find(item);
115         if (it != FUNCTION_MAPPING_N2C.end()) {
116             ret |= it->second;
117         } else {
118             USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager::ConvertFromString Invalid argument of usb function");
119             return UEC_SERVICE_INVALID_VALUE;
120         }
121     }
122 
123     return ret;
124 }
125 
ConvertToString(uint32_t function)126 std::string UsbDeviceManager::ConvertToString(uint32_t function)
127 {
128     std::string stream;
129     if (function <= UsbSrvSupport::FUNCTION_NONE || function > functionSettable_) {
130         stream = std::string {UsbSrvSupport::FUNCTION_NAME_NONE};
131         return stream;
132     }
133     bool flag = false;
134     for (auto it = FUNCTION_MAPPING_N2C.begin(); it != FUNCTION_MAPPING_N2C.end(); ++it) {
135         if ((function & it->second) != 0) {
136             if (flag) {
137                 stream += ",";
138             }
139             stream += std::string {it->first};
140             flag = true;
141         }
142     }
143     USB_HILOGI(MODULE_USB_SERVICE, "UsbDeviceManager::ConvertToString success");
144     return stream;
145 }
146 
UpdateFunctions(int32_t func)147 void UsbDeviceManager::UpdateFunctions(int32_t func)
148 {
149     ReportFuncChangeSysEvent(currentFunctions_, func);
150     currentFunctions_ = func;
151 }
152 
GetCurrentFunctions()153 int32_t UsbDeviceManager::GetCurrentFunctions()
154 {
155     return currentFunctions_;
156 }
157 
HandleEvent(int32_t status)158 void UsbDeviceManager::HandleEvent(int32_t status)
159 {
160     if (usbd_ == nullptr) {
161         USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager::usbd_ is nullptr");
162         return;
163     }
164     bool curConnect = false;
165     switch (status) {
166         case ACT_UPDEVICE: {
167             curConnect = true;
168             gadgetConnected_ = true;
169             break;
170         }
171         case ACT_DOWNDEVICE: {
172             curConnect = false;
173             gadgetConnected_ = false;
174             break;
175         }
176         default:
177             USB_HILOGE(MODULE_USB_SERVICE, "invalid status %{public}d", status);
178             curConnect = false;
179     }
180     delayDisconn_.Unregister(delayDisconnTimerId_);
181     delayDisconn_.Shutdown();
182     if (curConnect && (connected_ != curConnect)) {
183         connected_ = curConnect;
184         usbd_->GetCurrentFunctions(currentFunctions_);
185         ProcessFuncChange(connected_, currentFunctions_);
186     } else if (!curConnect && (connected_ != curConnect)) {
187         auto task = [&]() {
188             connected_ = false;
189             ProcessFuncChange(connected_, currentFunctions_);
190             return;
191         };
192         auto ret = delayDisconn_.Setup();
193         if (ret != UEC_OK) {
194             USB_HILOGE(MODULE_USB_SERVICE, "set up timer failed %{public}u", ret);
195             return;
196         }
197         delayDisconnTimerId_ = delayDisconn_.Register(task, DELAY_DISCONN_INTERVAL, true);
198     } else {
199         USB_HILOGI(MODULE_USB_SERVICE, "else info cur status %{public}d, bconnected: %{public}d", status, connected_);
200     }
201 }
202 
ProcessFuncChange(bool connected,int32_t currentFunc)203 void UsbDeviceManager::ProcessFuncChange(bool connected, int32_t currentFunc)
204 {
205     USB_HILOGI(MODULE_USB_SERVICE, "Current Connect %{public}d,bconnected: %{public}d", connected, currentFunc);
206     Want want;
207     want.SetAction(CommonEventSupport::COMMON_EVENT_USB_STATE);
208 
209     want.SetParam(std::string {UsbSrvSupport::CONNECTED}, connected);
210     uint32_t remainderFunc = static_cast<uint32_t>(currentFunc);
211     // start from bit 1
212     uint32_t bit = 1;
213     while (remainderFunc != 0) {
214         if (remainderFunc & bit) {
215             want.SetParam(ConvertToString(bit), true);
216             // set current bit to zero
217             remainderFunc &= ~bit;
218         }
219         // 1 means to next bit
220         bit = bit << 1;
221     }
222     CommonEventData data(want);
223     CommonEventPublishInfo publishInfo;
224     USB_HILOGI(MODULE_SERVICE, "send COMMON_EVENT_USB_STATE broadcast connected:%{public}d, "
225         "currentFunctions:%{public}d", connected, currentFunc);
226     CommonEventManager::PublishCommonEvent(data, publishInfo);
227     ReportDevicePlugSysEvent(currentFunc, connected);
228     ProcessFunctionSwitchWindow(connected);
229 }
230 
ProcessFunctionSwitchWindow(bool connected)231 void UsbDeviceManager::ProcessFunctionSwitchWindow(bool connected)
232 {
233     std::shared_ptr<UsbFunctionSwitchWindow> window_ = UsbFunctionSwitchWindow::GetInstance();
234     if (window_ == nullptr) {
235         USB_HILOGE(MODULE_USB_SERVICE, "show window: get usb function switch window failed");
236         return;
237     }
238 
239     if (connected) {
240         USB_HILOGD(MODULE_USB_SERVICE, "start pop up usb service switch window");
241         if (!window_->PopUpFunctionSwitchWindow()) {
242             USB_HILOGE(MODULE_USB_SERVICE, "start pop up usb service switch window failed");
243         }
244     } else {
245         USB_HILOGD(MODULE_USB_SERVICE, "start dismiss usb service switch window");
246         if (!window_->DismissFunctionSwitchWindow()) {
247             USB_HILOGE(MODULE_USB_SERVICE, "start dismiss usb service switch window failed");
248         }
249     }
250 }
251 
GetDumpHelp(int32_t fd)252 void UsbDeviceManager::GetDumpHelp(int32_t fd)
253 {
254     dprintf(fd, "========= dump the all device function =========\n");
255     dprintf(fd, "usb_device -a:    Query all function\n");
256     dprintf(fd, "usb_device -f Q:  Query Current function\n");
257     dprintf(fd, "usb_device -f 0:  Switch to function:none\n");
258     dprintf(fd, "usb_device -f 1:  Switch to function:acm\n");
259     dprintf(fd, "usb_device -f 2:  Switch to function:ecm\n");
260     dprintf(fd, "usb_device -f 3:  Switch to function:acm&ecm\n");
261     dprintf(fd, "usb_device -f 4:  Switch to function:hdc\n");
262     dprintf(fd, "usb_device -f 5:  Switch to function:acm&hdc\n");
263     dprintf(fd, "usb_device -f 6:  Switch to function:ecm&hdc\n");
264     dprintf(fd, "usb_device -f 32: Switch to function:rndis\n");
265     dprintf(fd, "usb_device -f 512:Switch to function:storage\n");
266     dprintf(fd, "usb_device -f 36: Switch to function:rndis&hdc\n");
267     dprintf(fd, "usb_device -f 516:Switch to function:storage&hdc\n");
268     dprintf(fd, "------------------------------------------------\n");
269 }
270 
DumpGetSupportFunc(int32_t fd)271 void UsbDeviceManager::DumpGetSupportFunc(int32_t fd)
272 {
273     dprintf(fd, "Usb Device function list info:\n");
274     dprintf(fd, "current function: %s\n", ConvertToString(currentFunctions_).c_str());
275     dprintf(fd, "supported functions list: %s\n", ConvertToString(functionSettable_).c_str());
276 }
277 
DumpSetFunc(int32_t fd,const std::string & args)278 void UsbDeviceManager::DumpSetFunc(int32_t fd, const std::string &args)
279 {
280     int32_t currentFunction;
281     int32_t ret;
282     if (usbd_ == nullptr) {
283         USB_HILOGE(MODULE_USB_SERVICE, "UsbDeviceManager::DumpSetFunc usbd_ is nullptr");
284         return;
285     }
286     if (args.compare("Q") == 0) {
287         ret = usbd_->GetCurrentFunctions(currentFunction);
288         if (ret != UEC_OK) {
289             dprintf(fd, "GetCurrentFunctions failed: %d\n", __LINE__);
290             return;
291         }
292         dprintf(fd, "current function: %s\n", ConvertToString(currentFunction).c_str());
293         return;
294     }
295 
296     int32_t mode = stoi(args);
297     ret = usbd_->SetCurrentFunctions(mode);
298     if (ret != UEC_OK) {
299         dprintf(fd, "SetCurrentFunctions failed");
300         return;
301     }
302     ret = usbd_->GetCurrentFunctions(currentFunction);
303     if (ret != UEC_OK) {
304         dprintf(fd, "GetCurrentFunctions failed: %d\n", __LINE__);
305         return;
306     }
307 
308     dprintf(fd, "current function: %s\n", ConvertToString(currentFunction).c_str());
309 }
310 
Dump(int32_t fd,const std::vector<std::string> & args)311 void UsbDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args)
312 {
313     if (args.size() < PARAM_COUNT_TWO || args.size() > PARAM_COUNT_THR) {
314         GetDumpHelp(fd);
315         return;
316     }
317 
318     if (args[CMD_INDEX] == "-a" && args.size() == PARAM_COUNT_TWO) {
319         DumpGetSupportFunc(fd);
320     } else if (args[CMD_INDEX] == "-f" && args.size() == PARAM_COUNT_THR) {
321         DumpSetFunc(fd, args[PARAM_INDEX]);
322     } else {
323         dprintf(fd, "func param error, please enter again\n");
324         GetDumpHelp(fd);
325     }
326 }
327 
ReportFuncChangeSysEvent(int32_t currentFunctions,int32_t updateFunctions)328 void UsbDeviceManager::ReportFuncChangeSysEvent(int32_t currentFunctions, int32_t updateFunctions)
329 {
330     USB_HILOGI(MODULE_USB_SERVICE, "Device function Indicates the switch point information:");
331     HiSysEventWrite(HiSysEvent::Domain::USB, "FUNCTION_CHANGED",
332         HiSysEvent::EventType::BEHAVIOR, "CURRENT_FUNCTION",
333         currentFunctions_, "UPDATE_FUNCTION", updateFunctions);
334 }
335 
ReportDevicePlugSysEvent(int32_t currentFunctions,bool connected)336 void UsbDeviceManager::ReportDevicePlugSysEvent(int32_t currentFunctions, bool connected)
337 {
338     USB_HILOGI(MODULE_USB_SERVICE, "Device mode Indicates the insertion and removal information:");
339     HiSysEventWrite(HiSysEvent::Domain::USB, "PLUG_IN_OUT_DEVICE_MODE",
340         HiSysEvent::EventType::BEHAVIOR, "CURRENT_FUNCTIONS",
341         currentFunctions, "CONNECTED", connected);
342 }
IsGadgetConnected(void)343 bool UsbDeviceManager::IsGadgetConnected(void)
344 {
345     return gadgetConnected_;
346 }
347 } // namespace USB
348 } // namespace OHOS
349