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