1 /*
2 * Copyright (c) 2024 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 "input_device_mgr.h"
17
18 #include "device.h"
19 #include "devicestatus_define.h"
20 #include "utility.h"
21
22 #undef LOG_TAG
23 #define LOG_TAG "InputDeviceMgr"
24
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace Cooperate {
29 constexpr size_t MAX_INPUT_DEV_PER_DEVICE { 10 };
30 namespace {
31 const std::string VIRTUAL_TRACK_PAD_NAME { "VirtualTrackpad" }; // defined in multimodalinput
32 }
33
InputDeviceMgr(IContext * context)34 InputDeviceMgr::InputDeviceMgr(IContext *context) : env_(context) {}
35
Enable(Channel<CooperateEvent>::Sender sender)36 void InputDeviceMgr::Enable(Channel<CooperateEvent>::Sender sender)
37 {
38 CALL_INFO_TRACE;
39 if (enable_) {
40 return;
41 }
42 FI_HILOGI("Enable InputDeviceMgr");
43 enable_ = true;
44 sender_ = sender;
45 }
46
Disable()47 void InputDeviceMgr::Disable()
48 {
49 CALL_INFO_TRACE;
50 if (enable_) {
51 enable_ = false;
52 }
53 FI_HILOGI("Disable InputDeviceMgr");
54 }
55
OnSoftbusSessionOpened(const DSoftbusSessionOpened & notice)56 void InputDeviceMgr::OnSoftbusSessionOpened(const DSoftbusSessionOpened ¬ice)
57 {
58 CALL_INFO_TRACE;
59 NotifyInputDeviceToRemote(notice.networkId);
60 }
61
OnSoftbusSessionClosed(const DSoftbusSessionClosed & notice)62 void InputDeviceMgr::OnSoftbusSessionClosed(const DSoftbusSessionClosed ¬ice)
63 {
64 CALL_INFO_TRACE;
65 RemoveAllRemoteInputDevice(notice.networkId);
66 }
67
OnLocalHotPlug(const InputHotplugEvent & notice)68 void InputDeviceMgr::OnLocalHotPlug(const InputHotplugEvent ¬ice)
69 {
70 CALL_INFO_TRACE;
71 BroadcastHotPlugToRemote(notice);
72 }
73
OnRemoteInputDevice(const DSoftbusSyncInputDevice & notice)74 void InputDeviceMgr::OnRemoteInputDevice(const DSoftbusSyncInputDevice ¬ice)
75 {
76 CALL_INFO_TRACE;
77 std::string networkId = notice.networkId;
78 for (const auto &device : notice.devices) {
79 DispDeviceInfo(device);
80 AddRemoteInputDevice(networkId, device);
81 }
82 }
83
OnRemoteHotPlug(const DSoftbusHotPlugEvent & notice)84 void InputDeviceMgr::OnRemoteHotPlug(const DSoftbusHotPlugEvent ¬ice)
85 {
86 CALL_INFO_TRACE;
87 }
88
AddVirtualInputDevice(const std::string & networkId)89 void InputDeviceMgr::AddVirtualInputDevice(const std::string &networkId)
90 {
91 CALL_INFO_TRACE;
92 FI_HILOGI("Add virtual device from %{public}s", Utility::Anonymize(networkId).c_str());
93 for (const auto &device : remoteDevices_[networkId]) {
94 CHKPC(device);
95 AddVirtualInputDevice(networkId, device->GetId());
96 }
97 }
98
RemoveVirtualInputDevice(const std::string & networkId)99 void InputDeviceMgr::RemoveVirtualInputDevice(const std::string &networkId)
100 {
101 CALL_INFO_TRACE;
102 FI_HILOGI("Remove virtual device from %{public}s", Utility::Anonymize(networkId).c_str());
103 for (const auto &device : remoteDevices_[networkId]) {
104 CHKPC(device);
105 RemoveVirtualInputDevice(networkId, device->GetId());
106 }
107 }
108
HandleRemoteHotPlug(const DSoftbusHotPlugEvent & notice)109 void InputDeviceMgr::HandleRemoteHotPlug(const DSoftbusHotPlugEvent ¬ice)
110 {
111 CALL_INFO_TRACE;
112 CHKPV(notice.device);
113 auto remoteDeviceId = notice.device->GetId();
114 if (notice.type == InputHotplugType::UNPLUG) {
115 if (remote2VirtualIds_.find(remoteDeviceId) == remote2VirtualIds_.end()) {
116 FI_HILOGI("No virtual matches remote deviceId:%{public}d", remoteDeviceId);
117 return;
118 }
119 RemoveVirtualInputDevice(notice.networkId, remoteDeviceId);
120 }
121 if (notice.type == InputHotplugType::PLUG) {
122 AddVirtualInputDevice(notice.networkId, remoteDeviceId);
123 }
124 }
125
NotifyInputDeviceToRemote(const std::string & remoteNetworkId)126 void InputDeviceMgr::NotifyInputDeviceToRemote(const std::string &remoteNetworkId)
127 {
128 CALL_INFO_TRACE;
129 auto virTrackPads = env_->GetDeviceManager().GetVirTrackPad();
130 if ((virTrackPads.size() == 0) &&
131 (!env_->GetDeviceManager().HasKeyboard() && !env_->GetDeviceManager().HasLocalPointerDevice())) {
132 FI_HILOGE("Local device have no keyboard or pointer device, skip");
133 return;
134 }
135 auto keyboards = env_->GetDeviceManager().GetKeyboard();
136 auto pointerDevices = env_->GetDeviceManager().GetPointerDevice();
137 NetPacket packet(MessageId::DSOFTBUS_INPUT_DEV_SYNC);
138 FI_HILOGI("Num: keyboard:%{public}zu, pointerDevice:%{public}zu, virTrackPads:%{public}zu",
139 keyboards.size(), pointerDevices.size(), virTrackPads.size());
140 int32_t inputDeviceNum = static_cast<int32_t>(keyboards.size() + pointerDevices.size() + virTrackPads.size());
141 packet << inputDeviceNum;
142 for (const auto &keyboard : keyboards) {
143 if (SerializeDevice(keyboard, packet) != RET_OK) {
144 FI_HILOGE("Serialize keyboard failed");
145 return;
146 }
147 DispDeviceInfo(keyboard);
148 }
149 for (const auto &pointerDevice : pointerDevices) {
150 if (SerializeDevice(pointerDevice, packet) != RET_OK) {
151 FI_HILOGE("Serialize pointer device failed");
152 return;
153 }
154 DispDeviceInfo(pointerDevice);
155 }
156 if (virTrackPads.size() > 0) {
157 for (const auto &virTrackPad : virTrackPads) {
158 if (SerializeDevice(virTrackPad, packet) != RET_OK) {
159 FI_HILOGE("Serialize virTrackPad failed");
160 return;
161 }
162 DispDeviceInfo(virTrackPad);
163 }
164 }
165 if (int32_t ret = env_->GetDSoftbus().SendPacket(remoteNetworkId, packet); ret != RET_OK) {
166 FI_HILOGE("SenPacket to networkId:%{public}s failed, ret:%{public}d",
167 Utility::Anonymize(remoteNetworkId).c_str(), ret);
168 return;
169 }
170 FI_HILOGI("NotifyInputDeviceToRemote networkId:%{public}s", Utility::Anonymize(remoteNetworkId).c_str());
171 }
172
BroadcastHotPlugToRemote(const InputHotplugEvent & notice)173 void InputDeviceMgr::BroadcastHotPlugToRemote(const InputHotplugEvent ¬ice)
174 {
175 CALL_INFO_TRACE;
176 FI_HILOGI("HotplugType%{public}d deviceId:%{public}d", static_cast<int32_t>(notice.type), notice.deviceId);
177 if (!notice.isKeyboard) {
178 FI_HILOGI("Not keyboard, skip");
179 return;
180 }
181 NetPacket packet(MessageId::DSOFTBUS_INPUT_DEV_HOT_PLUG);
182 packet << static_cast<int32_t>(notice.type);
183 if (notice.type == InputHotplugType::PLUG) {
184 auto device = env_->GetDeviceManager().GetDevice(notice.deviceId);
185 CHKPV(device);
186 DispDeviceInfo(device);
187 if (SerializeDevice(device, packet) != RET_OK) {
188 FI_HILOGE("SerializeDevice failed");
189 return;
190 }
191 }
192 if (notice.type == InputHotplugType::UNPLUG) {
193 packet << notice.deviceId;
194 if (packet.ChkRWError()) {
195 FI_HILOGE("Write packet failed");
196 return;
197 }
198 }
199 if (int32_t ret = env_->GetDSoftbus().BroadcastPacket(packet); ret != RET_OK) {
200 FI_HILOGE("BroadcastPacket failed");
201 return;
202 }
203 }
204
RemoveRemoteInputDevice(const std::string & networkId,std::shared_ptr<IDevice> device)205 void InputDeviceMgr::RemoveRemoteInputDevice(const std::string &networkId, std::shared_ptr<IDevice> device)
206 {
207 CALL_INFO_TRACE;
208 if (remoteDevices_.find(networkId) == remoteDevices_.end()) {
209 FI_HILOGE("NetworkId:%{public}s have no device existed", Utility::Anonymize(networkId).c_str());
210 return;
211 }
212 DispDeviceInfo(device);
213 remoteDevices_[networkId].erase(device);
214 }
215
AddRemoteInputDevice(const std::string & networkId,std::shared_ptr<IDevice> device)216 void InputDeviceMgr::AddRemoteInputDevice(const std::string &networkId, std::shared_ptr<IDevice> device)
217 {
218 CALL_INFO_TRACE;
219 DispDeviceInfo(device);
220 if (remoteDevices_.find(networkId) != remoteDevices_.end() &&
221 remoteDevices_[networkId].size() >= MAX_INPUT_DEV_PER_DEVICE) {
222 FI_HILOGE("Input device num from networkId:%{public}s exceeds limit", Utility::Anonymize(networkId).c_str());
223 return;
224 }
225 remoteDevices_[networkId].insert(device);
226 }
227
RemoveAllRemoteInputDevice(const std::string & networkId)228 void InputDeviceMgr::RemoveAllRemoteInputDevice(const std::string &networkId)
229 {
230 CALL_INFO_TRACE;
231 if (virtualInputDevicesAdded_.find(networkId) != virtualInputDevicesAdded_.end()) {
232 FI_HILOGI("NetworkId:%{public}s has device added as virtual one already, remove all",
233 Utility::Anonymize(networkId).c_str());
234 RemoveVirtualInputDevice(networkId);
235 }
236 if (remoteDevices_.find(networkId) == remoteDevices_.end()) {
237 FI_HILOGE("NetworkId:%{public}s have no device existed", Utility::Anonymize(networkId).c_str());
238 return;
239 }
240 remoteDevices_.erase(networkId);
241 }
242
DispDeviceInfo(std::shared_ptr<IDevice> device)243 void InputDeviceMgr::DispDeviceInfo(std::shared_ptr<IDevice> device)
244 {
245 CHKPV(device);
246 FI_HILOGI(" device %{public}d:%{private}s", device->GetId(), device->GetDevPath().c_str());
247 FI_HILOGI(" sysPath: \"%{private}s\"", device->GetSysPath().c_str());
248 FI_HILOGI(" bus: %{public}04x", device->GetBus());
249 FI_HILOGI(" vendor: %{public}04x", device->GetVendor());
250 FI_HILOGI(" product: %{public}04x", device->GetProduct());
251 FI_HILOGI(" version: %{public}04x", device->GetVersion());
252 FI_HILOGI(" name: \"%{public}s\"", device->GetName().c_str());
253 FI_HILOGI(" location: \"%{public}s\"", device->GetPhys().c_str());
254 FI_HILOGI(" unique id: \"%{private}s\"", device->GetUniq().c_str());
255 FI_HILOGI(" is pointer: %{public}s, is keyboard:%{public}s",
256 device->IsPointerDevice() ? "True" : "False", device->IsKeyboard() ? "True" : "False");
257 }
258
DumpRemoteInputDevice(const std::string & networkId)259 void InputDeviceMgr::DumpRemoteInputDevice(const std::string &networkId)
260 {
261 CALL_INFO_TRACE;
262 if (remoteDevices_.find(networkId) == remoteDevices_.end()) {
263 FI_HILOGE("NetworkId:%{public}s have no device existed", Utility::Anonymize(networkId).c_str());
264 return;
265 }
266 FI_HILOGI("NetworkId%{public}s, device mount:%{public}zu", Utility::Anonymize(networkId).c_str(),
267 remoteDevices_.size());
268 for (const auto &elem : remoteDevices_[networkId]) {
269 FI_HILOGI("DeviceId:%{public}d, deviceName:%{public}s", elem->GetId(), elem->GetName().c_str());
270 }
271 }
272
SerializeDevice(std::shared_ptr<IDevice> device,NetPacket & packet)273 int32_t InputDeviceMgr::SerializeDevice(std::shared_ptr<IDevice> device, NetPacket &packet)
274 {
275 CALL_INFO_TRACE;
276 packet << device->GetId() << device->GetDevPath() << device->GetSysPath() << device->GetBus() <<
277 device->GetVendor() << device->GetProduct() << device->GetVersion() << device->GetName() <<
278 device->GetPhys() << device->GetUniq() << device->IsPointerDevice() << device->IsKeyboard() <<
279 static_cast<int32_t> (device->GetKeyboardType());
280 if (packet.ChkRWError()) {
281 FI_HILOGE("Write packet failed");
282 return RET_ERR;
283 }
284 return RET_OK;
285 }
286
Transform(std::shared_ptr<IDevice> device)287 std::shared_ptr<MMI::InputDevice> InputDeviceMgr::Transform(std::shared_ptr<IDevice> device)
288 {
289 CALL_DEBUG_ENTER;
290 CHKPP(device);
291 auto inputDevice = std::make_shared<MMI::InputDevice>();
292 inputDevice->SetId(device->GetId());
293 inputDevice->SetName(device->GetName());
294 inputDevice->SetBus(device->GetBus());
295 inputDevice->SetVersion(device->GetVersion());
296 inputDevice->SetProduct(device->GetProduct());
297 inputDevice->SetVendor(device->GetVendor());
298 inputDevice->SetPhys(device->GetPhys());
299 inputDevice->SetUniq(device->GetUniq());
300 if (device->IsKeyboard()) {
301 inputDevice->AddCapability(MMI::InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
302 }
303 if (device->IsPointerDevice()) {
304 inputDevice->AddCapability(MMI::InputDeviceCapability::INPUT_DEV_CAP_POINTER);
305 }
306 if (device->GetName() == VIRTUAL_TRACK_PAD_NAME) {
307 inputDevice->AddCapability(MMI::InputDeviceCapability::INPUT_DEV_CAP_POINTER);
308 inputDevice->AddCapability(MMI::InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
309 }
310 return inputDevice;
311 }
312
AddVirtualInputDevice(const std::string & networkId,int32_t remoteDeviceId)313 void InputDeviceMgr::AddVirtualInputDevice(const std::string &networkId, int32_t remoteDeviceId)
314 {
315 CALL_INFO_TRACE;
316 if (remote2VirtualIds_.find(remoteDeviceId) != remote2VirtualIds_.end()) {
317 FI_HILOGW("Remote device:%{public}d already added as virtual device:%{public}d",
318 remoteDeviceId, remote2VirtualIds_[remoteDeviceId]);
319 return;
320 }
321 auto device = GetRemoteDeviceById(networkId, remoteDeviceId);
322 CHKPV(device);
323 int32_t virtualDeviceId = -1;
324 if (env_->GetInput().AddVirtualInputDevice(Transform(device), virtualDeviceId) != RET_OK) {
325 FI_HILOGE("Add virtual device failed, remoteDeviceId:%{public}d, name:%{public}s", remoteDeviceId,
326 device->GetName().c_str());
327 return;
328 }
329 virtualInputDevicesAdded_[networkId].insert(virtualDeviceId);
330 remote2VirtualIds_[remoteDeviceId] = virtualDeviceId;
331 FI_HILOGI("Add virtual device success, virtualDeviceId:%{public}d", virtualDeviceId);
332 UpdateVirtualDeviceIdMap();
333 }
334
RemoveVirtualInputDevice(const std::string & networkId,int32_t remoteDeviceId)335 void InputDeviceMgr::RemoveVirtualInputDevice(const std::string &networkId, int32_t remoteDeviceId)
336 {
337 CALL_INFO_TRACE;
338 if (remote2VirtualIds_.find(remoteDeviceId) == remote2VirtualIds_.end()) {
339 FI_HILOGE("No remote device from networkId%{public}s with id:%{public}d",
340 Utility::Anonymize(networkId).c_str(), remoteDeviceId);
341 return;
342 }
343 auto virtualDeviceId = remote2VirtualIds_[remoteDeviceId];
344 if (env_->GetInput().RemoveVirtualInputDevice(virtualDeviceId) != RET_OK) {
345 FI_HILOGE("Remove virtual device failed, virtualDeviceId:%{public}d", virtualDeviceId);
346 return;
347 }
348 virtualInputDevicesAdded_[networkId].erase(virtualDeviceId);
349 remote2VirtualIds_.erase(remoteDeviceId);
350 FI_HILOGI("Remove virtual device success, virtualDeviceId:%{public}d", virtualDeviceId);
351 UpdateVirtualDeviceIdMap();
352 }
353
GetRemoteDeviceById(const std::string & networkId,int32_t remoteDeviceId)354 std::shared_ptr<IDevice> InputDeviceMgr::GetRemoteDeviceById(const std::string &networkId, int32_t remoteDeviceId)
355 {
356 std::shared_ptr<IDevice> dev = std::make_shared<Device>(remoteDeviceId);
357 if (remoteDevices_.find(networkId) == remoteDevices_.end()) {
358 FI_HILOGE("No remoteDevice from networkId:%{public}s", Utility::Anonymize(networkId).c_str());
359 return nullptr;
360 }
361 if (auto iter = remoteDevices_[networkId].find(dev); iter != remoteDevices_[networkId].end()) {
362 return *iter;
363 }
364 FI_HILOGW("No remote device with deviceId:%{public}d", remoteDeviceId);
365 return nullptr;
366 }
367
UpdateVirtualDeviceIdMap()368 void InputDeviceMgr::UpdateVirtualDeviceIdMap()
369 {
370 CALL_INFO_TRACE;
371 auto ret = sender_.Send(CooperateEvent(
372 CooperateEventType::UPDATE_VIRTUAL_DEV_ID_MAP,
373 UpdateVirtualDeviceIdMapEvent {
374 remote2VirtualIds_
375 }));
376 if (ret != Channel<CooperateEvent>::NO_ERROR) {
377 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
378 }
379 }
380 } // namespace Cooperate
381 } // namespace DeviceStatus
382 } // namespace Msdp
383 } // namespace OHOS
384