• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &notice)
57 {
58     CALL_INFO_TRACE;
59     NotifyInputDeviceToRemote(notice.networkId);
60 }
61 
OnSoftbusSessionClosed(const DSoftbusSessionClosed & notice)62 void InputDeviceMgr::OnSoftbusSessionClosed(const DSoftbusSessionClosed &notice)
63 {
64     CALL_INFO_TRACE;
65     RemoveAllRemoteInputDevice(notice.networkId);
66 }
67 
OnLocalHotPlug(const InputHotplugEvent & notice)68 void InputDeviceMgr::OnLocalHotPlug(const InputHotplugEvent &notice)
69 {
70     CALL_INFO_TRACE;
71     BroadcastHotPlugToRemote(notice);
72 }
73 
OnRemoteInputDevice(const DSoftbusSyncInputDevice & notice)74 void InputDeviceMgr::OnRemoteInputDevice(const DSoftbusSyncInputDevice &notice)
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 &notice)
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 
RemoveAllVirtualInputDevice()109 void InputDeviceMgr::RemoveAllVirtualInputDevice()
110 {
111     CALL_INFO_TRACE;
112     for (const auto& [key, deviceSet] : remoteDevices_) {
113         for (const auto &device : deviceSet) {
114             CHKPC(device);
115             FI_HILOGI("Remove virtual device from %{public}s", Utility::Anonymize(key).c_str());
116             RemoveVirtualInputDevice(key, device->GetId());
117         }
118     }
119 }
120 
HandleRemoteHotPlug(const DSoftbusHotPlugEvent & notice)121 void InputDeviceMgr::HandleRemoteHotPlug(const DSoftbusHotPlugEvent &notice)
122 {
123     CALL_INFO_TRACE;
124     CHKPV(notice.device);
125     auto remoteDeviceId = notice.device->GetId();
126     if (notice.type == InputHotplugType::UNPLUG) {
127         if (remote2VirtualIds_.find(remoteDeviceId) == remote2VirtualIds_.end()) {
128             FI_HILOGI("No virtual matches remote deviceId:%{public}d", remoteDeviceId);
129             return;
130         }
131         RemoveVirtualInputDevice(notice.networkId, remoteDeviceId);
132     }
133     if (notice.type == InputHotplugType::PLUG) {
134         AddVirtualInputDevice(notice.networkId, remoteDeviceId);
135     }
136 }
137 
NotifyInputDeviceToRemote(const std::string & remoteNetworkId)138 void InputDeviceMgr::NotifyInputDeviceToRemote(const std::string &remoteNetworkId)
139 {
140     CALL_INFO_TRACE;
141     CHKPV(env_);
142     auto virTrackPads = env_->GetDeviceManager().GetVirTrackPad();
143     if ((virTrackPads.size() == 0) &&
144         (!env_->GetDeviceManager().HasKeyboard() && !env_->GetDeviceManager().HasLocalPointerDevice())) {
145         FI_HILOGE("Local device have no keyboard or pointer device, skip");
146         return;
147     }
148     auto keyboards = env_->GetDeviceManager().GetKeyboard();
149     auto pointerDevices =  env_->GetDeviceManager().GetPointerDevice();
150     NetPacket packet(MessageId::DSOFTBUS_INPUT_DEV_SYNC);
151     FI_HILOGI("Num: keyboard:%{public}zu, pointerDevice:%{public}zu, virTrackPads:%{public}zu",
152         keyboards.size(), pointerDevices.size(), virTrackPads.size());
153     int32_t inputDeviceNum = static_cast<int32_t>(keyboards.size() + pointerDevices.size() + virTrackPads.size());
154     packet << inputDeviceNum;
155     for (const auto &keyboard : keyboards) {
156         if (SerializeDevice(keyboard, packet) != RET_OK) {
157             FI_HILOGE("Serialize keyboard failed");
158             return;
159         }
160         DispDeviceInfo(keyboard);
161     }
162     for (const auto &pointerDevice : pointerDevices) {
163         if (SerializeDevice(pointerDevice, packet) != RET_OK) {
164             FI_HILOGE("Serialize pointer device failed");
165             return;
166         }
167         DispDeviceInfo(pointerDevice);
168     }
169     if (virTrackPads.size() > 0) {
170         for (const auto &virTrackPad : virTrackPads) {
171             if (SerializeDevice(virTrackPad, packet) != RET_OK) {
172                 FI_HILOGE("Serialize virTrackPad failed");
173                 return;
174             }
175             DispDeviceInfo(virTrackPad);
176         }
177     }
178     if (int32_t ret = env_->GetDSoftbus().SendPacket(remoteNetworkId, packet); ret != RET_OK) {
179         FI_HILOGE("SenPacket to networkId:%{public}s failed, ret:%{public}d",
180             Utility::Anonymize(remoteNetworkId).c_str(), ret);
181         return;
182     }
183     FI_HILOGI("NotifyInputDeviceToRemote networkId:%{public}s", Utility::Anonymize(remoteNetworkId).c_str());
184 }
185 
BroadcastHotPlugToRemote(const InputHotplugEvent & notice)186 void InputDeviceMgr::BroadcastHotPlugToRemote(const InputHotplugEvent &notice)
187 {
188     CALL_INFO_TRACE;
189     CHKPV(env_);
190     FI_HILOGI("HotplugType%{public}d deviceId:%{public}d", static_cast<int32_t>(notice.type), notice.deviceId);
191     if (!notice.isKeyboard) {
192         FI_HILOGI("Not keyboard, skip");
193         return;
194     }
195     NetPacket packet(MessageId::DSOFTBUS_INPUT_DEV_HOT_PLUG);
196     packet << static_cast<int32_t>(notice.type);
197     if (notice.type == InputHotplugType::PLUG) {
198         auto device = env_->GetDeviceManager().GetDevice(notice.deviceId);
199         CHKPV(device);
200         DispDeviceInfo(device);
201         if (SerializeDevice(device, packet) != RET_OK) {
202             FI_HILOGE("SerializeDevice failed");
203             return;
204         }
205     }
206     if (notice.type == InputHotplugType::UNPLUG) {
207         packet << notice.deviceId;
208         if (packet.ChkRWError()) {
209             FI_HILOGE("Write packet failed");
210             return;
211         }
212     }
213     if (int32_t ret = env_->GetDSoftbus().BroadcastPacket(packet); ret != RET_OK) {
214         FI_HILOGE("BroadcastPacket failed");
215         return;
216     }
217 }
218 
RemoveRemoteInputDevice(const std::string & networkId,std::shared_ptr<IDevice> device)219 void InputDeviceMgr::RemoveRemoteInputDevice(const std::string &networkId, std::shared_ptr<IDevice> device)
220 {
221     CALL_INFO_TRACE;
222     if (remoteDevices_.find(networkId) == remoteDevices_.end()) {
223         FI_HILOGE("NetworkId:%{public}s have no device existed", Utility::Anonymize(networkId).c_str());
224         return;
225     }
226     DispDeviceInfo(device);
227     remoteDevices_[networkId].erase(device);
228 }
229 
AddRemoteInputDevice(const std::string & networkId,std::shared_ptr<IDevice> device)230 void InputDeviceMgr::AddRemoteInputDevice(const std::string &networkId, std::shared_ptr<IDevice> device)
231 {
232     CALL_INFO_TRACE;
233     DispDeviceInfo(device);
234     if (remoteDevices_.find(networkId) != remoteDevices_.end() &&
235         remoteDevices_[networkId].size() >= MAX_INPUT_DEV_PER_DEVICE) {
236         FI_HILOGE("Input device num from networkId:%{public}s exceeds limit", Utility::Anonymize(networkId).c_str());
237         return;
238     }
239     remoteDevices_[networkId].insert(device);
240 }
241 
RemoveAllRemoteInputDevice(const std::string & networkId)242 void InputDeviceMgr::RemoveAllRemoteInputDevice(const std::string &networkId)
243 {
244     CALL_INFO_TRACE;
245     if (virtualInputDevicesAdded_.find(networkId) != virtualInputDevicesAdded_.end()) {
246         FI_HILOGI("NetworkId:%{public}s has device added as virtual one already, remove all",
247             Utility::Anonymize(networkId).c_str());
248         RemoveVirtualInputDevice(networkId);
249     }
250     if (remoteDevices_.find(networkId) == remoteDevices_.end()) {
251         FI_HILOGE("NetworkId:%{public}s have no device existed", Utility::Anonymize(networkId).c_str());
252         return;
253     }
254     remoteDevices_.erase(networkId);
255 }
256 
DispDeviceInfo(std::shared_ptr<IDevice> device)257 void InputDeviceMgr::DispDeviceInfo(std::shared_ptr<IDevice> device)
258 {
259     CHKPV(device);
260     FI_HILOGI("  device %{public}d:%{private}s", device->GetId(), device->GetDevPath().c_str());
261     FI_HILOGI("  sysPath:       \"%{private}s\"", device->GetSysPath().c_str());
262     FI_HILOGI("  bus:           %{public}04x", device->GetBus());
263     FI_HILOGI("  vendor:        %{public}04x", device->GetVendor());
264     FI_HILOGI("  product:       %{public}04x", device->GetProduct());
265     FI_HILOGI("  version:       %{public}04x", device->GetVersion());
266     FI_HILOGI("  name:          \"%{public}s\"", device->GetName().c_str());
267     FI_HILOGI("  location:      \"%{public}s\"", device->GetPhys().c_str());
268     FI_HILOGI("  unique id:     \"%{private}s\"", device->GetUniq().c_str());
269     FI_HILOGI("  is pointer:    %{public}s, is keyboard:%{public}s",
270         device->IsPointerDevice() ? "True" : "False", device->IsKeyboard() ? "True" : "False");
271 }
272 
DumpRemoteInputDevice(const std::string & networkId)273 void InputDeviceMgr::DumpRemoteInputDevice(const std::string &networkId)
274 {
275     CALL_INFO_TRACE;
276     if (remoteDevices_.find(networkId) == remoteDevices_.end()) {
277         FI_HILOGE("NetworkId:%{public}s have no device existed", Utility::Anonymize(networkId).c_str());
278         return;
279     }
280     FI_HILOGI("NetworkId%{public}s, device mount:%{public}zu", Utility::Anonymize(networkId).c_str(),
281         remoteDevices_.size());
282     for (const auto &elem : remoteDevices_[networkId]) {
283         FI_HILOGI("DeviceId:%{public}d, deviceName:%{public}s", elem->GetId(), elem->GetName().c_str());
284     }
285 }
286 
SerializeDevice(std::shared_ptr<IDevice> device,NetPacket & packet)287 int32_t InputDeviceMgr::SerializeDevice(std::shared_ptr<IDevice> device, NetPacket &packet)
288 {
289     CALL_INFO_TRACE;
290     CHKPR(device, RET_ERR);
291     packet << device->GetId() << device->GetDevPath() << device->GetSysPath() << device->GetBus() <<
292     device->GetVendor() << device->GetProduct() << device->GetVersion() << device->GetName() <<
293     device->GetPhys() << device->GetUniq() << device->IsPointerDevice()  << device->IsKeyboard() <<
294     static_cast<int32_t> (device->GetKeyboardType());
295     if (packet.ChkRWError()) {
296         FI_HILOGE("Write packet failed");
297         return RET_ERR;
298     }
299     return RET_OK;
300 }
301 
Transform(std::shared_ptr<IDevice> device)302 std::shared_ptr<MMI::InputDevice> InputDeviceMgr::Transform(std::shared_ptr<IDevice> device)
303 {
304     CALL_DEBUG_ENTER;
305     CHKPP(device);
306     auto inputDevice = std::make_shared<MMI::InputDevice>();
307     inputDevice->SetId(device->GetId());
308     inputDevice->SetName(device->GetName() + std::to_string(device->GetId()));
309     inputDevice->SetBus(device->GetBus());
310     inputDevice->SetVersion(device->GetVersion());
311     inputDevice->SetProduct(device->GetProduct());
312     inputDevice->SetVendor(device->GetVendor());
313     inputDevice->SetPhys(device->GetPhys());
314     inputDevice->SetUniq(device->GetUniq());
315     if (device->IsKeyboard()) {
316         inputDevice->AddCapability(MMI::InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
317     }
318     if (device->IsPointerDevice()) {
319         inputDevice->AddCapability(MMI::InputDeviceCapability::INPUT_DEV_CAP_POINTER);
320     }
321     if (device->GetName() == VIRTUAL_TRACK_PAD_NAME) {
322         inputDevice->AddCapability(MMI::InputDeviceCapability::INPUT_DEV_CAP_POINTER);
323         inputDevice->AddCapability(MMI::InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
324     }
325     return inputDevice;
326 }
327 
AddVirtualInputDevice(const std::string & networkId,int32_t remoteDeviceId)328 void InputDeviceMgr::AddVirtualInputDevice(const std::string &networkId, int32_t remoteDeviceId)
329 {
330     CALL_INFO_TRACE;
331     if (remote2VirtualIds_.find(remoteDeviceId) != remote2VirtualIds_.end()) {
332         FI_HILOGW("Remote device:%{public}d already added as virtual device:%{public}d",
333             remoteDeviceId, remote2VirtualIds_[remoteDeviceId]);
334             return;
335     }
336     auto device = GetRemoteDeviceById(networkId, remoteDeviceId);
337     CHKPV(device);
338     int32_t virtualDeviceId = -1;
339     if (env_->GetInput().AddVirtualInputDevice(Transform(device), virtualDeviceId) != RET_OK) {
340         FI_HILOGE("Add virtual device failed, remoteDeviceId:%{public}d, name:%{public}s", remoteDeviceId,
341             device->GetName().c_str());
342         return;
343     }
344     virtualInputDevicesAdded_[networkId].insert(virtualDeviceId);
345     remote2VirtualIds_[remoteDeviceId] = virtualDeviceId;
346     FI_HILOGI("Add virtual device success, virtualDeviceId:%{public}d", virtualDeviceId);
347     UpdateVirtualDeviceIdMap();
348 }
349 
RemoveVirtualInputDevice(const std::string & networkId,int32_t remoteDeviceId)350 void InputDeviceMgr::RemoveVirtualInputDevice(const std::string &networkId, int32_t remoteDeviceId)
351 {
352     CALL_INFO_TRACE;
353     CHKPV(env_);
354     if (remote2VirtualIds_.find(remoteDeviceId) == remote2VirtualIds_.end()) {
355         FI_HILOGE("No remote device from networkId%{public}s with id:%{public}d",
356             Utility::Anonymize(networkId).c_str(), remoteDeviceId);
357         return;
358     }
359     auto virtualDeviceId = remote2VirtualIds_[remoteDeviceId];
360     if (env_->GetInput().RemoveVirtualInputDevice(virtualDeviceId) != RET_OK) {
361         FI_HILOGE("Remove virtual device failed, virtualDeviceId:%{public}d", virtualDeviceId);
362         return;
363     }
364     virtualInputDevicesAdded_[networkId].erase(virtualDeviceId);
365     remote2VirtualIds_.erase(remoteDeviceId);
366     FI_HILOGI("Remove virtual device success, virtualDeviceId:%{public}d", virtualDeviceId);
367     UpdateVirtualDeviceIdMap();
368 }
369 
GetRemoteDeviceById(const std::string & networkId,int32_t remoteDeviceId)370 std::shared_ptr<IDevice> InputDeviceMgr::GetRemoteDeviceById(const std::string &networkId, int32_t remoteDeviceId)
371 {
372     std::shared_ptr<IDevice> dev = std::make_shared<Device>(remoteDeviceId);
373     if (remoteDevices_.find(networkId) == remoteDevices_.end()) {
374         FI_HILOGE("No remoteDevice from networkId:%{public}s", Utility::Anonymize(networkId).c_str());
375         return nullptr;
376     }
377     if (auto iter = remoteDevices_[networkId].find(dev); iter != remoteDevices_[networkId].end()) {
378         return *iter;
379     }
380     FI_HILOGW("No remote device with deviceId:%{public}d", remoteDeviceId);
381     return nullptr;
382 }
383 
UpdateVirtualDeviceIdMap()384 void InputDeviceMgr::UpdateVirtualDeviceIdMap()
385 {
386     CALL_INFO_TRACE;
387     auto ret = sender_.Send(CooperateEvent(
388         CooperateEventType::UPDATE_VIRTUAL_DEV_ID_MAP,
389         UpdateVirtualDeviceIdMapEvent {
390             remote2VirtualIds_
391         }));
392     if (ret != Channel<CooperateEvent>::NO_ERROR) {
393         FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
394     }
395 }
396 } // namespace Cooperate
397 } // namespace DeviceStatus
398 } // namespace Msdp
399 } // namespace OHOS
400