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